栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

redis——实现点赞功能

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

redis——实现点赞功能

目录

完善点赞功能

实现点赞排行榜功能


完善点赞功能

(采用redis中的set集合)

实现

    @Override
    public Result likeBlog(Long id) {
        //1.获取登录用户
        Long userId = UserHolder.getUser().getId();
        //2.判断当前用户是否点赞
        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());
            }
        }

        return Result.ok();
    }

在查询Blog的业务中添加下面方法,来判断该用户是否点过赞

    private void isBlogLiked(Blog blog) {
        //1.获取登录用户
        Long userId = UserHolder.getUser().getId();
        //2.判断当前用户是否点赞
        String key="blog:liked:"+blog.getId();
        Boolean isMember = stringRedisTemplate.opsForSet().isMember(key,userId.toString());
        blog.setIsLike(BooleanUtil.isTrue(isMember));
    }

实现点赞排行榜功能

根据上图可知,要想能够对数据进行排序,我们需要更改redis中的数据结构Set为SortedSet

实现

根据当时间戳设置score值进行排序

    @Override
    public Result likeBlog(Long id) {
        //1.获取登录用户
        Long userId = UserHolder.getUser().getId();
        //2.判断当前用户是否点赞
        String key="blog:liked:"+id;
        //没有isMember方法,采用score获取当前score值,通过判断是否为空来判断有无点赞
        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的set集合中
            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的set集合移除
            if(isSuccess){
                stringRedisTemplate.opsForZSet().remove(key,userId.toString());
            }
        }

        return Result.ok();
    }

    @Override
    public Result queryBlogLikes(Long id) {
        String key="blog:liked:"+id;
        //1.查询top5的点赞用户 zrange key 0 4
        Set top5 = stringRedisTemplate.opsForZSet().range(key, 0, 4);
        if(top5==null||top5.isEmpty()){
            return Result.ok(Collections.emptyList());
        }
        //2.解析出其中的用户id
        //stream转流,map映射,collect收集
        List ids = top5.stream().map(Long::valueOf).collect(Collectors.toList());

        //3.根据用户id查询用户
        List userDTOS = userService.listByIds(ids)
                .stream()
                .map(user -> BeanUtil.copyProperties(user, UserDTO.class))
                .collect(Collectors.toList());

        //4.返回
        return Result.ok(userDTOS);
    }

修改一个小bug(因为主界面不一定需要登录,所以检索文章时无需考虑该用户是否点赞,所以需要增加判断语句)

    private void isBlogLiked(Blog blog) {
        //1.获取登录用户
        UserDTO user = UserHolder.getUser();
        if(user==null){
            //用户未登录无需查询是否点赞
            return;
        }
        Long userId = UserHolder.getUser().getId();
        //2.判断当前用户是否点赞
        String key="blog:liked:"+blog.getId();
        Double score = stringRedisTemplate.opsForZSet().score(key, userId.toString());
        blog.setIsLike(score!=null);
    }

 

仍存在一些问题,虽然我们传入的id是按顺序的,但是listByIds()内部封装的sql语句是采用in的方法,导致查询出来的结构会根据id来进行排序,如下图所示

 

所以需要进行相应的改造,改造sql

 修改如下

    @Override
    public Result queryBlogLikes(Long id) {
        String key="blog:liked:"+id;
        //1.查询top5的点赞用户 zrange key 0 4
        Set top5 = stringRedisTemplate.opsForZSet().range(key, 0, 4);
        if(top5==null||top5.isEmpty()){
            return Result.ok(Collections.emptyList());
        }
        //2.解析出其中的用户id
        //stream转流,map映射,collect收集
        List ids = top5.stream().map(Long::valueOf).collect(Collectors.toList());
        String idStr = StrUtil.join(",",ids);
        //3.根据用户id查询用户
        List userDTOS = userService.query().in("id",ids)
                .last("ORDER BY FIELD(id,"+idStr+")")
                .list()
                .stream()
                .map(user -> BeanUtil.copyProperties(user, UserDTO.class))
                .collect(Collectors.toList());

        //4.返回
        return Result.ok(userDTOS);
    }

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/884484.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号