微信公众号访问地址:基于Redis实现点赞及排行榜功能
推荐文章:
1、SpringBoot整合多数据源,并支持动态新增与切换(详细教程)
2、Redis中使用lua脚本
3、SpringBoot统一标准响应格式及异常处理
4、SpringBoot+MyBatis流式查询,处理大规模数据,提高系统的性能和响应能力
5、SpringBoot对接kafka,批量、并发、异步获取消息,并动态、批量插入库表
6、SpringBoot用线程池ThreadPoolTaskExecutor异步处理百万级数据
7、Redis实现消息队列
一、简介
1.1、点赞相关需求:
1、同一个用户只能点赞一次,再次点击则取消点赞(点赞/取消点赞);
2、如果当前用户已经点赞,则点赞按钮高亮显示(前端实现,判断字段Blog类的isLik属性)。
1.2、实现步骤:
1、给Blog类中添加一个isLike字段,标识是否被当前用户点赞;
2、修改点赞功能,利用Redis的set集合判断是否点赞过,未点赞过则点赞数+1,已点赞过则点赞数-1;
3、修改根据id查询Blog的业务,判断当前登录用户是否点赞过,赋值给isLike字;
4、修改分页查询Blog业务,判断当前登录用户是否点赞过,赋值给isLike字段。
1.3、点赞实现思路:
1.4、排行榜实现:
分析:由于需要对点赞功能进行排行榜分析,按照点赞时间先后排序,返回最早点赞的Top5的用户,所以最好是选择SortedSet实现功能。(特别说明:代码获取方式在文章结尾)
涉及到表信息:
二、常用的命令
2.1、zadd
案例:
redis:0>zadd myzset 1 a1
"1"
redis:0>zadd myzset 2 a2
"1"
2.2、zscore
案例:
redis:0>zscore myzset a2
"2"
redis:0>zscore myzset a3
"5"
2.3、zrem
案例:
redis:0>zrem myzset a2
"1"
redis:0>zscore myzset a2
null
redis:0>
2.4、zrange
案例:获取前四个元素
redis:0>zrange blog:liked:6 0 4
1) "999"
2) "111"
3) "222"
三、代码实现
3.1、点赞/取消点赞功能
核心代码实现:
public Result likeBlog(Long id, Long userId) {
// 1.获取登录用户 展示用接口传值
// Long userId = UserHolder.getUser().getId();
// 2.判断当前登录用户是否已经点赞
String key = BLOG_LIKED_KEY + id;
//redis:0>zscore myzset a3 -> "5"
Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString());
if (score == null) {
// 3.如果未点赞,可以点赞
// 3.1.数据库点赞数 + 1
boolean isSuccess = update().setSql("liked = liked + 1").eq("id", id).update();
// 3.2.保存用户到Redis的set集合 zadd key value score
if (isSuccess) {
//ZADD key score1 member1 [score2 member2]
stringRedisTemplate.opsForZSet().add(key, userId.toString(), System.currentTimeMillis());
}
} else {
// 4.如果已点赞,取消点赞
// 4.1.数据库点赞数 -1
boolean isSuccess = update().setSql("liked = liked - 1").eq("id", id).update();
// 4.2.把用户从Redis的set集合移除
if (isSuccess) {
stringRedisTemplate.opsForZSet().remove(key, userId.toString());
}
}
return Result.ok();
}
控制层:
@ApiOperation(value="点赞功能", notes="likeBlog")
@PostMapping("/liked")
public Result likeBlog(@RequestParam("id") Long id,@RequestParam("userId") Long userId) {
return blogService.likeBlog(id,userId);
}
接口调用:
结果展示:
3.2、排行榜功能
核心代码实现:
public Result queryBlogLikes(Long id) {
String key = BLOG_LIKED_KEY + id;
// 1.查询top5的点赞用户 zrange key 0 4
Set<String> top5 = stringRedisTemplate.opsForZSet().range(key, 0, 4);
//判断集合是否为空(包括null和没有元素的集合)
//参考hutool工具:https://www.hutool.cn/docs/#/core
if(CollUtil.isEmpty(top5)){
return Result.ok(Collections.emptyList());
}
// 2.解析出其中的用户id
List<Long> ids = top5.stream().map(Long::valueOf).collect(Collectors.toList());
String idStr = StrUtil.join(",", ids);
// 3.根据用户id查询用户 WHERE id IN ( 5 , 1 ) ORDER BY FIELD(id, 5, 1)
//数据量少基本不影响性能,若获取top数量比较大的时候,就需要优化性能
List<UserDTO> userDTOS = userService.query()
.in("id", ids).last("ORDER BY FIELD(id," + idStr + ")").list()
.stream()
.map(user -> BeanUtil.copyProperties(user, UserDTO.class))
.collect(Collectors.toList());
// 4.返回
return Result.ok(userDTOS);
}
控制层:
@ApiOperation(value="根据ID查询点赞的所有用户", notes="queryBlogLikes")
@GetMapping("/likes/{id}")
public Result queryBlogLikes(@PathVariable("id") Long id) {
return blogService.queryBlogLikes(id);
}
接口调用及展示:
四、源码获取方式
更多优秀文章,请关注个人微信公众号或搜索“程序猿小杨”查阅。然后回复:源码,可以获取该项目对应的源码及表结构,开箱即可使用。
说明:后面redis相关操作的功能都会放在此文件夹中,需要相关功能的,只需要获取最新的资源即可。
如果大家对相关文章感兴趣,可以关注微信公众号"程序猿小杨",会持续更新优秀文章!如果这篇文章对您有所帮助、有所启发,请帮忙 分享、收藏、点赞、在看,您的支持就是我坚持下去的最大动力!谢谢! |