评论模块设计
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;
}
至此,全文结束,作者是菜狗,有问题请不吝赐教,原创作品,思路可能雷同,但是行文确为原创。