简单低配版的评论区功能-Java-Springboot+mysql

commentFunction-My-blog: 这个一个实现了简单低配版的评论区功能的后端程序 (gitee.com)

https://gitee.com/flowers-bloom-is-the-sea/commentFunction-My-blog

视频介绍:

1、评论区功能-设计原理_哔哩哔哩_bilibili

https://www.bilibili.com/video/BV1Kh411N7iy/

2、评论区功能-表的设计+java查询实现+接口测试https://www.bilibili.com/video/BV1Su411t7XG/

技术栈:Springboot+mysql

一、创建的数据表:

CREATE TABLE `blog_comment` (                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
                `blog_id` bigint(20) NOT NULL,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
                `comment_user_id` bigint(20) NOT NULL,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                `comment_detail` varchar(255) CHARACTER SET utf8mb4 NOT NULL,                                                                                                                                                                                                                                                                                                                                                                                                                                                                               
                `deep` int(11) NOT NULL,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    
                `answer_id` bigint(20) NOT NULL,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
                `status` bit(1) NOT NULL DEFAULT b'1',                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
                `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 
                KEY `uniqe_key_blog_id` (`blog_id`),                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
                KEY `uniqe_key_comment_user_id` (`comment_user_id`)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
              ) ENGINE=InnoDB DEFAULT CHARSET=utf8  

二、核心实现:

1、controller

    @GetMapping("/{id}")
    @ApiOperation("blogComment信息,获取博客id这篇博客的所有博客的评论信息")
    public Result get(@PathVariable("id") Long id){
        List<BlogCommentDto> blogComments = blogCommentService.getTreeByBlogId(id);
        return Result.ok(blogComments);
    }

2、实现类:

    @Override//通过博客id获取当前博客的所有评论。评论肯定是确定了的,而且有子评论,情况较为复杂,下面是自己的一个实现
    public List<BlogCommentDto> getTreeByBlogId(Long blogId) {
        //1、首先获取根评论链表rootBlogComments
        List<BlogComment> rootBlogComments = getBlogCommentsByBlogIdWithDeepOrderByAsc(blogId, 0);
        //2、再次将首先获取根评论链表rootBlogComments里的BlogComment封装到dto里面,因为BlogComment没有子评论链表属性:nodes
        List<BlogCommentDto> rootBlogDtoComments = getBlogCommentDtoListByBlogComments(rootBlogComments);
        //3、往根评论链表rootBlogDtoComments添加子评论,递归添加,每次递归则将子评论作为递归函数的根评论
        fillRootCommentsByBlogIdWithDeepOrderByAsc(blogId,1,rootBlogDtoComments);
        //4、返回结果
        return rootBlogDtoComments;
    }

    //往根节点评论添加子评论
    private void fillRootCommentsByBlogIdWithDeepOrderByAsc(Long blogId,int deep,List<BlogCommentDto> rootBlogComments) {
        //先获取下一级评论列表
        List<BlogComment> sonBlogComments = getBlogCommentsByBlogIdWithDeepOrderByAsc(blogId, deep);
        //判断子评论链表是否存在
        if (sonBlogComments == null || sonBlogComments.size() == 0) return;
        //逐一封装为dto
        List<BlogCommentDto> sonCommentDtoList = getBlogCommentDtoListByBlogComments(sonBlogComments);
        //根评论字典:作用定位root评论的索引
        HashMap<Long,Integer> rootIndexMap = getIndex(rootBlogComments);

        //往根评论里添加子评论
        for (BlogCommentDto blogCommentDto : sonCommentDtoList) {
            //先找到根节点评论到底是哪一个
            Long answerId = blogCommentDto.getAnswerId();

            //找到rootBlogComments里的定位
            int index = rootIndexMap.get(answerId);

            //通过rootIndexMap这个根评论字典寻找root.commentId=ansId的根评论
            BlogCommentDto rootBlogComment = rootBlogComments.get(index);

            List<BlogComment> nodes = rootBlogComment.getNodes();
            if (nodes == null) {
                nodes = new LinkedList<>();
                rootBlogComment.setNodes(nodes);
            }
            //添加子评论
            nodes.add(blogCommentDto);

        }

        //每次递归则将子评论链表sonCommentDtoList作为递归函数的根评论链表
        fillRootCommentsByBlogIdWithDeepOrderByAsc(blogId,deep + 1,sonCommentDtoList);

    }

    //根评论的定位字典
    private HashMap<Long, Integer> getIndex(List<BlogCommentDto> blogComments) {
        HashMap<Long, Integer> indexMap = new HashMap<>();
        for(int index = 0 ; index < blogComments.size();index++){
            indexMap.put(blogComments.get(index).getCommentUserId(),index);
        }
        return indexMap;
    }

    private List<BlogComment> getBlogCommentsByBlogIdWithDeepOrderByAsc(Long blogId,int deep){
        LambdaQueryWrapper<BlogComment> queryWrapper = new LambdaQueryWrapper<>();//asc升序,从小到大
        queryWrapper.eq(BlogComment::getBlogId,blogId).eq(BlogComment::getDeep,deep).orderByAsc(BlogComment::getCreateTime);
        return baseMapper.selectList(queryWrapper);
    }

    //将BlogComments封装成为BlogCommentDto
    private List<BlogCommentDto> getBlogCommentDtoListByBlogComments(List<BlogComment> blogComments) {
        List<BlogCommentDto> blogCommentDtoList = new ArrayList<>(blogComments.size());
        for (BlogComment blogComment :blogComments) {
            BlogCommentDto blogCommentDto = new BlogCommentDto();
            BeanUtils.copyProperties(blogComment, blogCommentDto);
            blogCommentDtoList.add(blogCommentDto);
        }
        return blogCommentDtoList;
    }

三、测试接口:

localhost:8081/blogComment/1

结果:

{
    "success": true,
    "errorMsg": null,
    "data": [
        {
            "blogId": 1,
            "commentUserId": 1,
            "commentDetail": "a",
            "deep": 0,
            "answerId": 0,
            "status": true,
            "createTime": "2023-06-25T22:13:35",
            "updateTime": "2023-06-25T22:13:35",
            "nodes": null
        },
        {
            "blogId": 1,
            "commentUserId": 2,
            "commentDetail": "b",
            "deep": 0,
            "answerId": 0,
            "status": true,
            "createTime": "2023-06-25T22:17:00",
            "updateTime": "2023-06-25T22:17:00",
            "nodes": [
                {
                    "blogId": 1,
                    "commentUserId": 2,
                    "commentDetail": "bb",
                    "deep": 1,
                    "answerId": 2,
                    "status": true,
                    "createTime": "2023-06-25T22:20:22",
                    "updateTime": "2023-06-25T22:20:22",
                    "nodes": null
                },
                {
                    "blogId": 1,
                    "commentUserId": 3,
                    "commentDetail": "cc",
                    "deep": 1,
                    "answerId": 2,
                    "status": true,
                    "createTime": "2023-06-25T22:21:23",
                    "updateTime": "2023-06-25T22:21:23",
                    "nodes": [
                        {
                            "blogId": 1,
                            "commentUserId": 5,
                            "commentDetail": "ee",
                            "deep": 2,
                            "answerId": 3,
                            "status": true,
                            "createTime": "2023-06-25T22:22:04",
                            "updateTime": "2023-06-25T22:22:04",
                            "nodes": null
                        }
                    ]
                },
                {
                    "blogId": 1,
                    "commentUserId": 4,
                    "commentDetail": "dd",
                    "deep": 1,
                    "answerId": 2,
                    "status": true,
                    "createTime": "2023-06-25T22:21:35",
                    "updateTime": "2023-06-25T22:21:35",
                    "nodes": null
                }
            ]
        },
        {
            "blogId": 1,
            "commentUserId": 3,
            "commentDetail": "c",
            "deep": 0,
            "answerId": 0,
            "status": true,
            "createTime": "2023-06-25T22:17:21",
            "updateTime": "2023-06-25T22:17:21",
            "nodes": null
        },
        {
            "blogId": 1,
            "commentUserId": 4,
            "commentDetail": "d",
            "deep": 0,
            "answerId": 0,
            "status": true,
            "createTime": "2023-06-25T22:17:47",
            "updateTime": "2023-06-25T22:17:47",
            "nodes": null
        },
        {
            "blogId": 1,
            "commentUserId": 5,
            "commentDetail": "e",
            "deep": 0,
            "answerId": 0,
            "status": true,
            "createTime": "2023-06-25T22:17:57",
            "updateTime": "2023-06-25T22:17:57",
            "nodes": null
        }
    ],
    "total": null
}

四、其他

因为之前没学过评论区的功能,于是自己想着去实现一下,正好自己有思路,于是就来实现一个案例了,当然了这个还是没有进行优化,如果要应用到实际生产环境里,那么还需要各种高并发测试以及缓存功能的添加,可以基于这个程序的基础上进行优化。

我也会继续优化下去,敬请期待吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值