首页 > 数据库 >redis项目黑马点评之博客功能的开发

redis项目黑马点评之博客功能的开发

时间:2023-01-22 11:22:07浏览次数:42  
标签:userId redis 博客 id blog Result key 黑马 user

方法均在BlogServiceImpl中实现,因此需要在IBlogService创建接口

queryHotBlog

此类会在首页展示热门的博客

@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IBlogService {

    @Resource
    private IUserService userService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private IFollowService followService;

    @Override
    public Result queryHotBlog(Integer current) {
        // 根据用户查询
        Page<Blog> page = query()
                .orderByDesc("liked")
                .page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE));
        // 获取当前页数据
        List<Blog> records = page.getRecords();
        // 查询用户
        records.forEach(blog -> {
            this.queryBlogUser(blog);
            this.isBlogLiked(blog);
        });
        return Result.ok(records);
    }

queryBlogById

通过blog的id来查找笔记

    @Override
    public Result queryBlogById(Long id) {
        // 1.查询blog
        Blog blog = getById(id);
        if (blog == null) {
            return Result.fail("笔记不存在!");
        }
        // 2.查询blog有关的用户
        queryBlogUser(blog);
        // 3.查询blog是否被点赞
        isBlogLiked(blog);
        return Result.ok(blog);
    }

isBlogLiked

判断该博客是否已经被当前登录用户点赞了,这里采用的是redis的zset数据结构,通过查询分数是否为空,判断此用户是否已经给博客点赞了。注意此方法并没有在接口层定义,因此将其权限设置为private

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

LikeBlog

点赞功能之前需要判断当前用户是否能够点赞

@Override
    public Result likeBlog(Long id) {
        // 1.获取登录用户
        Long userId = UserHolder.getUser().getId();
        // 2.判断当前登录用户是否已经点赞
        String key = BLOG_LIKED_KEY + 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的set集合  zadd key value score
            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_KEY + id;
        // 1.查询top5的点赞用户 zrange key 0 4
        Set<String> top5 = stringRedisTemplate.opsForZSet().range(key, 0, 4);
        if (top5 == null || top5.isEmpty()) {
            return Result.ok(Collections.emptyList());
        }
        // 2.解析出其中的用户id
        List<Long> ids = top5.stream().map(Long::valueOf).collect(Collectors.toList());
        String idStr = StrUtil.join(",", ids);
        // 3.根据用户id查询用户 WHERE id IN ( 5 , 1 ) ORDER BY FIELD(id, 5, 1)
        List<UserDTO> 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);
    }

    @Override
    public Result saveBlog(Blog blog) {
        // 1.获取登录用户
        UserDTO user = UserHolder.getUser();
        blog.setUserId(user.getId());
        // 2.保存探店笔记
        boolean isSuccess = save(blog);
        if(!isSuccess){
            return Result.fail("新增笔记失败!");
        }
        // 3.查询笔记作者的所有粉丝 select * from tb_follow where follow_user_id = ?
        List<Follow> follows = followService.query().eq("follow_user_id", user.getId()).list();
        // 4.推送笔记id给所有粉丝
        for (Follow follow : follows) {
            // 4.1.获取粉丝id
            Long userId = follow.getUserId();
            // 4.2.推送
            String key = FEED_KEY + userId;
            stringRedisTemplate.opsForZSet().add(key, blog.getId().toString(), System.currentTimeMillis());
        }
        // 5.返回id
        return Result.ok(blog.getId());
    }

    @Override
    public Result queryBlogOfFollow(Long max, Integer offset) {
        // 1.获取当前用户
        Long userId = UserHolder.getUser().getId();
        // 2.查询收件箱 ZREVRANGEBYSCORE key Max Min LIMIT offset count
        String key = FEED_KEY + userId;
        Set<ZSetOperations.TypedTuple<String>> typedTuples = stringRedisTemplate.opsForZSet()
                .reverseRangeByScoreWithScores(key, 0, max, offset, 2);
        // 3.非空判断
        if (typedTuples == null || typedTuples.isEmpty()) {
            return Result.ok();
        }
        // 4.解析数据:blogId、minTime(时间戳)、offset
        List<Long> ids = new ArrayList<>(typedTuples.size());
        long minTime = 0; // 2
        int os = 1; // 2
        for (ZSetOperations.TypedTuple<String> tuple : typedTuples) { // 5 4 4 2 2
            // 4.1.获取id
            ids.add(Long.valueOf(tuple.getValue()));
            // 4.2.获取分数(时间戳)
            long time = tuple.getScore().longValue();
            if(time == minTime){
                os++;
            }else{
                minTime = time;
                os = 1;
            }
        }

        // 5.根据id查询blog
        String idStr = StrUtil.join(",", ids);
        List<Blog> blogs = query().in("id", ids).last("ORDER BY FIELD(id," + idStr + ")").list();

        for (Blog blog : blogs) {
            // 5.1.查询blog有关的用户
            queryBlogUser(blog);
            // 5.2.查询blog是否被点赞
            isBlogLiked(blog);
        }

        // 6.封装并返回
        ScrollResult r = new ScrollResult();
        r.setList(blogs);
        r.setOffset(os);
        r.setMinTime(minTime);

        return Result.ok(r);
    }

    private void queryBlogUser(Blog blog) {
        Long userId = blog.getUserId();
        User user = userService.getById(userId);
        blog.setName(user.getNickName());
        blog.setIcon(user.getIcon());
    }
}

