MyBatis如何使用PageHelper實現(xiàn)分頁查詢
使用PageHelper實現(xiàn)分頁查詢
【實例】MyBatis使用PageHelper實現(xiàn)分頁查詢,并顯示分頁信息。執(zhí)行效果如下圖:
1、創(chuàng)建數(shù)據(jù)表
在MySQL數(shù)據(jù)庫中創(chuàng)建用戶信息表(tb_user),并添加數(shù)據(jù)。
-- 判斷數(shù)據(jù)表是否存在,存在則刪除 DROP TABLE IF EXISTS tb_user; -- 創(chuàng)建“用戶信息”數(shù)據(jù)表 CREATE TABLE IF NOT EXISTS tb_user ( user_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用戶編號', user_name VARCHAR(50) NOT NULL COMMENT '用戶姓名', province VARCHAR(50) NOT NULL COMMENT '省份', create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '注冊時間' ) COMMENT = '用戶信息表'; -- 添加數(shù)據(jù) INSERT INTO tb_user(user_name,province) VALUES ('pan_junbiao的博客_01','廣東省'),('pan_junbiao的博客_02','黑龍江省'),('pan_junbiao的博客_03','山東省'),('pan_junbiao的博客_04','安徽省'),('pan_junbiao的博客_05','黑龍江省'), ('pan_junbiao的博客_06','江蘇省'),('pan_junbiao的博客_07','黑龍江省'),('pan_junbiao的博客_08','廣東省'),('pan_junbiao的博客_09','陜西省'),('pan_junbiao的博客_10','廣東省'), ('pan_junbiao的博客_11','廣東省'),('pan_junbiao的博客_12','江蘇省'),('pan_junbiao的博客_13','陜西省'),('pan_junbiao的博客_14','安徽省'),('pan_junbiao的博客_15','山東省'), ('pan_junbiao的博客_16','陜西省'),('pan_junbiao的博客_17','安徽省'),('pan_junbiao的博客_18','江蘇省'),('pan_junbiao的博客_19','黑龍江省'),('pan_junbiao的博客_20','安徽省'), ('pan_junbiao的博客_21','江蘇省'),('pan_junbiao的博客_22','廣東省'),('pan_junbiao的博客_23','安徽省'),('pan_junbiao的博客_24','陜西省'),('pan_junbiao的博客_25','廣東省'), ('pan_junbiao的博客_26','廣東省'),('pan_junbiao的博客_27','安徽省'),('pan_junbiao的博客_28','山東省'),('pan_junbiao的博客_29','山東省'),('pan_junbiao的博客_30','黑龍江省'), ('pan_junbiao的博客_31','廣東省'),('pan_junbiao的博客_32','江蘇省'),('pan_junbiao的博客_33','陜西省'),('pan_junbiao的博客_34','安徽省'),('pan_junbiao的博客_35','山東省');
2、創(chuàng)建項目
(1)創(chuàng)建SpringBoot項目,項目結(jié)構(gòu)如下圖:
(2)添加pom.xml配置信息
在pom.xml配置文件中添加PageHelper、 MySQL的JDBC數(shù)據(jù)庫驅(qū)動。
<!-- SpringBoot/MyBatis使用PageHelper分頁控件 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.13</version> </dependency> <!-- MySQL的JDBC數(shù)據(jù)庫驅(qū)動 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.20</version> </dependency>
(3)配置相關(guān)信息
將默認的application.properties文件的后綴修改為“.yml”,即配置文件名稱為:application.yml,并配置以下信息:
spring: #DataSource數(shù)據(jù)源 datasource: url: jdbc:mysql://localhost:3306/db_admin?useSSL=false& username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver #MyBatis配置 mybatis: type-aliases-package: com.pjb.entity #別名定義 configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #指定 MyBatis 所用日志的具體實現(xiàn),未指定時將自動查找 map-underscore-to-camel-case: true #開啟自動駝峰命名規(guī)則(camel case)映射 lazy-loading-enabled: true #開啟延時加載開關(guān) aggressive-lazy-loading: false #將積極加載改為消極加載(即按需加載),默認值就是false lazy-load-trigger-methods: "" #阻擋不相干的操作觸發(fā),實現(xiàn)懶加載 cache-enabled: true #打開全局緩存開關(guān)(二級環(huán)境),默認值就是true #MyBatis使用pageHelper分頁 pagehelper: helper-dialect: mysql reasonable: true support-methods-arguments: true
配置說明:
helper-dialect:配置使用哪種數(shù)據(jù)庫語言,不配置的話pageHelper也會自動檢測。
reasonable:在啟用合理化時,如果 pageNum<1,則會查詢第一頁;如果 pageNum>pages,則會查詢最后一頁。
support-methods-arguments:支持通過Mapper接口參數(shù)來傳遞分頁參數(shù),默認值false,分頁插件會從查詢方法的參數(shù)值中,自動根據(jù)上面 params 配置的字段中取值,查找到合適的值時就會自動分頁。
2.1 創(chuàng)建實體類(Entity層)
在com.pjb.entity包中,創(chuàng)建UserInfo類(用戶信息實體類)。
package com.pjb.entity; import org.springframework.stereotype.Component; import java.util.Date; /** * 用戶信息實體類 * @author pan_junbiao **/ @Component public class UserInfo { private int userId; //用戶編號 private String userName; //用戶姓名 private String province; //省份 private Date createTime; //注冊時間 //省略getter與setter方法... @Override public String toString() { return "編號:" + this.getUserId() +" 姓名:" + this.getUserName() + " 省份:" + this.getProvince(); } }
在com.pjb.entity包中,創(chuàng)建UserSearchParam類(用戶查詢條件類)。
package com.pjb.entity; /** * 用戶查詢條件類 * @author pan_junbiao **/ public class UserSearchParam { private String userName; //用戶姓名 private String province; //省份 //省略getter與setter方法... }
2.2 數(shù)據(jù)庫映射層(Mapper層)
在com.pjb.mapper包中,創(chuàng)建UserMapper接口(用戶信息Mapper動態(tài)代理接口)。
package com.pjb.mapper; import com.pjb.entity.UserInfo; import com.pjb.entity.UserSearchParam; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.SelectProvider; import org.apache.ibatis.jdbc.SQL; import org.springframework.stereotype.Repository; import java.util.List; /** * 用戶信息Mapper動態(tài)代理接口 * @author pan_junbiao **/ @Mapper @Repository public interface UserMapper { /** * 查詢用戶列表 */ @SelectProvider(type = UserSqlBuilder.class, method = "searchUserList") public List<UserInfo> searchUserList(UserSearchParam param); //建議將SQL Builder以映射器接口內(nèi)部類的形式進行定義 public class UserSqlBuilder { public String searchUserList(UserSearchParam param) { return new SQL() { { SELECT("*"); FROM("tb_user"); WHERE("1 = 1"); if(param!=null) { //用戶姓名 if(param.getUserName()!=null && param.getUserName().length()>0) { WHERE("user_name like '%${userName}%'"); } //省份 if(param.getProvince()!=null && param.getProvince().length()>0) { WHERE("province = #{province}"); } } } }.toString(); } } }
3、運行測試
【運行】查詢第2頁的用戶數(shù)據(jù),每頁10條數(shù)據(jù),并根據(jù)創(chuàng)建時間排序。
@Autowired private UserMapper userMapper; /** * 分頁查詢用戶列表 * @author pan_junbiao */ @Test public void searchUserByParam() { int pageIndex = 2; ///獲取第2頁的數(shù)據(jù) int pageSize = 10; //每頁10條數(shù)據(jù) String orderBy = "create_time ASC"; //排序 //分頁信息 PageHelper.startPage(pageIndex, pageSize, orderBy); //查詢條件類 UserSearchParam userSearchParam = new UserSearchParam(); //userSearchParam.setUserName("pan_junbiao的博客"); //查詢條件1 //userSearchParam.setProvince("廣東省"); //查詢條件2 //執(zhí)行分頁查詢 PageInfo<UserInfo> userInfoPage = new PageInfo<UserInfo>(userMapper.searchUserList(userSearchParam)); //打印用戶列表 System.out.println("\n"); List<UserInfo> userInfoList = userInfoPage.getList(); userInfoList.stream().forEach(System.out::println); //打印分頁信息 System.out.println("當(dāng)前頁碼:第" + userInfoPage.getPageNum() + "頁"); System.out.println("分頁大?。好宽? + userInfoPage.getPageSize() + "條"); System.out.println("數(shù)據(jù)總數(shù):共" + userInfoPage.getTotal() + "條"); System.out.println("總頁數(shù):共" + userInfoPage.getPages() + "頁"); }
PageInfo類提供的相關(guān)屬性如下:
執(zhí)行結(jié)果:
MyBatis PageHelper的使用
1、引入pagehelper的jar包
如果是maven項目,pom里添加依賴:
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>4.1.4</version> </dependency>
2、在mybatis的配置文件中配置攔截(也可以在spring配置文件中配置)
小編在mybatis配置文件SqlMapConfig.xml中配置的
<?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> <plugins> <plugin interceptor="com.github.pagehelper.PageHelper"> <!--設(shè)置數(shù)據(jù)可類型Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六種數(shù)據(jù)庫--> <property name="dialect" value="mysql"/> </plugin> </plugins> </configuration>
在spring中配置如下:
<!--配置SqlSessionFactory對象 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath:mybatis-config.xml" /> <property name="typeAliasesPackage" value="com.aoChine.model.entity" /> <property name="mapperLocations" value="classpath:mapper/*.xml" /> <!-- 配置mybatis分頁插件PageHelper --> <property name="plugins"> <array> <bean class="com.github.pagehelper.PageInterceptor"> <property name="properties"> <!-- 什么都不配,使用默認的配置 --> <value></value> </property> </bean> </array> </property> </bean>
3、代碼中如何實現(xiàn)
Service中一個方法示例:
EasyUIDataGridResult是自己封裝的一個pojo,如下:
public class EasyUIDataGridResult implements Serializable { private long total; private List rows; public long getTotal() { return total; } public void setTotal(long total) { this.total = total; } public List getRows() { return rows; } public void setRows(List rows) { this.rows = rows; } }
如果不需要的話直接返回PageInfo就可以
4、注意事項 分頁不安全的情況
分頁不安全的情況
PageHelper 方法使用了靜態(tài)的 ThreadLocal 參數(shù),分頁參數(shù)和線程是綁定的。
只要你可以保證在 PageHelper 方法調(diào)用后緊跟 MyBatis 查詢方法,這就是安全的。因為 PageHelper 在 finally 代碼段中自動清除了 ThreadLocal 存儲的對象。
如下代碼是不安全的:
PageHelper.startPage(1, 10); List<Country> list; if(param1 != null){ list = countryMapper.selectIf(param1); } else { list = new ArrayList<Country>(); }
這種情況下由于 param1 存在 null 的情況,就會導(dǎo)致 PageHelper 生產(chǎn)了一個分頁參數(shù),但是沒有被消費,這個參數(shù)就會一直保留在這個線程上。當(dāng)這個線程再次被使用時,就可能導(dǎo)致不該分頁的方法去消費這個分頁參數(shù),這就產(chǎn)生了莫名其妙的分頁。
寫成如下便安全了:
List<Country> list; if(param1 != null){ PageHelper.startPage(1, 10); list = countryMapper.selectIf(param1); } else { list = new ArrayList<Country>(); }
另外也可以手動清理ThreadLocal存儲的分頁參數(shù):
PageHelper.clearPage();
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot 使用Spring Boot Actuator監(jiān)控應(yīng)用小結(jié)
本篇文章主要介紹了springboot 使用Spring Boot Actuator監(jiān)控應(yīng)用小結(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-02-02spring?data?jpa如何使用自定義repository實現(xiàn)類
這篇文章主要介紹了spring?data?jpa如何使用自定義repository實現(xiàn)類,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11mybatis那些約定的配置你真的都了解嗎(經(jīng)驗總結(jié))
mybatsi中Mapper和xml文件之間有很多約定俗稱的規(guī)則,比如名稱匹配,包掃描,別名等,這些規(guī)則是什么。如果想更加靈活,該如何配置呢?今天就給大家講一下如何配置mybatsi的xml文件2021-06-06Java 實戰(zhàn)項目錘煉之IT設(shè)備固定資產(chǎn)管理系統(tǒng)的實現(xiàn)流程
讀萬卷書不如行萬里路,只學(xué)書上的理論是遠遠不夠的,只有在實戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Java+SSM+jsp+mysql+maven實現(xiàn)一個IT設(shè)備固定資產(chǎn)管理系統(tǒng),大家可以在過程中查缺補漏,提升水平2021-11-11