PageHelper 是 MyBatis 生態**最流行、最省心**的分頁插件,支持 Oracle、MySQL、MariaDB、SQLite、HsqlDB、PostgreSQL 六大數據庫。
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"/> <!-- 數據庫類型 -->
<property name="rowBoundsWithCount" value="true"/> <!-- RowBounds 也查總數 -->
<property name="pageSizeZero" value="true"/> <!-- pageSize=0 查全部 -->
<property name="reasonable" value="true"/> <!-- 頁碼越界自動修正 -->
</plugin>
</plugins>
PageHelper.startPage + 強轉 Page<E>// 查第 1 頁,每頁 10 條
PageHelper.startPage(1, 10);
List<Country> list = countryMapper.selectIf(1);
// 強轉獲取分頁元數據
Page<Country> page = (Page<Country>) list;
long total = page.getTotal(); // 總記錄數
int pages = page.getPages(); // 總頁數
int pageNum = page.getPageNum(); // 當前頁碼
int pageSize = page.getPageSize(); // 每頁大小
boolean hasNext = page.isHasNextPage();
PageInfo 包裝結果PageHelper.startPage(1, 10);
List<Country> list = countryMapper.selectAll();
// 包裝
PageInfo<Country> pageInfo = new PageInfo<>(list);
// 完整元數據
assertEquals(1, pageInfo.getPageNum());
assertEquals(10, pageInfo.getPageSize());
assertEquals(1, pageInfo.getStartRow()); // 當前頁起始行號 (1-based)
assertEquals(10, pageInfo.getEndRow()); // 當前頁結束行號
assertEquals(183, pageInfo.getTotal()); // 總記錄數
assertEquals(19, pageInfo.getPages()); // 總頁數
assertEquals(1, pageInfo.getFirstPage()); // 首頁頁碼
assertEquals(8, pageInfo.getLastPage()); // 尾頁頁碼
assertEquals(true, pageInfo.isFirstPage());
assertEquals(false, pageInfo.isLastPage());
assertEquals(false, pageInfo.isHasPreviousPage());
assertEquals(true, pageInfo.isHasNextPage());
assertEquals(8, pageInfo.getNavigatePages()); // 導航頁碼數
assertEquals(1, pageInfo.getNavigateFirstPage());
assertEquals(8, pageInfo.getNavigateLastPage());
assertEquals(8, pageInfo.getNavigatepageNums().length);
| 場景 | 解決方案 |
|---|---|
| 手動控制 count 查詢 | PageHelper.startPage(pageNum, pageSize, false) 第三參數 count=false 跳過總數查詢,極大提升大表性能 |
| 不想污染 ThreadLocal | 使用 PageHelper.offsetPage(offset, limit) (MyBatis 3.5+) 無 ThreadLocal,線程安全 |
| Spring Boot 整合 | 引入 pagehelper-spring-boot-starter,application.yml 配置 pagehelper.helper-dialect=mysql |
| 多數據源 | 每個 SqlSessionFactory 獨立配置插件,或使用 PageHelper.autoDialect=true 自動識別 |
| 分頁參數來自前端 | Controller 直接透傳 pageNum/pageSize,配合 reasonable=true 防止非法值 |
Executor.query(),解析 MappedStatement 獲取原始 SQL。dialect 方言生成分頁 SQL:MySQL LIMIT offset, size、Oracle ROWNUM 子查詢、PostgreSQL LIMIT/OFFSET 等。SELECT COUNT(*) FROM (original_sql) tmp 獲取總數(可關閉)。Page<E>(繼承 ArrayList),攜帶分頁屬性。offsetPage 或手動 clearPage()。startPage 會被內層覆蓋,需手動保存恢復或使用 PageHelper.clearPage()。PageHelper 讓分頁從「業務邏輯」變成「基礎設施」,專注業務才是正道。