六,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);
    }
相关推荐
wyt5314292 小时前
Redis的安装教程(Windows+Linux)【超详细】
linux·数据库·redis
vpk1123 小时前
Docker Compose 安装 Redis
redis·docker·容器
我真会写代码6 小时前
Redis高频面试题(含标准答案,覆盖基础+进阶+实战)
数据库·redis·缓存
6+h7 小时前
【Redis】缓存问题及解决方案
数据库·redis·缓存
6+h8 小时前
【Redis】高可用核心讲解
数据库·redis·缓存
Aloha_up9 小时前
redis与数据库的一致性问题分析
数据库·redis·缓存
6+h9 小时前
【Redis】底层原理解析(SDS / 跳表 / IO多路复用 / 单线程模型)
数据库·redis·bootstrap
知识分享小能手11 小时前
Redis入门学习教程,从入门到精通,Redis集群架构:语法知识点、使用方法与综合案例(6)
redis·学习·架构
czlczl2002092511 小时前
Redis过期删除策略
数据库·redis·缓存
爱学习的小可爱卢12 小时前
Redis从入门到精通:入门到精通(万字详解)
数据库·redis·中间件