六,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);
    }
相关推荐
IT大白鼠4 天前
Redis 系列 · 第 01 篇——认知入门:Redis 是什么
redis·nosql
彧azz4 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
lbb 小魔仙4 天前
OpenClaw + cpolar 实战:远程 NAS、分享小游戏、RDP,再配置公网 AI 入口
数据库·人工智能·redis·oracle·prometheus
夕除4 天前
redis--018
redis
两锭子4 天前
Redis基础
redis
烟沙九洲4 天前
Redis 缓存穿透、缓存击穿、缓存雪崩
数据库·redis
字节探索4 天前
Redis 只会当缓存用?这 10 大实战场景,让你的系统快到飞起
redis·后端
于樱花森上飞舞4 天前
【Redis】哨兵详解
java·开发语言·数据库·redis
Rain的Java大神之路4 天前
如何快速上传10G文件
java·spring boot·redis·后端·mysql·spring cloud·面试
Wang's Blog4 天前
Java 接入Redis: 通用命令与键管理
java·服务器·redis