springboot博客项⽬实现多级评论(后端)⾸先是这个接⼝需要返回的json数据:可以看到是⼀层套着⼀层来实现多级评论的。
```java
{
"success": true,
springboot结构"code": 200,
"msg": "success",
"data": [
{
"id": 53,
"author": {
"nickname": "李四",
"avatar": "localhost:8080/static/img/logo.b3a48c0.png",
"id": 1
},
"content": "写的好",
"childrens": [
{
"id": 54,
"author": {
"nickname": "李四",
"avatar": "localhost:8080/static/img/logo.b3a48c0.png",
"id": 1
},
"content": "111",
"childrens": [],
"createDate": "1973-11-26 08:52",
"level": 2,
"toUser": {
"nickname": "李四",
"avatar": "localhost:8080/static/img/logo.b3a48c0.png",
"id": 1
}
}
]
,
"createDate": "1973-11-27 09:53",
"level": 1,
"toUser": null
}
]
}
数据库的结构:
要返回给页⾯数据的vo:
public class CommentVo {
private Long id;
private SysUserVo author;
private String content;
private List<CommentVo> childrens;
private String createDate;
private Integer level;
private SysUserVo toUser;
//⽗节点id
private Long parentId;
}
⼤致思路是⾸先从数据库中查出所有记录,根据库中各个评论的⽗⼦关系(通过id确定)来⽣成树。根节点是⼀个空节点,每个1级评论是这个根节点的⼦节点。
树的节点类:
public class MyTreeNode {
private Long parentId;
private Long Id;
//⼦节点
private List<MyTreeNode> commentVoList;
//内容
private CommentVo content;
//创建节点
public static MyTreeNode buildNode(CommentVo commentVo){
MyTreeNode node=new MyTreeNode();
node.Id());
node.ParentId());
node.setContent(commentVo);
return node;
}
public static MyTreeNode buildRoot(){
MyTreeNode node=new MyTreeNode();
node.setId(0L);
node.setParentId(-999L);
node.setContent(null);
ArrayList<MyTreeNode> children=new ArrayList<>();
node.setChildren(children);
return node;
}
public Long getParentId(){
return parentId;
}
public void setParentId(Long parentId){
this.parentId = parentId;
}
public Long getId(){
return Id;
}
public void setId(Long id){
Id = id;
}
public List<MyTreeNode>getChildren(){
return commentVoList;
}
public void setChildren(List<MyTreeNode> commentVoList){
thismentVoList = commentVoList;
}
public CommentVo getContent(){
return content;
}
public void setContent(CommentVo content){
}
}
将所有的评论Vo⽣成树的⼯具类:
在findParentNode⽅法中,根据每⼀个节点的id来寻他的⽗节点。到⽗节点后将⼦节点所携带的CommentVo对象添加到⽗节点的CommentVoList中(为了⽣成前端返回的json数据)。
//实现多级评论,将此篇⽂章的全部评论封装成为⼀棵树
@Component
public class TreeUtils {
public  MyTreeNode buildTree(List<CommentVo> commentVoList){
//创建根节点 id为0
MyTreeNode root = MyTreeNode.buildRoot();
//根节点的⼦节点列表
List<MyTreeNode> rootChildren=new ArrayList<>();
//将评论封装为树的节点
List<MyTreeNode> nodes=new ArrayList<>();
for(CommentVo commentVo : commentVoList){
MyTreeNode TreeNode = MyTreeNode.buildNode(commentVo);
nodes.add(TreeNode);
}
for(MyTreeNode node : nodes){
MyTreeNode parentNode=findParentNode(node,nodes);
if(parentNode!=null){
//不为空,说明有⽗节点
Children()==null){
//说明这个节点是⽗节点的第⼀个⼦节点,创建⼀个⼦节点数组
List<MyTreeNode> children=new ArrayList<>();
children.add(node);
parentNode.setChildren(children);
}else{
}
}else{
//为空,说明⽗节点为根节点
//⽗节点添加⼦节点
rootChildren.add(node);
//⼦节点添加⽗节点id
node.Id());
}
root.setChildren(rootChildren);
}
return root;
}
//到⼦节点的⽗节点
public MyTreeNode findParentNode(MyTreeNode childNode,List<MyTreeNode> allNodes){ for(MyTreeNode node : allNodes){
ParentId().Id())){
//将⼦评论的内容添加到⽗评论的children列表中。
//如果⽗评论(CommentVo)的⼦评论列表为null,则新建⼀个列表。
List<CommentVo> fatherCommentVoList = Content().getChildrens();
if(fatherCommentVoList==null){
fatherCommentVoList=new ArrayList<>();
fatherCommentVoList.Content());
}else{
}
//添加此节点的⽗亲节点
childNode.Id());
return node;
}
}
return null;
}
}
CommentService实现类中查⽂章评论功能的实现:使⽤的是MybatisPlus,并使⽤BeanUtil类的copyProperties⽅法将查询到的comment数据转变为CommentVo数据。
public Result getCommentsById(Long id){
//查出⽂章的所有评论
QueryWrapper<Comment> qw=new QueryWrapper<>();
qw.eq("article_id",id);
List<Comment> comments = commentMapper.selectList(qw);
//所有CommentVo对象的列表
List<CommentVo> commentVos=new ArrayList<>();
//补充评论内容 copy属性转换为vo
for(Comment comment : comments){
CommentVo commentVo=new CommentVo();
//作者信息
SysUser author = AuthorId());
SysUserVo authorVo=new SysUserVo();
commentVo.setAuthor(authorVo);
//toUser信息 level>1 说明有回复对象
Level()>1){
SysUserVo toUserVo=new SysUserVo();
SysUser ToUid());
commentVo.setToUser(toUserVo);
}
commentVos.add(commentVo);
}
//构造成树
MyTreeNode myTree = treeUtils.buildTree(commentVos);
//根节点的⼦节点(即level为1的评论)
List<MyTreeNode> children = Children();
List<CommentVo> level1CommentVo=new ArrayList<>();
for(MyTreeNode child : children){
level1CommentVo.Content());
}
return Result.success(level1CommentVo);
}
controller类:
@RequestMapping("/comments")
public class CommentsController {
@Autowired
CommentService commentService;
@GetMapping("/article/{id}")
public Result getCommentsById(@PathVariable("id") Long id){
CommentsById(id);
}
}
最后是发送请求后得到的数据:
{
"success":true,
"code":200,
"msg":"success",
"data":[
{
"id":53,
"author":{
"id":1,
"nickname":"李四",
"avatar":"localhost:8080/static/img/logo.b3a48c0.png"