点赞功能开发

ops/2024/9/20 7:26:49/ 标签: 点赞, redis

文章目录

    • 1.点赞收藏功能设计
        • 1.示意图
        • 2.描述
          • 1.使用redis记录的数据
          • 2.数据库的设计
          • 3.功能设计
            • 1.新增点赞
            • 2.取消点赞
            • 3.查询当前题目被点赞的数量
            • 4.查询当前题目被当前用户是否点过赞
            • 5.我的点赞
    • 2.代码生成器的使用
        • 1.找到代码生成器在磁盘的位置,直接复制到项目下
        • 2.导入模块
          • 1.打开项目结构,选择导入模块
          • 2.从已存在的资源中导入
          • 3.一直下一步即可
          • 4.导入成功
          • 5.右击pom.xml将其作为maven项目
          • 6.发现刷新maven无法找到这个starter
          • 7.将jc-club-common-starter模块也导入进来
        • 3.gen.yml 进行配置
          • 1.替换数据库连接信息及对应表
          • 2.使用的模板与生成文件映射给关系
          • 3.全局参数
    • 3.点赞功能基本开发
        • 1.sun-club-application-controller
          • 1.SubjectLikedController.java 接受点赞题目id和点赞状态
        • 2.sun-club-common
          • 1.SubjectLikedStatusEnum.java 题目点赞状态枚举
        • 3.sun-club-domain
          • 1.SubjectLikedDomainService.java
          • 2.SubjectLikedDomainServiceImpl.java
          • 3.RedisUtil.java 新增hash结构api
        • 4.测试
    • 3.题目详情增加点赞数据
        • 1.sun-club-application-controller
          • 1.SubjectInfoDTO.java 新增字段
        • 2.sun-club-domain
          • 1.SubjectInfoBO.java 新增字段
          • 2.SubjectLikedDomainService.java
          • 3.SubjectLikedDomainServiceImpl.java
          • 4.SubjectInfoDomainServiceImpl.java 在查询题目信息时查询点赞信息
        • 3.测试
          • 1.给508题目点赞
          • 2.查询508题目详情,发现被当前用户点赞

1.点赞收藏功能设计

1.示意图

img

2.描述
redis_10">1.使用redis记录的数据
  • **hash类型:**hashkey:subjectId:userId,hashval:存的是点赞的状态 1 是点赞 0 是不点赞
  • **string 类型:**key subjectId,val:我们的题目被点赞的数量
  • **string 类型:**key subjectId.userId,val:"1"记录题目被谁点过赞
2.数据库的设计
create table subject_liked
(id           bigint auto_increment comment '主键'primary key,subject_id   bigint                   null comment '题目id',like_user_id varchar(32)              null comment '点赞人id',status       int                      null comment '点赞状态 1点赞 0不点赞',created_by   varchar(32) charset utf8 null comment '创建人',created_time datetime                 null comment '创建时间',update_by    varchar(32) charset utf8 null comment '修改人',update_time  datetime                 null comment '修改时间',is_deleted   int default 0            null,constraint uniq_likeunique (subject_id, like_user_id) comment '点赞唯一索引'
)comment '题目点赞表' collate = utf8mb4_bin;
3.功能设计
1.新增点赞

直接操作 redis,存 hash,存数量,存点赞的人与题目的 key

2.取消点赞

上面的反逻辑,数量会-1,hash 里面的状态会更新,点赞人与题目关联的 key 会被删除

3.查询当前题目被点赞的数量

直接与 redis 交互,读题目的被点赞数量的 key

4.查询当前题目被当前用户是否点过赞

直接查 redis 就可以了

5.我的点赞

直接查数据库做分页逻辑的展示

2.代码生成器的使用

1.找到代码生成器在磁盘的位置,直接复制到项目下

image-20240623135451683

2.导入模块
1.打开项目结构,选择导入模块

image-20240623135601572

image-20240623135633463

