一,点赞功能
需求:
- 同一个用户只能点赞一次,再次点击则取消点赞
- 如果当前用户已经点赞,则点赞按钮高亮显示(前端已实现,判断字段Blog类的isLike属性)
实现步骤:
-
给Blog类中添加一个
isLike
字段,标识是否被当前用户点赞 -
修改点赞功能,利用Redis的set集合判断是否点赞过,未点赞则点赞数+1,已点赞则点赞数-1(key是博客id,value是用户id,存储已经点赞的用户id)
javapublic Result likeBlog(Long id){ //1.获取登录用户(从ThreadLocal里面获取) Long userId=UserHolder.getUser().getId(); //2.判断当前登录用户是否已经点赞(查redis即可) String key="blog:liked:"+id; Boolean isMember=stringRedisTemplate.opsForSet().isMember(key,userId.toString()); if(BooleanUtil.isFalse(isMember)){ //3.如果未点赞,可以点赞 //3.1 数据库点赞数+1 boolean isSuccess=update().setSql("liked=liked+1").eq("id",id).update(); //3.2 保存用户到Redis的set集合 if(isSuccess){ stringRedisTemplate.opsForSet().add(key,userId.toString()); } }else{ //4.如果已经点赞,取消点赞 //4.1 数据库点赞数-1 boolean isSuccess=update().setSql("liked=liked-1").eq("id",id).update(); //4.2 把用户从Redis的set集合取消 if(isSuccess){ stringRedisTemplate.opsForSet().remove(key,userId.toString()); } } }
-
修改根据id查询Blog的业务,判断当前登录用户是否点赞过,赋值给isLike字段
-
修改分页查Blog业务,判断当前登录用户是否点赞过,赋值给isLike字段
二,排行榜功能

-
修改点赞业务,将Set改成SortedSet
javapublic Result likeBlog(Long id){ //1.获取登录用户(从ThreadLocal里面获取) Long userId=UserHolder.getUser().getId(); //2.判断当前登录用户是否已经点赞(查redis即可) String key="blog:liked:"+id; 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的SortedSet集合 if(isSuccess){ 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的SortedSet集合取消 if(isSuccess){ stringRedisTemplate.opsForZSet().remove(key,userId.toString()); } } }
-
实现点赞列表查询逻辑
javapublic Result queryBlogLikes(Long id){ //1.查询top5的点赞用户 zrange key 0 4 String key="blog:liked:"+id; Set<String> top5Id=stringRedisTemplate.opsForZSet().rank(key,0,4); if(top5Id == null || top5Id.isEmpty()){ return Result.ok(Collections.emptyList()); } //2. 解析出其中的用户id List<Long> ids=top5Id.stream().map(Long::valueOf).collect(Collectors.toList()); //3. 根据用户id查询用户(如果直接查询in(5,1) 会自动排序成1,5) //需要我们order by field(id,5,1)手动指定即可实现5,1 String idStr=StrUtil.join(",",ids); List<User> users=userService.query().in("id",ids).last("ORDER BY FIELD(id,"+idStr+")").list(); //4. 返回 return Result,ok(users); }