1. 创立表
biz_comment
biz_users
表的字段,类型,长度等均可依据你的业务需要,随你施展。这里只提供必要字段。
2. 通过主动生成代码生成 biz_comment 表
domain :
阐明:
@TableField(exist = false)
示意此字段不在表中,为本人定义的属性,不须要mybatis去找此字段。
private List<Comment> subComments;
把子评论当做是 Comment 的一条属性装进List汇合中,Comment是所有父级评 论,而 subComments 是此父级的所有子评论。如果你违心能够独自写一个 CommentVO来封装所有子评论。(举个例子:一篇文章,A进行了回复,B感觉A说的不错回复了 A,C也感觉A说的不错回复了A,这时候A就是父级,咱们就把A装进Comment外面,通过循 环和set办法将B、C装进 subComments 外面成为A的子评论 )这一步很重要,心愿先能 了解这一步再持续往下做。
package com.cema.manage.project.manage.comment.domain;/** * 评论表 biz_comment * * @author reasahi * @date 2021-04-22 */@TableName(value = "biz_comment")public class Comment extends Model<Comment>{private static final long serialVersionUID=1L;/** 编号 */ @TableId(value = "id") private Integer id;/** 用户ID */ @TableField(value = "bu_id") private Integer buId;/** 文章ID */ @TableField(value = "bp_id") private Integer bpId;/** 回复用户ID */ @TableField(value = "wc_id") private Integer wcId;/** 内容 */ @TableField(value = "wc_content") private String wcContent;/** 评论工夫 */ @TableField(value = "create_time") private String createTime; @TableField(exist = false) private List<Comment> subComments; public List<Comment> getSubComments() { return subComments; } public void setSubComments(List<Comment> subComments) { this.subComments = subComments; } /** * 设置:编号 */public void setId(Integer id) { this.id = id; }/** * 获取:编号 */public Integer getId() { return id; }/** * 设置:用户ID */public void setBuId(Integer buId) { this.buId = buId; }/** * 获取:用户ID */public Integer getBuId() { return buId; }/** * 设置:文章ID */public void setBpId(Integer bpId) { this.bpId = bpId; }/** * 获取:文章ID */public Integer getBpId() { return bpId; }/** * 设置:回复用户ID */public void setWcId(Integer wcId) { this.wcId = wcId; }/** * 获取:回复用户ID */public Integer getWcId() { return wcId; }/** * 设置:内容 */public void setWcContent(String wcContent) { if(wcContent!=null){ if(wcContent.trim().isEmpty()){ this.wcContent =null; }else{ this.wcContent = wcContent; } } }/** * 获取:内容 */public String getWcContent() { return wcContent; }/** * 设置:评论工夫 * @param createTime */public void setCreateTime(String createTime) { this.createTime = createTime; }/** * 获取:评论工夫 * @return */public String getCreateTime() { return createTime; }@Overrideprotected Serializable pkVal(){ return this.id; } }
mapper :
阐明:
两个接口别离对应两条查问,level1Query为查问父级,另一个为查问子级。
package com.cema.manage.project.manage.comment.mapper;/** * 评论 数据层 * * @author reasahi * @date 2021-04-22 */public interface CommentMapper extends BaseMapper<Comment>{ List<Comment> level1Query(Map<String,Object> map); List<Comment> level2Query(Map<String,Object> map);}
xml :
阐明:
bu_id为用户id,wc_id 为回复的用户的id。通过wc_id为null能够判断查问进去的后果都为 父级id。(构想一下,你去评论一篇文章,你本人有个id,或者说是用户名,这个id/用户名就 是bu_id,你评论了文章,文章是没有wc_id的吧,所以像数据库存入了默认值null,当然你可 以存0或其它的,随便就好。这就是父级。在构想一下,这次你拿着你的id/用户名不去评论文 章了,你去评论了一篇文章下诸多评论者A,你回复了A,这样在数据库是怎么存入的呢?是不 是须要拿着你的bu_id和A的bu_id都存入数据库,其实A的bu_id就是wc_id,没错吧,那是不 是就能够通过wc_id判断所有在同一篇文章回复了A的人,咱们只须要拿出这个要害的 wc_id。)
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.cema.manage.project.manage.comment.mapper.CommentMapper"> <!-- biz_comment --> <resultMap id="resultMapComment" type="com.cema.manage.project.manage.comment.domain.Comment"> <id column="id" property="id"></id> <result column="bu_id" property="buId"></result> <result column="bp_id" property="bpId"></result> <result column="wc_id" property="wcId"></result> <result column="wc_content" property="wcContent"></result> <result column="create_time" property="createTime"></result> </resultMap> <select id="level1Query" resultMap="resultMapComment" parameterType="map"> SELECT u.bu_mail, c.bp_id, c.wc_id, c.bu_id, c.create_time, c.wc_content FROM biz_comment c LEFT JOIN biz_users_1 u ON c.bu_id = u.id WHERE c.wc_id IS NULL AND c.bp_id = #{bp_id} ORDER BY c.create_time DESC LIMIT #{current}, #{size}; </select> <select id="level2Query" resultMap="resultMapComment" parameterType="map"> SELECT u.bu_mail, c.bp_id, c.wc_id, c.bu_id, c.create_time, c.wc_content FROM biz_comment c LEFT JOIN biz_users_1 u ON c.wc_id = u.id WHERE c.wc_id IS NOT NULL AND bu_id = #{bu_id} AND bp_id = #{bp_id} ORDER BY c.create_time DESC </select></mapper>
service :
package com.cema.manage.project.manage.comment.service;/** * 评论 服务层 * * @author reasahi * @date 2021-04-22 */public interface ICommentService extends IService<Comment> { List<Comment> getCommentList(Map<String,Object> map);}
serviceImpl :
阐明:
如果后面都能了解,这里也很好了解,首先调用level1Query拿到父级,循环遍历父级拿到 bu_id,bp_id存入map给level2Query,再顺次遍历子评论,最初将所有父/子都存入汇合中, 返回给前端。
package com.cema.manage.project.manage.comment.service;/** * 评论 服务层实现 * * @author reasahi * @date 2021-04-22 */@Servicepublic class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements ICommentService { @Resource private CommentMapper commentMapper; @Override public List<Comment> getCommentList(Map<String, Object> map) { Map<String, Object> resultMap = new HashMap<>(); List<Comment> resultList = new ArrayList<>(); List<Comment> parentComments = commentMapper.level1Query(map); for (Comment c : parentComments) { resultMap.put("bu_id",c.getBuId()); resultMap.put("bp_id",c.getBpId()); List<Comment> subComments = commentMapper.level2Query(resultMap); List<Comment> reply = new ArrayList<>(); for (Comment c1 : subComments) { reply.add(c1); } c.setSubComments(reply); resultList.add(c); } return resultList; }}
controller :
阐明:
所有用户id都须要通过token来获取,没有的话为了测试能够写死,无所谓的。current为第几页,前端是不会返回0的,因为没谁会看第0页是吧,都是从第一页开始,所以做一个简略的解决。咱们对立返回JSON,便于开发。
@PostMapping("getCommentList") @ResponseBody public String getCommentList(HttpServletRequest request) { Map<String, Object> resultMap = new HashMap<>(); String token = (String) request.getAttribute("token"); Users users = (Users) redisService.get(token); Integer bu_id = users.getId(); String current = request.getParameter("current"); String size = request.getParameter("size"); String bp_id = request.getParameter("bp_id"); resultMap.put("bu_id", bu_id); resultMap.put("current", (Integer.parseInt(current) - 1) * Integer.parseInt(size)); resultMap.put("size", Integer.parseInt(size)); resultMap.put("bp_id", Integer.parseInt(bp_id)); List<Comment> comments = commentService.getCommentList(resultMap); JSONObject jsonStr = jsonDataUtilsInterFase.getJsonObject(comments, attributeUtilsInterFase.getAttributeName(String.class, TestAttributeUtils.FILTER_PROTECTED), TestJSONDataUtils.SUCCESS_CODE1); return jsonStr.toString(); }
5. 总结
至此代码完结,能够开始测试了,返回的JSON如下:
{ "code": 1, "datalist": [ 父亲评论列表 { "buId": 用户id, "wcId": 回复用户id, "createTime": 创立工夫, "subComments": [ // 儿子评论列表 { "buId": 用户id, "wcId": 回复用户id, "createTime": 创立工夫, "subComments": [ 三级的回复 不必管 没数据 ], "bpId": 文章id, "id": 主键, "wcContent": "回复用户的评论" }, { "buId": 用户id, "wcId": 回复用户id, "createTime": 创立工夫, "subComments": [ 三级的回复 不必管 没数据 ], "bpId": 文章id, "id": 主键, "wcContent": "回复用户的评论" } ], "bpId": 文章id, "id": 主键, "wcContent": "回复文章的评论" } ], "timetamp": 1619322835508}
此接口重点就在于SQL的书写和数据结构。你须要通过SQL筛选出所有父评论和子评论。数据结构是父包着子,你能够用List汇合装,也能够用其它的,封装一个vo来装,本文只提供一个思路,你能够撸的更好。
byeBye ^ ^~