MyBatis實現(xiàn)分頁全過程
下面我將詳細講解MyBatis實現(xiàn)分頁的幾種方式,通過通俗易懂的故事和代碼示例幫助理解:
故事背景
假設(shè)我們經(jīng)營一個"圖書管理系統(tǒng)",數(shù)據(jù)庫中有10萬本圖書。
當用戶查看圖書列表時,一次性加載所有數(shù)據(jù)會導(dǎo)致系統(tǒng)崩潰(就像把整個圖書館的書都堆在收銀臺上)。
這時就需要分頁功能——每次只展示"一架子書"(如每頁20本)。
一、MyBatis實現(xiàn)分頁的三種方式
1.手動SQL分頁(物理分頁)
SELECT * FROM books LIMIT #{start}, #{pageSize}
原理:
直接在SQL中通過LIMIT(MySQL)或ROWNUM(Oracle)控制數(shù)據(jù)范圍。
代碼示例:
// Mapper接口
List<Book> getBooksByPage(@Param("start") int start, @Param("pageSize") int pageSize);
// 調(diào)用方式(獲取第3頁,每頁20條)
int pageNum = 3;
int pageSize = 20;
List<Book> books = bookMapper.getBooksByPage((pageNum-1)*pageSize, pageSize);
? 優(yōu)點:
- 性能最佳(數(shù)據(jù)庫只返回所需數(shù)據(jù))
- 完全掌控SQL邏輯
? 缺點:
- 需手動計算偏移量(如
(pageNum-1)*pageSize) - 不同數(shù)據(jù)庫語法不同(MySQL用LIMIT,Oracle用ROWNUM)
2.RowBounds分頁(邏輯分頁)
RowBounds rowBounds = new RowBounds(40, 20); // 跳過前40條,取20條
List<Book> books = sqlSession.selectList("getAllBooks", null, rowBounds);
原理:
先查詢所有數(shù)據(jù)到內(nèi)存,再在Java層截取指定范圍(像把整個圖書館的書運到倉庫,再挑出20本)。
? 優(yōu)點:
- 使用簡單,無需改SQL
? 缺點:
- 性能災(zāi)難(數(shù)據(jù)量大時內(nèi)存溢出)
- 實際工作中禁止使用!
3.分頁插件(推薦方案)
使用PageHelper插件(最主流方案):
// 只需在查詢前設(shè)置分頁參數(shù)
PageHelper.startPage(3, 20); // 第3頁,每頁20條
List<Book> books = bookMapper.selectAllBooks();
// 獲取分頁信息
PageInfo<Book> pageInfo = new PageInfo<>(books);
System.out.println("總頁數(shù):" + pageInfo.getPages());
原理:
通過MyBatis攔截器自動改寫SQL,添加LIMIT語句(像有個智能機器人幫你從書架上拿指定范圍的書)。
配置步驟:
- 添加依賴:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.2</version>
</dependency>
- 配置攔截器(mybatis-config.xml):
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"/>
</plugins>
? 優(yōu)點:
- 零侵入(不改動原SQL)
- 自動適配不同數(shù)據(jù)庫
- 返回豐富分頁信息(總頁數(shù)/當前頁等)
二、分頁原理對比表
| 方式 | 性能 | 易用性 | 適用場景 |
|---|---|---|---|
| 手動SQL分頁 | ???? | ?? | 簡單SQL,明確數(shù)據(jù)庫類型 |
| RowBounds | ? | ???? | 禁止生產(chǎn)使用 |
| PageHelper | ???? | ????? | 99%的生產(chǎn)場景 |
三、總結(jié)
絕對避免使用RowBounds邏輯分頁(除非數(shù)據(jù)量極?。?/p>
簡單場景可用手動SQL分頁(需處理數(shù)據(jù)庫差異)
PageHelper是終極解決方案:
- 自動生成分頁SQL
- 統(tǒng)一不同數(shù)據(jù)庫行為
- 返回完整分頁元數(shù)據(jù)
百萬級數(shù)據(jù)分頁優(yōu)化:
-- 使用索引覆蓋優(yōu)化 SELECT * FROM books WHERE id >= (SELECT id FROM books ORDER BY id LIMIT 1000000, 1) LIMIT 20

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java匿名內(nèi)部類導(dǎo)致內(nèi)存泄露的原因與解決方案詳解
這篇文章主要為大家詳細介紹了Java因為匿名內(nèi)部類導(dǎo)致內(nèi)存泄露的原因以及其解決方案,文中的示例代碼講解詳細,希望對大家有所幫助2022-11-11
Java模擬實現(xiàn)HTTP服務(wù)器項目實戰(zhàn)
本文主要介紹了Java模擬實現(xiàn)HTTP服務(wù)器項目實戰(zhàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-03-03
Java代理模式與動態(tài)代理之間的關(guān)系以及概念
代理模式是開發(fā)中常見的一種設(shè)計模式,使用代理模式可以很好的對程序進行橫向擴展。動態(tài)代理:代理類在程序運行時被創(chuàng)建的代理方式。關(guān)鍵在于動態(tài),程序具有了動態(tài)特性,可以在運行期間根據(jù)不同的目標對象生成動態(tài)代理對象2023-02-02
Java內(nèi)部類的實現(xiàn)原理與可能的內(nèi)存泄漏說明
這篇文章主要介紹了Java內(nèi)部類的實現(xiàn)原理與可能的內(nèi)存泄漏說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10
Spring IOC:CreateBean環(huán)節(jié)中的流程轉(zhuǎn)換
Spring IOC 體系是一個很值得深入和研究的結(jié)構(gòu) , 只有自己真正的讀一遍 , 才能有更好的理解.這篇文章主要說明一下 CreateBean 整個環(huán)節(jié)中的大流程轉(zhuǎn)換 , 便于查找問題的原因2021-05-05

