博客评论自己与自己的多对多处理
domain类
dao层
因为用的JPA框架(底层是HIbernate)所以根据方法名自动查询,这一层就把所有评论就都查询出来了
service层
//找出所有评论并且扁平化处理(一共两级目录)
@Override
public List<Comment> listCommentByBlogId(Long blogId) {
Sort sort = Sort.by(Sort.Direction.ASC,"createTime");
List<Comment> comments = commentRepository.findByBlogIdAndParentCommentNull(blogId,sort);
return eachComment(comments);
}
/**
* 循环每个*的评论节点 其实就是复制
* @param comments
* @return
*/
private List<Comment> eachComment(List<Comment> comments){
List<Comment> commentsView = new ArrayList<>();
for(Comment comment : comments){
Comment c = new Comment();
BeanUtils.copyProperties(comment,c);//避免产生数据库上面的一些变化
commentsView.add(c);
}
//将评论的各层子代到第一级子代集合(二级目录)中
combineChildren(commentsView);
return commentsView;
}
/**
* root根节点,blog不为空的对象集合
* @param comments
*/
private void combineChildren(List<Comment> comments){
for(Comment comment : comments){
List<Comment> replys = comment.getReplyComments();
for(Comment reply : replys){
//循环迭代,找出子代,存放在temReplys中
recursively(reply);
}
//修改*节点的reply集合为迭代处理后的集合
comment.setReplyComments(tempReplys);
//清除临时存放区
tempReplys = new ArrayList<>();
}
}
//存放迭代找出的所有子代的集合
private List<Comment> tempReplys = new ArrayList<>();
/**
*递归迭代,把深层次的回复都归为二级目录
*/
private void recursively(Comment comment){
tempReplys.add(comment);//从第二级的评论开始添加到临时存放集合
if(comment.getReplyComments().size() > 0){
List<Comment> replys = comment.getReplyComments();
for(Comment reply : replys){
tempReplys.add(reply);
if(reply.getReplyComments().size() > 0){
recursively(reply);
}
}
}
}
controller层
@GetMapping("/comments/{blogId}")
public String comments(@PathVariable Long blogId, Model model){//ajax局部刷新commentList
model.addAttribute("comments",commentService.listCommentByBlogId(blogId));
return "blog :: commentList";
}
ps:之前也是被面试官问到这个问题,当时回答的不够清楚,所以特地回来总结一番,希望他不会看到。。。