标签:userId,redis,博客,id,blog,Result,key,黑马,user
From: https://www.cnblogs.com/xuechuyang/p/17064317.html

相关文章

  • 这个人的Maven博客很不错,我准备从这个人的这篇以及他写的下一篇全部学起
    这个人的博客很不错,我准备从这个人的这篇以及他写的下一篇全部学起Java开发学习(二十九)----Maven依赖传递、可选依赖、排除依赖解析https://www.cnblogs.com/xiaoyh/p/1......
  • Halo博客搭建问题
    问题描述今天晚上在搭建Halo博客时,发现在服务器中是可以正常启动Jar包,并运行正常,但访问域名:8090却提示无法访问。解决办法这个问题其实之前就出现了3次(博主之前重装......
  • Docker部署Redis
    Docker部署Redis更新yum源[#]yumupdate安装Docker[#]yum-yinstalldocker[#]systemctlenabledocker[#]systemctlstartdocker安装Redis创建文件夹[#]mkd......
  • 【Redis技术专区】「实战案例」谈谈使用Redis缓存时高效的批量删除的几种方案
    前因后果之前我们的服务,在上线的时候发现有一些大Key的使用不是很规范,特别是没有设置过期时间,因此导致redis中内存的数据越来越多,目前Redis节点的内存已经快撑不住了。所以......
  • Redis设置开机自启动
    0.前提条件redis_version:7.0.5LinuxAlibabaCloudLinuxrelease3(soaringFalcon)查询版本有如下两种方式:1.通过redis-cli 客户端查询版本信息  //-pip地......
  • Redis分布式锁的五大演进攻略
     本文我们来探讨下如何引入分布式锁解决本地锁的问题。本篇所有代码和业务基于我的开源项目PassJava。 本篇主要内容如下:  一、本地锁的问题 ......
  • Redis分布式锁的五大演进攻略
     本文我们来探讨下如何引入分布式锁解决本地锁的问题。本篇所有代码和业务基于我的开源项目PassJava。 本篇主要内容如下:  一、本地锁的问题 ......
  • Redis分布式锁的五大演进攻略
     本文我们来探讨下如何引入分布式锁解决本地锁的问题。本篇所有代码和业务基于我的开源项目PassJava。 本篇主要内容如下:  一、本地锁的问题 ......
  • 博客园美化及markdown代码问题解决
    博客园美化Cnblogs-Theme-SimpleMemory代码出处GitHub-BNDong/Cnblogs-Theme-SimpleMemoryatv1.2.6说明文档:简介-Document(bndong.github.io)如果无法进入网站,......
  • 补博客 5 ( 1 )
    1005.K次取反后最大化的数组和publicintlargestSumAfterKNegations(int[]nums,intk){if(nums.length==1){returnk%2==1?-nums[......