2.从已存在的资源中导入

image-20240623135709102

3.一直下一步即可

image-20240623135747788

4.导入成功

image-20240623135855599

5.右击pom.xml将其作为maven项目

image-20240623141337612

image-20240623141716529

6.发现刷新maven无法找到这个starter

image-20240623141605273

7.将jc-club-common-starter模块也导入进来
3.gen.yml 进行配置
1.替换数据库连接信息及对应表
# 数据库连接信息
jdbc:dbName: sun_clubtableName: subject_likedurl: username: password: driver: com.mysql.cj.jdbc.Driver
2.使用的模板与生成文件映射给关系
mapperInfos: genCode/subjectLikedMapper.yml
3.全局参数
# 全局参数
params:# 作者author: sun# 模块module: subject# controller 通用前缀api: /subjectLiked# 生成对象是否移除前缀removePre: false# 使用内置函数赋值给变量  FunctionUtils 中替换genDate: now()# win 需要补充模板具体目录templateBasePath: D:/Intelij_IDEA_Project/sun-club/code-generate/src/main/resources/

3.点赞功能基本开发

1.sun-club-application-controller
1.SubjectLikedController.java 接受点赞题目id和点赞状态
/*** 新增点赞* @param subjectLikedDTO 点赞题目id、点赞状态0/1* @return*/
@RequestMapping("add")
public Result<Boolean> add(@RequestBody SubjectLikedDTO subjectLikedDTO) {try {if (log.isInfoEnabled()) {log.info("SubjectLikedController.add.dto:{}", JSON.toJSONString(subjectLikedDTO));}Preconditions.checkNotNull(subjectLikedDTO.getSubjectId(), "题目id不能为空");Preconditions.checkNotNull(subjectLikedDTO.getStatus(), "点赞状态不能为空");// 获取点赞人的idString loginId = LoginUtil.getLoginId();subjectLikedDTO.setLikeUserId(loginId);Preconditions.checkNotNull(subjectLikedDTO.getLikeUserId(), "点赞人不能为空");SubjectLikedBO SubjectLikedBO = SubjectLikedDTOConverter.INSTANCE.convertDTOToBO(subjectLikedDTO);subjectLikedDomainService.add(SubjectLikedBO);return Result.ok(true);} catch (Exception e) {log.error("SubjectLikedController.register.error:{}", e.getMessage(), e);return Result.fail("新增题目点赞表失败");}
}
2.sun-club-common
1.SubjectLikedStatusEnum.java 题目点赞状态枚举
package com.sunxiansheng.subject.common.enums;import lombok.Getter;/*** Description: 题目点赞枚举* @Author sun* @Create 2024/5/24 9:53* @Version 1.0*/
@Getter
public enum SubjectLikedStatusEnum {LIKED(1, "点赞"),UN_LIKED(0, "取消点赞"),;public int code;public String desc;SubjectLikedStatusEnum(int code, String desc) {this.code = code;this.desc = desc;}/*** 根据code获取枚举* @param code* @return*/public static SubjectLikedStatusEnum getByCode(int code) {for (SubjectLikedStatusEnum value : values()) {if (value.code == code) {return value;}}return null;}
}
3.sun-club-domain
1.SubjectLikedDomainService.java
/*** 添加 题目点赞表 信息*/
void add(SubjectLikedBO subjectLikedBO);
2.SubjectLikedDomainServiceImpl.java
/*
与redis交互*/
@Resource
private RedisUtil redisUtil;/*
点赞 hash结构:大key*/
public static final String SUBJECT_LIKE_KEY = "subject.liked";/*
题目点赞计数 string结构:key*/
public static final String SUBJECT_LIKE_COUNT_KEY = "subject.liked.count";/*
题目被谁点过赞 string结构:key
*/
public static final String SUBJECT_LIKE_DETAIL_KEY = "subject.liked.detail";/*** 构建新增点赞redis中的hashKey(小key)* @param subjectId* @param userId* @return*/
private String buildSubjectLikedKey(String subjectId, String userId) {return subjectId + ":" + userId;
}@Override
public void add(SubjectLikedBO subjectLikedBO) {// 获取信息Long subjectId = subjectLikedBO.getSubjectId();String likeUserId = subjectLikedBO.getLikeUserId();Integer status = subjectLikedBO.getStatus();// 构建hashKeyString hashKey = buildSubjectLikedKey(String.valueOf(subjectId), likeUserId);// 存储点赞信息redisUtil.putHash(SUBJECT_LIKE_KEY, hashKey, status);// 题目点赞计数String countKey = SUBJECT_LIKE_COUNT_KEY + "." + subjectId;// 题目被谁点过赞String detailKey = SUBJECT_LIKE_DETAIL_KEY + "." + subjectId + "." + likeUserId;// 如果是点赞,则增加一if (SubjectLikedStatusEnum.LIKED.getCode() == status) {// 记录该题目被谁点过赞redisUtil.set(detailKey, "1");redisUtil.increment(countKey, 1);} else {// 如果说是取消点赞,则要判断是否已经是0了Integer count = redisUtil.getInt(countKey);// 如果是0,就直接返回,不是0则减一if (Objects.isNull(count) || count <= 0) {return;}redisUtil.increment(countKey, -1);// 取消点赞,也要删除点赞细节redisUtil.del(detailKey);}
}
3.RedisUtil.java 新增hash结构api
/*** 向Redis中的hash结构存储数据* @param key 一个hash结构的key* @param hashKey hash中的小key* @param hashVal hash中的小value*/
public void putHash(String key, String hashKey, Object hashVal) {redisTemplate.opsForHash().put(key, hashKey, hashVal);
}/*** Redis中的String类型,获取value时将其转换为int类型* @param key* @return*/
public Integer getInt(String key) {return (Integer) redisTemplate.opsForValue().get(key);
}/*** Redis中的String类型,将value增加一* @param key* @param count* @return*/
public void increment(String key, Integer count) {redisTemplate.opsForValue().increment(key, count);
}
4.测试
1.点赞

image-20240623160707690

2.Redis

image-20240623160728623

image-20240623160733922

image-20240623160739429

3.题目详情增加点赞数据

1.sun-club-application-controller
1.SubjectInfoDTO.java 新增字段
/*** 是否被当前用户点赞*/
private Boolean liked;/*** 当前题目点赞的数量*/
private Integer likedCount;
2.sun-club-domain
1.SubjectInfoBO.java 新增字段
/*** 是否被当前用户点赞*/
private Boolean liked;/*** 当前题目点赞的数量*/
private Integer likedCount;
2.SubjectLikedDomainService.java
/*** 获取当前是否被点赞过*/
Boolean isLiked(String subjectId, String userId);/*** 获取点赞数量*/
Integer getLikedCount(Long subjectId);
3.SubjectLikedDomainServiceImpl.java
@Override
public Boolean isLiked(String subjectId, String userId) {String detailKey = SUBJECT_LIKE_DETAIL_KEY + "." + subjectId + "." + userId;// 如果存在这个key,就说明该题目被这个用户点过赞了return redisUtil.exist(detailKey);
}@Override
public Integer getLikedCount(Long subjectId) {String countKey = SUBJECT_LIKE_COUNT_KEY + "." + subjectId;Integer count = redisUtil.getInt(countKey);// 如果为空或0,直接返回0if (Objects.isNull(count) || count <= 0) {return 0;}return count;
}
4.SubjectInfoDomainServiceImpl.java 在查询题目信息时查询点赞信息
// ========== redis查询点赞信息 ==========
bo.setLiked(subjectLikedDomainService.isLiked(String.valueOf(subjectInfoBO.getId()), LoginUtil.getLoginId()));
bo.setLikedCount(subjectLikedDomainService.getLikedCount(subjectInfoBO.getId()));
// ========== redis查询点赞信息 ==========
3.测试
1.给508题目点赞

image-20240623164317097

2.查询508题目详情,发现被当前用户点赞

image-20240623164239496


http://www.ppmy.cn/ops/93714.html

相关文章

微信小程序中实现自动滚动

使用scroll-view组件的scroll-into-view属性&#xff1a; <scroll-view class"container" scroll-y"{{true}}" scroll-into-view"recordBottomScroll"><view class"text_style" style"color: #252526;">{{te…

16 交换机命令行配置

交换机命令行配置 一、交换机命令行基本配置 &#xff08;一&#xff09;配置主机名 Switch>enable Switch#configure terminal Switch(config)#hostname S1&#xff08;二&#xff09;查看配置信息 Switch#show running-config Building configuration...Current confi…

SpringBoot配置

目录 yaml基本含义 yaml基本语法 yaml数据格式 实操 yaml:参数引用 小结 yaml基本含义 通过对比不同配置文件写法&#xff0c;就可以发现yaml配置文件&#xff0c;更加注重数据本身 原因 1 比properties配置文件&#xff0c;更加注重层级关系 2 和xml文件比起来&#xff…

【Unity-UGUI】UI重建

UGUI UI重建二三事(一) UGUI UI重建二三事(二) [UGUI源码二]Unity UI重建(Rebuild)源码分析 这一部分主要是通过以上几篇文章学习的&#xff0c;总结一下&#xff1a; UI重建主要分类两类&#xff0c;一类是布局重建(Layout Rebuild)&#xff0c;另一类是图形重建(Graphic Reb…

jar包扫描不到,idea如何通过Project Structure设置

目录 一、进入Project Structure二、添加你的项目进来三、手动添加依赖 很多时候jar包文件已经存在&#xff0c;但是无法使用&#xff0c;需要通过Project Structure设置 一、进入Project Structure 选择Modules->点击 二、添加你的项目进来 一直next&#xff0c;最后点…

git推送错误:Failed to connect to github.com port 443

今天在push代码到github的时候遇到了错误&#xff1a;fatal: unable to access https://github.com/ShangyiAlone/FacemaskDetection.git/: Failure when receiving data from the peer 网上搜了下教程&#xff0c;是开启梯子的时候代理服务器的问题&#xff0c;开启梯子的时候…

【Python SHA256 摘要算法】

SHA256 是一种广泛使用的密码散列函数&#xff0c;用于生成数据的唯一指纹&#xff0c;即散列值。它属于SHA-2家族&#xff0c;该家族还包括 SHA-384 和 SHA-512 算法。SHA256 算法在许多领域都有应用&#xff0c;例如&#xff1a; 数据完整性验证&#xff1a;用于验证数据在传…

使用 Flask、Celery 和 Python 实现每月定时任务

为了创建一个使用 Flask、Celery 和 Python 实现的每月定时任务&#xff0c;我们需要按照以下步骤进行&#xff1a; 1.安装必要的库 我们需要安装 Flask、Celery 和 Redis&#xff08;作为消息代理&#xff09;。我们可以使用 pip 来安装它们&#xff1a; bash复制代码 ​ p…

C++ | Leetcode C++题解之第331题验证二叉树的前序序列化

题目&#xff1a; 题解&#xff1a; class Solution { public:bool isValidSerialization(string preorder) {int n preorder.length();int i 0;int slots 1;while (i < n) {if (slots 0) {return false;}if (preorder[i] ,) {i;} else if (preorder[i] #){slots--;i…

Ubuntu 将更改版本规则,使用最新内核发布发行版

众所周知&#xff0c;Canonical 开发的 Ubuntu 发行版每半年发布一个新版本&#xff0c;而 Linux 内核却是大约每 2-3 个月发布一个新版本。 这导致一个问题&#xff0c;Ubuntu发行版永远使用的不是最新内核。因为按照Ubuntu的开发周期&#xff0c; Ubuntu 开发阶段选择使用的…

zookeeper集群搭建Windows 7

在 Windows 7 操作系统上搭建 ZooKeeper 集群是可行的,但是由于 Windows 7 是一个较旧的操作系统,可能缺少某些现代的功能或者安全性更新。尽管如此,你仍然可以在 Windows 7 上搭建一个 ZooKeeper 单服务器三节点集群用于测试和学习目的。 下面是针对 Windows 7 系统的步骤…

C# TreeView

添加 TreeView 控件&#xff1a;定义节点&#xff1a;添加节点&#xff1a;设置节点属性&#xff1a;处理节点事件&#xff1a;自定义节点绘制&#xff1a;数据绑定&#xff1a;节点选择&#xff1a;节点展开和折叠&#xff1a;搜索和过滤&#xff1a;示例代码总结 C# 中的 Tre…

C#加载toolblock工具

VisionPro QuickBuild工具 VisionPro QuickBuild是康耐视旗下的与相机配套的软件&#xff0c;主要是设计了一些底层算法&#xff0c;免去了开发者要进行底层开发的工作量&#xff0c;而其中的ToolBlock工具相当于一个函数&#xff0c;可以在这个函数里面完成你想完成的功能&…

nvm下载node时没有下载npm问题的解决

问题&#xff1a; 使用nvm下载node版本时,没有自动下载npm 1&#xff0c;卸载指定的版本 nvm uninstall "版本号" 2&#xff0c;设置npm的镜像地址&#xff08;将npm的地址指定为淘宝镜像&#xff09; nvm npm_mirror https://npmmirror.com/mirrors/npm/ 3&…

IDEA 创建类时自动生成注释

一、背景 在开发的过程中&#xff0c;公司都会要求开发针对自己创建的类进行一些描述说明&#xff0c;为了便于程序员在创建类时快速生成注释。 二、如何配置? 打开File -> Settings -> Editor -> File and Code Templates -> Includes&#xff0c;在File Header…

Java Facade 模式(外观模式)增强您的架构

通过我们的深入解释和实际示例揭示 Java Facade 模式的简单性 - 简化您的代码并增强您的架构。 您是否厌倦了让您头疼的乱七八糟的代码&#xff1f;您是否在为难以操作和维护的复杂软件而苦恼&#xff1f;那么让我们来谈谈外观 — — 不&#xff0c;不是建筑物的正面&#xff0…

三防平板满足多样化定制为工业领域打造硬件解决方案

在当今工业领域&#xff0c;数字化、智能化的发展趋势日益显著&#xff0c;对于高效、可靠且适应各种复杂环境的硬件设备需求不断增长。三防平板作为一种具有坚固耐用、防水防尘防摔特性的工业级设备&#xff0c;正以其出色的性能和多样化的定制能力&#xff0c;为不同行业的应…

Leetcode面试经典150题-112.路径总和

解法都在代码里&#xff0c;不懂就留言或者私信 超级简单的题&#xff0c;不过有隐形的坑 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.v…

StarRocks 存算分离 Data Cache 二三事

前言 StarRocks 存算分离模式架构中&#xff0c;数据导入后&#xff0c;会被写入远端对象存储。而对象存储由于其访问延迟较高特性&#xff0c;如果没有任何优化&#xff0c;每次查询直接访问后端对象存储&#xff0c;那么性能就会变得非常差&#xff0c;也就失去了 StarRocks…

Hadoop YARN:现代大数据集群资源管理与作业调度

1.Yarn的概述 1.1.解释Yarn的定义和基本概念 Hadoop YARN&#xff08;Yet Another Resource Negotiator&#xff09;是 Hadoop 2.x 版本引入的一种资源管理器&#xff0c;用于管理和调度大数据集群中的资源&#xff0c;是 Hadoop 集群的核心组件之一。YARN 的设计目标是提高 H…