评论区模块设计与实现(springboot+mybatis+mysql)

评论模块设计

1. 背景

在创作个人博客网站时想添加一个评论模块,就是那种常规的评论区,用户可以针对博客进行评论,其他用户可以针对用户的评论进行评论回复。效果图如下所示:

在这里插入图片描述

2. 数据库设计

表名为:blog_comment

字段名注释
id评论表主键id
content评论内容
blog_id博文id
user_id发表评论的用户id
level评论层级,分三层,0为针对博文的评论,1为针对0的评论,2为针对1的评论,具体参考效果图进行理解
parent_id回复的评论id,没有为null
root_id根评论id,没有为null,根评论的作用是为了方便归类
create_time评论创建时间

创建数据库评论表sql

CREATE TABLE `blog_comment` (
  `id` varchar(20) NOT NULL COMMENT '主键id',
  `content` varchar(200) NOT NULL COMMENT '评论内容',
  `blog_id` varchar(20) NOT NULL COMMENT '博文id',
  `user_id` varchar(20) NOT NULL COMMENT '评论人id',
  `level` int(11) NOT NULL COMMENT '评论层级,0为针对博文的评论,1为针对0的评论,2为针对1的评论',
  `parent_id` varchar(20) DEFAULT NULL COMMENT '回复的评论id',
  `root_id` varchar(20) DEFAULT NULL COMMENT '根评论id',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '评论时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

数据库表效果图

在这里插入图片描述

3. 后端设计

评论表实体类

@Data
@TableName("blog_comment")
public class BlogComment {

    @TableId
    private String id;

    @TableField("content")
    private String content;

    @TableField("blog_id")
    private String blogId;

    @TableField("user_id")
    private String userId;

    @TableField("level")
    private String level;

    @TableField("parent_id")
    private String parentId;

    @TableField("root_id")
    private String rootId;
    
    @TableField("createTime")
    private String create_time;
}

增删操作的例子就不举了,此处只记录查询操作

查询sql

此处使用的是mybatis的xml写法,其中blog_comment是评论表,user_info是用户信息表,left join左联查询两次是为了获取评论人以及父级评论人的昵称和评论人的头像

    <select id="getCommentListByBlogId" resultType="Map">
        SELECT `blog_comment`.`id`,
               `blog_comment`.`content`,
               `blog_comment`.`level`,
               `blog_comment`.`parent_id` AS parentId,
               `blog_comment`.`root_id` AS rootId,
               `blog_comment`.`user_id` AS userId,
               `blog_comment`.`create_time` AS createTime,
               `user_info`.`avatar`,
               `user_info`.`nickname`,
               user_info1.`nickname` AS replyUserName
        FROM `blog_comment`
        LEFT JOIN `user_info`
            ON `blog_comment`.`user_id` = `user_info`.`id`
        LEFT JOIN `blog_comment` AS blog_com1
            ON `blog_comment`.`parent_id` = blog_com1.`id`
        LEFT JOIN `user_info` AS user_info1
            ON blog_com1.`user_id` = user_info1.`id`
        WHERE `blog_comment`.`blog_id` = #{blogId}
        ORDER BY createTime
    </select>

查询结果后端分类

sql将有关的博文评论记录一次性查出,但是没有对记录进行分类,例如,我的设计中前端需要的数据格式为

在这里插入图片描述

所以需要对数据进行处理,在service层对数据进行重新封装,代码如下

    @Override
    public List<Map> getCommentListByBlogId(String blogId) {

        List<Map> initialList = blogCommentMapper.getCommentListByBlogId(blogId);      //查询博文所有评论记录
        List<Map> resultMap = new ArrayList<>();        //定义返回结果,重新封装返回结果

        /** 第一次循环,将根节点拿出来,这里也可以改为到数据库里查,我也不知道哪种方式更好 **/
        for (Map map : initialList){
            String level = map.get("level").toString();
            if ("0".equals(level)){
                map.put("child",new ArrayList<Map>());
                resultMap.add(map);
            }
        }
        /** 第二次循环,将不是根节点 根据root_id(根节点id)归类 **/
        for (Map map : initialList){
            if (!("0".equals(map.get("level").toString()))){
                /** 不是根节点的数据,对根节点数据进行遍历,然后跟非根节点数据的rootId进行匹配,符合添加到该child节点中 **/
                for (Map rootMap:resultMap){
                    if (rootMap.get("id").toString().equals(map.get("rootId"))){
                        List list = (ArrayList<Map>)rootMap.get("child");
                        list.add(map);
                        break;
                    }
                }
            }
        }
        return resultMap;
    }

至此,全文结束,作者是菜狗,有问题请不吝赐教,原创作品,思路可能雷同,但是行文确为原创。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值