說明
項目環(huán)境基于SpringBoot2.x + Mybatis3 + PageHelper5.x, 其他環(huán)境下是否有效未經(jīng)檢測.
使用Maven引入依賴, 在此只貼出PageHelper的依賴, 其他請自行配置.
PageHelper的依賴
<dependency>
<groupId> com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
Note
如果你使用xml配置mybatis, 網(wǎng)上可能有介紹加入如下配置
<!-- 配置mybatis的分頁插件PageHelper -->
<plugins>
<!-- com.github.pagehelper為PageHelper類所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
</plugin>
</plugins>
該配置在PageHelper5.x中會報錯, 直接刪除即可.
引言
項目中使用PageHelper進行分頁查詢, 結(jié)果集中攜帶total動態(tài)生成分頁標簽. 常規(guī)做法, 通過mapper獲取結(jié)果集List初始化PageInfo, 再調(diào)用getTotal方法得到總數(shù).
核心語句
//pageNum和pageSize自行獲取
PageHelper.startPage(pageNum, pageSize);
List<User> users= userService.getUsers();
PageInfo info = new PageInfo(list);
int total = info.getTotal();
在真正使用時, 會發(fā)現(xiàn)total的值并不等于數(shù)據(jù)庫中記錄總數(shù), 并且該值永遠等于查詢頁的記錄數(shù), 即getTotal和getSize()效果相同. 讀者若自行查看SQL日志, 可發(fā)現(xiàn)startPage()方法成功執(zhí)行, 返回的List是符合查詢條件的.
解決方法
在PageHelper的官方Github中, 有類似Issues, 但已關閉.
變更語句
Page page = PageHelper.startPage(pageNum, pageSize);
//使用page的getTotal()
int total = page.getTotal();
問題分析
Issues中有老哥認為通過PageInfo得到total的途徑是沒毛病的, 但問題確實發(fā)生了, 而且此方法能解決燃眉之急, 那我就來啃啃源碼探探究竟 :)
從PageInfo看起
/**
* 包裝Page對象
*
* @param list
*/
public PageInfo(List<T> list) {
this(list, 8);
}
/**
* 包裝Page對象
*
* @param list page結(jié)果
* @param navigatePages 頁碼數(shù)量
*/
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();
//由于結(jié)果是>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();
}
}