六,Redis实现点赞排行表

一,点赞功能

需求:

  • 同一个用户只能点赞一次,再次点击则取消点赞
  • 如果当前用户已经点赞,则点赞按钮高亮显示(前端已实现,判断字段Blog类的isLike属性)

实现步骤:

  1. 给Blog类中添加一个isLike字段,标识是否被当前用户点赞

  2. 修改点赞功能,利用Redis的set集合判断是否点赞过,未点赞则点赞数+1,已点赞则点赞数-1(key是博客id,value是用户id,存储已经点赞的用户id)

    java 复制代码
    public 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());
            }
        }
    }
  3. 修改根据id查询Blog的业务,判断当前登录用户是否点赞过,赋值给isLike字段

  4. 修改分页查Blog业务,判断当前登录用户是否点赞过,赋值给isLike字段

二,排行榜功能

  1. 修改点赞业务,将Set改成SortedSet

    java 复制代码
    public 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());
            }
        }
    }
  2. 实现点赞列表查询逻辑

    java 复制代码
    public 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);
    }
相关推荐
xxxmine11 小时前
redis学习
数据库·redis·学习
qq_54702617911 小时前
Redis 常见问题
数据库·redis·mybatis
知识即是力量ol12 小时前
基于 Redis 实现白名单,黑名单机制详解及应用场景
数据库·redis·缓存
CoLiuRs12 小时前
语义搜索系统原理与实现
redis·python·向量·es
fengxin_rou14 小时前
Redis 从零到精通:第一篇 初识redis
数据库·redis·缓存
陌上丨17 小时前
Redis内存使用率在95%以上,请问是什么原因?如何解决?
数据库·redis·缓存
heartbeat..17 小时前
Redis 性能优化全指南:从基础配置到架构升级
java·redis·性能优化·架构
xiaoye370817 小时前
redis和mysql数据库如何保证数据一致性
redis·mysql
小马爱打代码18 小时前
Spring Boot :使用 Spring Cache 注解方式集成 Redis
spring boot·redis·spring
笨蛋不要掉眼泪19 小时前
Spring Boot + RedisTemplate 数据结构的基础操作
java·数据结构·spring boot·redis·wpf