在上次实现对评论区显示之后,我发现了两个问题。参考上次的文章地址【Strelitzia项目】评论区的实现
1.商品评论的数量如果较多的话,由于我没有做分页展示,那不可能一级评论就展示非常大的页面。需要对一级页面进行分页的处理。
2.二级评论区也是同理,也需要对其进行分级展示,但是同时还有一个非常鸡肋的事情在于对未展开状态的评论显示,是我对二级评论区的处理是获取所有的数据之后,再数据进行切割这样的效果,所以对于实现二级评论区,需要重新写一下方法。
原先并没有对评论的获取进行分页,也没有对一级评论和二级评论进行分页,只有一个接口获取到所有的数据,然后将数据进行划分为一级评论和二级评论,这样的好处的就是简单快捷,但是一旦数据量大,那就不可避免出现问题。所以我这次需要将评论分级进行一下思路划分,首先是需要一个返回一级评论以及一级评论下前三条二级评论的接口,再需要一个返回指定一级评论下的二级评论接口。这样就可以做到对评论区的优化。
话不多说,直接附上代码,其中包含代码解析,需要注意的是:实体类的结构没有改变
log.info("comment list start");
// 获取请求的参数
JSONObject requestJson = JSONObject.parseObject(requestData);
Long goodsId = requestJson.getLong("goodsId");
Long currentPage = requestJson.getLong("currentPage");
Long pageSize = requestJson.getLong("pageSize");
// 存储拼接的rootParentId
String rootParentIds = null;
LambdaQueryWrapper<StrelitziaComment> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(StrelitziaComment::getGoodsId,goodsId);
queryWrapper.isNull(StrelitziaComment::getRootParentId);
queryWrapper.eq(StrelitziaComment::getDelFlag,0);
Page<StrelitziaComment> page = new Page<>(currentPage, pageSize);
// 查询一级评论区
IPage<StrelitziaComment> resultPage = commentService.page(page, queryWrapper);
// 对传输id进行处理
List<StrelitziaComment> records = resultPage.getRecords();
for (StrelitziaComment strelitziaComment : records) {
strelitziaComment.setSid(String.valueOf(strelitziaComment.getId()));
strelitziaComment.setSUserId(String.valueOf(strelitziaComment.getUserId()));
strelitziaComment.setSGoodsId(String.valueOf(strelitziaComment.getGoodsId()));
// 对rootParentId进行拼接
if (StringUtils.isEmpty(rootParentIds)){
rootParentIds = String.valueOf(strelitziaComment.getId());
}else {
rootParentIds = rootParentIds + ","+strelitziaComment.getId();
}
}
// 查询二级评论区
if (records.size()!=0){
List<StrelitziaComment> commentSecond = commentService.getCommentFirst(goodsId, rootParentIds);
// 对二级评论区进行处理,将二级评论区的值放入到一级评论区中
for (StrelitziaComment strelitziaComment : records) {
for (StrelitziaComment strelitziaComment1:commentSecond){
strelitziaComment1.setSid(String.valueOf(strelitziaComment1.getId()));
strelitziaComment1.setSUserId(String.valueOf(strelitziaComment1.getUserId()));
strelitziaComment1.setSGoodsId(String.valueOf(strelitziaComment1.getGoodsId()));
// 存放二级评论区
if (strelitziaComment1.getRootParentId().equals(strelitziaComment.getId()) ){
if (strelitziaComment.getChildren()==null){
strelitziaComment.setChildren(new ArrayList<>());
}
strelitziaComment.getChildren().add(strelitziaComment1);
}
}
}
}
AjaxResult ajaxResult = new AjaxResult();
ajaxResult.put("dataSize", resultPage.getRecords().size());
ajaxResult.put("total", resultPage.getTotal());
ajaxResult.put("code", 200);
ajaxResult.put("data", records);
log.info("comment rootList end");
return ajaxResult;
重要的是对于dao层编写的sql语句,commentService.getCommentFirst(goodsId, rootParentIds);代码附上
@Select("SELECT * FROM `comment` cm WHERE\n" +
"(SELECT count(*) FROM `comment` WHERE \n" +
"root_parent_id = cm.root_parent_id and id <= cm.id)<=3 and goods_id = ${goodsId} and root_parent_id in (${rootParentIds})\n" +
"ORDER BY root_parent_id ")
List<StrelitziaComment> getList(Long goodsId,String rootParentIds);
这样看可能不太直观,本次主要讲解的就是这部分的内容,我们从SQL的层面看这段查询语句,附上图片
通过将子查询中作为一个参数count进行输出,可以看到每一条数据后面都有一个count字段,这是两个查询决定的,还可以看到count是呈现出0,1,2,3数值变化,其中是一级评论的count为0,二级评论根据主键id的大小分为1,2,3。我们再结合count<=3这一条件,就可以排除count>3的数据。这两个查询可以看作是一条一条数据去查询,当查询到一级评论时,不满足where root_parent_id = cm.root_parent_id AND id <= cm.id条件,所以count是0;当查询到二级评论时,例如上图给出的倒数第三条数据,条件中有一条写的是id <= cm.id,此时前面有两条数据是符合条件并且id小于等于倒数第三条数据的id,所以的count为3。以此类推可以反映出我们DAO层写的查询代码其实就是一种变迁。对于DAO层的代码,将goodsId作为传入参数,并且限制传入的rootParentId,来查询指定商品,指定一级评论的的前三条二级评论。
那么为什么要这么做的原因就在于,首先会对一级评论做出分页,如果不对rootParentId做出限制,那么就会查询出来所有数据的前三条二级评论,这是我们不想要的,故还需要对二级评论的查询做出限制,提高效率。这就是一级评论区接口的重点重点了,这条sql语句的重要性不言而喻,还需要多多复习温故而知新。
修改完成一级评论区接口后可以看到,此次一级评论区已经可以分页并且自动获取到指定的前三条二级子评论了,所以二级评论区接口就只需要完成对应商品下且对应一级评论下的评论进行分页。那么这样看起来就是比较正常的一个分页接口。
@Operation(summary = "获取指定商品的下面分页展示所有评论")
@RequestMapping(value = "/secList",method = RequestMethod.POST)
public AjaxResult list(@RequestBody String requestData, HttpServletRequest request) throws ParseException {
log.info("comment secList start");
// 获取请求的参数
JSONObject requestJson = JSONObject.parseObject(requestData);
Long goodsId = requestJson.getLong("goodsId");
Long currentPage = requestJson.getLong("currentPage");
Long pageSize = requestJson.getLong("pageSize");
String rootParentId = requestJson.getString("rootParentId");
// 查询指定商品的二级子评论,并且做好分页处理
LambdaQueryWrapper<StrelitziaComment> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(StrelitziaComment::getDelFlag,0);
queryWrapper.eq(StrelitziaComment::getRootParentId,rootParentId);
queryWrapper.eq(StrelitziaComment::getGoodsId,goodsId);
// 创建分页对象
Page<StrelitziaComment> page = new Page<>(currentPage, pageSize);
// 执行分页查询
IPage<StrelitziaComment> resultPage = commentService.page(page, queryWrapper);
// 对传输id进行处理
List<StrelitziaComment> records = resultPage.getRecords();
// 对获取到的列表进行处理
for (StrelitziaComment strelitziaComment : records) {
strelitziaComment.setSid(String.valueOf(strelitziaComment.getId()));
strelitziaComment.setSUserId(String.valueOf(strelitziaComment.getUserId()));
strelitziaComment.setSGoodsId(String.valueOf(strelitziaComment.getGoodsId()));
}
AjaxResult ajaxResult = new AjaxResult();
ajaxResult.put("dataSize", resultPage.getRecords().size());
ajaxResult.put("total", resultPage.getTotal());
ajaxResult.put("code", 200);
ajaxResult.put("data", records);
log.info("comment secList end");
return ajaxResult;
}
这些就比较简单啦。比较基础的二级评论区分页展示数据,前端的代码我就不进行展示了,毕竟比较繁琐,做来做去也都是比较基础的数据展示,附上项目成果截图。