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