六,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);
    }
相关推荐
海梨花20 小时前
【从零开始学习Redis】项目实战-黑马点评D2
java·数据库·redis·后端·缓存
鼠鼠我捏,要死了捏2 天前
生产环境Redis缓存穿透与雪崩防护性能优化实战指南
redis·cache
曾经的三心草2 天前
微服务的编程测评系统11-jmeter-redis-竞赛列表
redis·jmeter·微服务
努力努力再努力wz2 天前
【c++深入系列】:万字详解模版(下)
java·c++·redis
2301_793086872 天前
Redis 04 Reactor
数据库·redis·缓存
AAA修煤气灶刘哥2 天前
搞定 Redis 不难:从安装到实战的保姆级教程
java·redis·后端
青鱼入云2 天前
redis怎么做rehash的
redis·缓存
考虑考虑2 天前
Redis事务
redis·后端
陈天cjq2 天前
Redis 实用型限流与延时队列:从 Lua 固定/滑动窗口到 Streams 消费组(含脚本与压测)
redis·junit·lua
Warren982 天前
Lua 脚本在 Redis 中的应用
java·前端·网络·vue.js·redis·junit·lua