SpringBoot3整合pageHelper實現(xiàn)分頁功能
1、介紹:
PageHelper是一個開源的Java分頁插件,它提供了方便的分頁查詢功能,適用于大多數(shù)基于Java的持久層框架(如MyBatis、Hibernate等)。
官網(wǎng):MyBatis 分頁插件 PageHelper
在一個程序中難免會使用到查詢操作,在查詢操作中如果數(shù)據(jù)量太大則需要進(jìn)行分頁查詢,分頁操作的實現(xiàn)方法有很多,比如:在 mybatis 中 xml 文件中通過 limit 關(guān)鍵字進(jìn)行分頁查詢,該插件就是為了簡化在 xml 中進(jìn)行分頁操作的工具;好比在 Mybatis-Plus 中也對分頁操作進(jìn)行了封裝,通過調(diào)用 selectPage() 方法就可以實現(xiàn)分頁操作。
在 sql 中使用 limit 進(jìn)行分頁查詢
SELECT * FROM user LIMIT 10, 10
- offset 是相對于首行的偏移量(首行是 0),rows 是返回條數(shù)
- mapper 中可以傳變量,即在實際使用的時候 offset 與 rows 可以用變量替代
我們當(dāng)然可以在sql中進(jìn)行分頁,但是為了簡化代碼。
我們還是會使用一些插件來幫我們更好的進(jìn)行分頁操作。如:在項目中我們執(zhí)行一個分頁查詢時,很多時候還需要知道該查詢的其他信息,比如:總數(shù)、每頁數(shù)量、當(dāng)前頁數(shù)、是否有上一頁或者是否有下一頁等等,這些信息如果每次都自己寫的話就會太繁瑣冗余了,而 PageHelper 插件能夠幫助我們更加方便地獲取這些信息,大大方便了我們的開發(fā)效率。
我始終認(rèn)為官網(wǎng)才是一個技術(shù)最權(quán)威、最公正的對照。如果你在使用某個相應(yīng)的技術(shù)中出現(xiàn)了錯誤,那么一定要先去官網(wǎng)上查找原因?,F(xiàn)在的web開發(fā)使用到的框架大多為spring boot,所以本篇文章只是教會你如何快速的在spring boot項目中使用pageHelper分頁插件,并介紹一些一些常用的方法,如果你有其他的疑問,可以在官網(wǎng)中查找。
2、新建spring boot項目,并導(dǎo)入依賴
引入pageHelper的坐標(biāo)(我引入的使pageHelper整合spring boot的依賴)
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.4.7</version> </dependency>
在yml配置文件中對pageHelper進(jìn)行一些配置,能更好的使用這個插件;
# PageHelper 分頁插件配置 pagehelper: helper-dialect: mysql reasonable: true support-methods-arguments: true params: count=countsql
helper-dialect:指定數(shù)據(jù)庫,不指定的話會默認(rèn)自動檢測數(shù)據(jù)庫類型
reasonable:是否啟動分頁合理化。如果啟用,當(dāng) pagenum < 1 時,會自動查詢第一頁的數(shù)據(jù),當(dāng) pagenum > pges 時,自動查詢最后一頁數(shù)據(jù);不啟用的,以上兩種情況都會返回空數(shù)據(jù),如果啟用則 pageHelper可以自動攔截請求參數(shù)中的 pageNum,pageSize參數(shù),否則需要使用 PageHelper.startPage(pageNum,pageSize) 方法調(diào)用。
support-methods-arguments:默認(rèn)為 false,分頁插件會從查詢方法的參數(shù)值中,自動根據(jù)上面 params 配置的字段中取值,查找到合適的值時就會自動分頁。
params:用于從對象中根據(jù)屬性名取值,可以配置 pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默認(rèn)值,默認(rèn)值為 pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero
創(chuàng)建一個mapper接口:
public interface UsersMapper { //查詢所有 List<Users> getAll(); }
mybatis的配置文件:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <!-- 設(shè)置駝峰標(biāo)識 --> <setting name="mapUnderscoreToCamelCase" value="true"/> <!-- 打印SQL語句 --> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> <!-- <plugins>--> <!-- <!– 分頁插件 –>--> <!-- <plugin interceptor="com.github.pagehelper.PageInterceptor"/>--> <!-- </plugins>--> <mappers> <package name="com.zq.pagehelpdemo.mapper"/> </mappers> </configuration>
我們已經(jīng)引入了pagehelper-spring-boot-starter的依賴。所以pageHelper插件在項目啟動時會自動注入到容器中。如果你的項目不是spring boot項目或者引入的依賴不是pageHelper整合了spring boot的依賴,那么就需要在mybatis的配置文件中引入pageHelper的插件。
在項目中使用pageHelper實現(xiàn)分頁:
@Override public List<Users> getPage(int page, int size) { //獲取第page頁,size條內(nèi)容,默認(rèn)查詢總數(shù)count PageHelper.startPage(page,size); //分頁時,實際返回的結(jié)果list類型是Page<E>,如果想取出分頁信息,需要強(qiáng)制轉(zhuǎn)換為Page<E>, return getAll(); }
xml中的sql語句:
<select id="getAll" resultType="com.zq.pagehelpdemo.entity.Users"> select * from users </select>
運(yùn)行結(jié)果:
在啟動項目時看到這個圖標(biāo)就說明pageHelper注入成功了:
sql語句:
可以看到先執(zhí)行了一個查詢所有記錄的語句,然后執(zhí)行了我們在xml中寫的查詢語句,在查詢語句的最后加上了LIMIT字段。
其實這些sql都不是我們寫的,我們只不過是寫了一個
PageHelper.startPage(page,size);
這一條語句就會幫助我們自動生成分頁語句;
注意PageHelper.startPage方法使用也有限制:
PageHelper.startPage方法重要提示
只有緊跟在PageHelper.startPage方法后的第一個Mybatis的查詢(Select)方法會被分頁。(PageHelper 啟動了一個新的線程)
還有在使用pageHelper插件時的幾個重要提示:
請不要配置多個分頁插件
請不要在系統(tǒng)中配置多個分頁插件(使用Spring時,mybatis-config.xml和Spring<bean>配置方式,請選擇其中一種,不要同時配置多個分頁插件)!
分頁插件不支持帶有for update語句的分頁
對于帶有for update的sql,會拋出運(yùn)行時異常,對于這樣的sql建議手動分頁,畢竟這樣的sql需要重視。
分頁插件不支持嵌套結(jié)果映射
由于嵌套結(jié)果方式會導(dǎo)致結(jié)果集被折疊,因此分頁查詢的結(jié)果在折疊后總數(shù)會減少,所以無法保證分頁結(jié)果數(shù)量正確。
pageHelper使用時,要注意線程的安全性,避免重復(fù)調(diào)用分頁參數(shù):
PageHelper 方法使用了靜態(tài)的 ThreadLocal 參數(shù),分頁參數(shù)和線程是綁定的。
只要你可以保證在 PageHelper 方法調(diào)用后緊跟 MyBatis 查詢方法,這就是安全的。因為 PageHelper 在 finally 代碼段中自動清除了 ThreadLocal 存儲的對象。
如果代碼在進(jìn)入 Executor 前發(fā)生異常,就會導(dǎo)致線程不可用,這屬于人為的 Bug(例如接口方法和 XML 中的不匹配,導(dǎo)致找不到 MappedStatement 時), 這種情況由于線程不可用,也不會導(dǎo)致 ThreadLocal 參數(shù)被錯誤的使用。
下面有一段代碼示例:
public List<Users> getPages(int page, int size) { // 調(diào)用PageHelper的靜態(tài)方法startPage PageHelper.startPage(page, size); List<Users> usersList=new ArrayList<>(); if (false) { System.out.println("調(diào)用了查詢方法"); usersList = usersMapper.getAll(); } else { System.out.println("沒有調(diào)用了查詢方法"); } return usersList; }
在這個方法中,我調(diào)用了PageHelper.startPage方法,這時就會導(dǎo)致PageHelper生產(chǎn)了一個分頁參數(shù),但是沒有被消費,這個參數(shù)就會一直保留在這個線程上。當(dāng)這個線程再次被使用時,就可能導(dǎo)致可能不該分頁的方法去消費這個分頁參數(shù),這就產(chǎn)生了莫名其妙的分頁。
所以我們一定要保證PageHelper.startPage方法后面跟了一個查詢方法。最好的情況就是將這兩條語句就放在一起,前后挨著。
當(dāng)然,使用 PageHelper.startPage進(jìn)行分頁時基本的用法。如果你不僅僅想要得到分頁內(nèi)容,還要得到一些分頁具體的值,如查詢的總記錄數(shù)等等??梢允褂肞ageInfo,在這個對象中pageHelper封裝了我們對于分頁來說的所有參數(shù),可以滿足我們對于分頁操作的所有需求。
public class PageInfo<T> extends PageSerializable<T> { public static final int DEFAULT_NAVIGATE_PAGES = 8; // 當(dāng)前頁 private int pageNum; // 每頁的數(shù)量 private int pageSize; // 當(dāng)前頁的數(shù)量 private int size; // 下面兩個不常用 // 在頁面中“顯示 startRow” 到 endRow 共 size條數(shù)據(jù) // 當(dāng)前頁面中第一個元素的在數(shù)據(jù)庫中的行號 private long startRow; // 當(dāng)前頁面最后一個元素在數(shù)據(jù)庫中的行號 private long endRow; // 總頁數(shù) private int pages; // 前一頁 private int prePage; // 下一頁 private int nextPage; // 是否為第一頁 private boolean isFirstPage; // 是否為最后一頁 private boolean isLastPage; // 是否有前一頁 private boolean hasPreviousPage; // 是否有下一頁 private boolean hasNextPage; // 導(dǎo)航頁碼數(shù) private int navigatePages; // 所有導(dǎo)航頁號 private int[] navigatepageNums; // 導(dǎo)航條上的第一頁 private int navigateFirstPage; // 導(dǎo)航條上的最后一頁 private int navigateLastPage; ...... }
在代碼中使用PageInfo:
(在創(chuàng)建PageInfo時,指定泛型。并將查詢到的結(jié)果作為入?yún)鬟f)
@Override public PageInfo<Users> getPageInfo(int page, int size) { PageHelper.startPage(page,size); List<Users> usersList = getAll(); // 將查詢到的數(shù)據(jù)封裝到PageInfo中 PageInfo<Users> pageInfo=new PageInfo<>(usersList); return pageInfo; }
運(yùn)行結(jié)果為:
可以很清晰的看到輸出了PageInfo的所有屬性,我們可以根據(jù)我們的需求動態(tài)的獲取用到的參數(shù)。
以上就是SpringBoot3整合pageHelper實現(xiàn)分頁功能的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot3 pageHelper分頁的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
tk.mybatis如何擴(kuò)展自己的通用mapper
這篇文章主要介紹了tk.mybatis如何擴(kuò)展自己的通用mapper操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06Spring?boot?Thymeleaf配置國際化頁面詳解
這篇文章主要給大家介紹了關(guān)于Spring?Boot?Thymeleaf實現(xiàn)國際化的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Spring?Boot具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07深入分析:用1K內(nèi)存實現(xiàn)高效I/O的RandomAccessFile類的詳解
本篇文章是對用1K內(nèi)存實現(xiàn)高效I/O的RandomAccessFile類的詳細(xì)分析介紹,需要的朋友參考下2013-05-05SpringBoot2.x中management.security.enabled=false無效的解決
這篇文章主要介紹了SpringBoot2.x中management.security.enabled=false無效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07