前言
开发过程中遇到的关于PageHelper失效的问题,一个是因为对PageHelper作用返回的list结果集进行二次操作导致的total总数等于查询到的数量。一个是因为使用了collection 和association 标签处理复杂映射时
PageHelper 分页total失效或当前页含数量不匹配问题解决方案 含原理分析
1 第一种情况,返回list结果之后进行了二次封装
这个问题的流程基本如下:
- 设置分页参数 PageHelper.startPage(1,10)
- 通过查询返回一个list列表(这时并没有丢失总数tatal)
- 真实情况往往需要继续对list进行业务处理,
还要对结果集进行加工,将结果集转变了类型
- 处理之后的list,分页信息就是错误的。
如下简单的代码逻辑
public PageInfo<DataDetailVo> search(String keyword) {
List<DataDetailVo> voList = new ArrayList<>();
// 1.设置分页,第1页,10条
PageHelper.startPage(1,10);
// 2.查询结果集
List<DataVo> dataVos = xxxMapper.searchDataList(keyword);
// 3.通过上一步的结果集构造 PageInfo
PageInfo<DataVo> pageSuccess = new PageInfo<>(dataVos);
// 结果是对的
log.info("pageSuccess:" + JSON.toJSONString(pageSuccess));
// 4.真实情况,还要对结果集进行加工,将结果集转变了类型
for (DataVo dataVo : dataVos) {
DataDetailVo vo = new DataDetailVo();
BeanUtils.copyProperties(dataVo, vo);
voList.add(vo);
}
// 5.这时候,通过新的结果集构造 PageInfo,分页信息就是错误的
PageInfo<DataDetailVo> pageFail = new PageInfo<>(voList);
log.info("pageFail:" + JSON.toJSONString(pageFail));
return pageFail;
}
2 问题原因
因为第5步构造 PageInfo 时使用了一个新的 List,才导致分页失效的。
因为在第2步中 看上去返回的是一个普通的list,其实包裹了一层page,断点的话可以看到。我们进行处理之后的page肯定是没有的,所以导致paga中存储的total总数丢失。
同时pagehelper也会检查如果total为null,那么就会吧查询的这一页的list.size()赋值给tatal
3 解决方式
方式1:不要加工了嘛,mapper 返回啥,就直接给调用方返回啥。
方式2:直接让 mapper 返回最终返回给调用方的类型,不要在加工的时候生成新的 List 了。
这种也可以,但是改动可能比较大,因为有的 Mapper 层的方法是供很多其他方法调用的,Mapper 层基本上只需要返回最通用的类型。不能为了某个方法调用方,而让其他调用方也做出改变。
方式3:在构造 PageInfo 的时候稍加修改就可以了
只需要将原本构造错误的 PageInfo
.
PageInfo<DataDetailVo> pageFail = new PageInfo<>(voList);
log.info("pageFail:" + JSON.toJSONString(