PageHelper通过PageInfo获取total数据错误
2018-08-29 本文已影响0人
朝五晚九浪迹天涯
说明
项目环境基于SpringBoot2.x + Mybatis3 + PageHelper5.x, 其他环境下是否有效未经检测.
使用Maven引入依赖, 在此只贴出PageHelper的依赖, 其他请自行配置.
PageHelper的依赖
<dependency>
<groupId> com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
Note
如果你使用xml配置mybatis, 网上可能有介绍加入如下配置
<!-- 配置mybatis的分页插件PageHelper -->
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
</plugin>
</plugins>
该配置在PageHelper5.x中会报错, 直接删除即可.
引言
项目中使用PageHelper进行分页查询, 结果集中携带total动态生成分页标签. 常规做法, 通过mapper获取结果集List初始化PageInfo, 再调用getTotal方法得到总数.
核心语句
//pageNum和pageSize自行获取
PageHelper.startPage(pageNum, pageSize);
List<User> users= userService.getUsers();
PageInfo info = new PageInfo(list);
int total = info.getTotal();
在真正使用时, 会发现total的值并不等于数据库中记录总数, 并且该值永远等于查询页的记录数, 即getTotal和getSize()效果相同. 读者若自行查看SQL日志, 可发现startPage()方法成功执行, 返回的List是符合查询条件的.
解决方法
在PageHelper的官方Github中, 有类似Issues, 但已关闭.
变更语句
Page page = PageHelper.startPage(pageNum, pageSize);
//使用page的getTotal()
int total = page.getTotal();
问题分析
Issues中有老哥认为通过PageInfo得到total的途径是没毛病的, 但问题确实发生了, 而且此方法能解决燃眉之急, 那我就来啃啃源码探探究竟 :)
从PageInfo看起
/**
* 包装Page对象
*
* @param list
*/
public PageInfo(List<T> list) {
this(list, 8);
}
/**
* 包装Page对象
*
* @param list page结果
* @param navigatePages 页码数量
*/
public PageInfo(List<T> list, int navigatePages) {
super(list);
if (list instanceof Page) {
Page page = (Page) list;
this.pageNum = page.getPageNum();
this.pageSize = page.getPageSize();
this.pages = page.getPages();
this.size = page.size();
//由于结果是>startRow的,所以实际的需要+1
if (this.size == 0) {
this.startRow = 0;
this.endRow = 0;
} else {
this.startRow = page.getStartRow() + 1;
//计算实际的endRow(最后一页的时候特殊)
this.endRow = this.startRow - 1 + this.size;
}
} 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;
//计算导航页
calcNavigatepageNums();
//计算前后页,第一页,最后一页
calcPage();
//判断页面边界
judgePageBoudary();
}
}
这部分不涉及total, 直接点开super()
public PageSerializable(List<T> list) {
this.list = list;
if(list instanceof Page){
this.total = ((Page)list).getTotal();
} else {
this.total = list.size();
}
}