文章目录
1.点赞收藏功能设计
1.示意图
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.查询当前题目被点赞的数量
4.查询当前题目被当前用户是否点过赞
直接查 redis 就可以了
5.我的点赞
直接查数据库做分页逻辑的展示
2.代码生成器的使用
1.找到代码生成器在磁盘的位置,直接复制到项目下
2.导入模块
1.打开项目结构,选择导入模块
2.从已存在的资源中导入
3.一直下一步即可
4.导入成功
5.右击pom.xml将其作为maven项目
6.发现刷新maven无法找到这个starter
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.点赞
2.Redis
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查询点赞信息 ==========