今天突然出现一个bug,发现表格页卡出现问题了,选择一页显示50条数据,好着没问题,然后选显示10条,就出现问题了,分页功能不起作用了,等于说是返回给页面的total总数不对劲。
一顿操作debug之后,发现是执行sql语句返回的数据条数就是10条,当时我就纳闷了,这么简单的bug不应该是PageHelper出现的啊,毕竟好歹也是好多人用的分页插件呢。(后来发现是自己找问题的方向错了 -.-)
然后就吧问题瞄准了sql语句,后来折腾了半天,发现sql没啥问题。百思不得其解,头发都掉了几根,为了不掉头发,就百度吧。
百度出来发现问题不在sql,我们都知道PageHelper在startPage之后,等于是对下一次查询sql切面处理了。看了看代码:
PageHelper.startPage(demandScreening.getPage(), demandScreening.getSize());
List list =
procurementDemandService.procurementDemandList(demandScreening);
PageInfo pageInfo = new PageInfo(list);
没啥问题啊。
然后看到了这个:
https://blog.csdn.net/fchen_123/article/details/82881381
这个大佬说是因为对查询完sql的返回集合做了foreach操作,产生了不同的集合,然后就出现和我一样的问题了。
这时我才发现我其实也对集合进行排序,最后排序完的集合也是发现改变了。问题终于找到了。
//排序
list = list.stream()
.sorted(Comparator.comparing(ProcurementDemandVo::getMaxDate).reversed())
.collect(Collectors.toList());
上面那篇文章中大佬说有个
PagerCopyUtil.setPageInfo(retPageList,plist,clueInfoDTOList);
不过,我没找到。那就只能自己想办法了,不过问题找出来了,bug就等于解决一半了。
改成这样,就好了:
public PageInfo procurementDemandList(DemandScreening demandScreening) {
List list =
procurementDemandMapper.procurementDemandList(demandScreening);
//执行完sql,直接把结果给PageInfo
PageInfo pageInfo = new PageInfo(list);
//...
//接下来在进行排序
//排序
list = list.stream()
.sorted(Comparator.comparing(ProcurementDemandVo::getMaxDate).reversed())
.collect(Collectors.toList());
//最后吧list集合替换掉
pageInfo.setList(list);
//只能返回PageInfo对象了
return pageInfo;
}
测试通过,没问题,就这样改。
可是为啥集合变了就出现问题了,这不应该啊,看看源码:
super(list);
this.isFirstPage = false;
this.isLastPage = false;
this.hasPreviousPage = false;
this.hasNextPage = false;
if (list instanceof Page) {
Page page = (Page)list;
this.pageNum = page.getPageNum();
this.pageSize = page.getPageSize();
this.pages = page.getPages();
this.size = page.size();
if (this.size == 0) {
this.startRow = 0;
this.endRow = 0;
} else {
this.startRow = page.getStartRow() + 1;
this.endRow = this.startRow - 1 + this.size;
}
//pageNum,size,pageSize,startRow......
} else if (list instanceof Collection) {
this.pageNum = 1;
this.pageSize = list.size();
this.pages = this.pageSize > 0 ? 1 : 0;
this.size = list.size();
this.startRow = 0;
this.endRow = list.size() > 0 ? list.size() - 1 : 0;
}
if (list instanceof Collection) {
this.navigatePages = navigatePages;
this.calcNavigatepageNums();
this.calcPage();
this.judgePageBoudary();
}
调用了父类的构造函数。
public PageSerializable(List list) {
this.list = list;
if (list instanceof Page) {
this.total = ((Page)list).getTotal();
} else {
//我们就是走了这一步,把size赋值给了total
this.total = (long)list.size();
}
}
紧跟着PageHelper.startPage()方法第一个select语句会被分页,并吧返回对象改成一个Page对象,所以这里会判断list是否是Page对象。
问题找到了,也算是给自己一个教训吧,以后没事还是要看看源码理解理解思路。
转载:
PageHelper分页插件的源码分析
这位老哥写的很详细,想分析源码的可以参考参考他的文章。