MyBatis如何使用PageHelper實(shí)現(xiàn)分頁(yè)查詢
使用PageHelper實(shí)現(xiàn)分頁(yè)查詢
【實(shí)例】MyBatis使用PageHelper實(shí)現(xiàn)分頁(yè)查詢,并顯示分頁(yè)信息。執(zhí)行效果如下圖:

1、創(chuàng)建數(shù)據(jù)表
在MySQL數(shù)據(jù)庫(kù)中創(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 '用戶編號(hào)',
user_name VARCHAR(50) NOT NULL COMMENT '用戶姓名',
province VARCHAR(50) NOT NULL COMMENT '省份',
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT '注冊(cè)時(shí)間'
) 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)建項(xiàng)目
(1)創(chuàng)建SpringBoot項(xiàng)目,項(xiàng)目結(jié)構(gòu)如下圖:

(2)添加pom.xml配置信息
在pom.xml配置文件中添加PageHelper、 MySQL的JDBC數(shù)據(jù)庫(kù)驅(qū)動(dòng)。
<!-- SpringBoot/MyBatis使用PageHelper分頁(yè)控件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.13</version>
</dependency>
<!-- MySQL的JDBC數(shù)據(jù)庫(kù)驅(qū)動(dòng) -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
(3)配置相關(guān)信息
將默認(rè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 所用日志的具體實(shí)現(xiàn),未指定時(shí)將自動(dòng)查找
map-underscore-to-camel-case: true #開啟自動(dòng)駝峰命名規(guī)則(camel case)映射
lazy-loading-enabled: true #開啟延時(shí)加載開關(guān)
aggressive-lazy-loading: false #將積極加載改為消極加載(即按需加載),默認(rèn)值就是false
lazy-load-trigger-methods: "" #阻擋不相干的操作觸發(fā),實(shí)現(xiàn)懶加載
cache-enabled: true #打開全局緩存開關(guān)(二級(jí)環(huán)境),默認(rèn)值就是true
#MyBatis使用pageHelper分頁(yè)
pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
配置說(shuō)明:
helper-dialect:配置使用哪種數(shù)據(jù)庫(kù)語(yǔ)言,不配置的話pageHelper也會(huì)自動(dòng)檢測(cè)。
reasonable:在啟用合理化時(shí),如果 pageNum<1,則會(huì)查詢第一頁(yè);如果 pageNum>pages,則會(huì)查詢最后一頁(yè)。
support-methods-arguments:支持通過(guò)Mapper接口參數(shù)來(lái)傳遞分頁(yè)參數(shù),默認(rèn)值false,分頁(yè)插件會(huì)從查詢方法的參數(shù)值中,自動(dòng)根據(jù)上面 params 配置的字段中取值,查找到合適的值時(shí)就會(huì)自動(dòng)分頁(yè)。
2.1 創(chuàng)建實(shí)體類(Entity層)
在com.pjb.entity包中,創(chuàng)建UserInfo類(用戶信息實(shí)體類)。
package com.pjb.entity;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
* 用戶信息實(shí)體類
* @author pan_junbiao
**/
@Component
public class UserInfo
{
private int userId; //用戶編號(hào)
private String userName; //用戶姓名
private String province; //省份
private Date createTime; //注冊(cè)時(shí)間
//省略getter與setter方法...
@Override
public String toString()
{
return "編號(hào):" + 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ù)庫(kù)映射層(Mapper層)
在com.pjb.mapper包中,創(chuàng)建UserMapper接口(用戶信息Mapper動(dòng)態(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動(dòng)態(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)部類的形式進(jìn)行定義
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、運(yùn)行測(cè)試
【運(yùn)行】查詢第2頁(yè)的用戶數(shù)據(jù),每頁(yè)10條數(shù)據(jù),并根據(jù)創(chuàng)建時(shí)間排序。
@Autowired
private UserMapper userMapper;
/**
* 分頁(yè)查詢用戶列表
* @author pan_junbiao
*/
@Test
public void searchUserByParam()
{
int pageIndex = 2; ///獲取第2頁(yè)的數(shù)據(jù)
int pageSize = 10; //每頁(yè)10條數(shù)據(jù)
String orderBy = "create_time ASC"; //排序
//分頁(yè)信息
PageHelper.startPage(pageIndex, pageSize, orderBy);
//查詢條件類
UserSearchParam userSearchParam = new UserSearchParam();
//userSearchParam.setUserName("pan_junbiao的博客"); //查詢條件1
//userSearchParam.setProvince("廣東省"); //查詢條件2
//執(zhí)行分頁(yè)查詢
PageInfo<UserInfo> userInfoPage = new PageInfo<UserInfo>(userMapper.searchUserList(userSearchParam));
//打印用戶列表
System.out.println("\n");
List<UserInfo> userInfoList = userInfoPage.getList();
userInfoList.stream().forEach(System.out::println);
//打印分頁(yè)信息
System.out.println("當(dāng)前頁(yè)碼:第" + userInfoPage.getPageNum() + "頁(yè)");
System.out.println("分頁(yè)大小:每頁(yè)" + userInfoPage.getPageSize() + "條");
System.out.println("數(shù)據(jù)總數(shù):共" + userInfoPage.getTotal() + "條");
System.out.println("總頁(yè)數(shù):共" + userInfoPage.getPages() + "頁(yè)");
}
PageInfo類提供的相關(guān)屬性如下:

執(zhí)行結(jié)果:

MyBatis PageHelper的使用
1、引入pagehelper的jar包
如果是maven項(xiàng)目,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ù)庫(kù)-->
<property name="dialect" value="mysql"/>
</plugin>
</plugins>
</configuration>
在spring中配置如下:
<!--配置SqlSessionFactory對(duì)象 -->
<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分頁(yè)插件PageHelper -->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<!-- 什么都不配,使用默認(rèn)的配置 -->
<value></value>
</property>
</bean>
</array>
</property>
</bean>
3、代碼中如何實(shí)現(xiàn)
Service中一個(gè)方法示例:

EasyUIDataGridResult是自己封裝的一個(gè)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、注意事項(xiàng) 分頁(yè)不安全的情況
分頁(yè)不安全的情況
PageHelper 方法使用了靜態(tài)的 ThreadLocal 參數(shù),分頁(yè)參數(shù)和線程是綁定的。
只要你可以保證在 PageHelper 方法調(diào)用后緊跟 MyBatis 查詢方法,這就是安全的。因?yàn)?PageHelper 在 finally 代碼段中自動(dòng)清除了 ThreadLocal 存儲(chǔ)的對(duì)象。
如下代碼是不安全的:
PageHelper.startPage(1, 10);
List<Country> list;
if(param1 != null){
list = countryMapper.selectIf(param1);
} else {
list = new ArrayList<Country>();
}
這種情況下由于 param1 存在 null 的情況,就會(huì)導(dǎo)致 PageHelper 生產(chǎn)了一個(gè)分頁(yè)參數(shù),但是沒(méi)有被消費(fèi),這個(gè)參數(shù)就會(huì)一直保留在這個(gè)線程上。當(dāng)這個(gè)線程再次被使用時(shí),就可能導(dǎo)致不該分頁(yè)的方法去消費(fèi)這個(gè)分頁(yè)參數(shù),這就產(chǎn)生了莫名其妙的分頁(yè)。
寫成如下便安全了:
List<Country> list;
if(param1 != null){
PageHelper.startPage(1, 10);
list = countryMapper.selectIf(param1);
} else {
list = new ArrayList<Country>();
}
另外也可以手動(dòng)清理ThreadLocal存儲(chǔ)的分頁(yè)參數(shù):
PageHelper.clearPage();
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- 解決mybatis分頁(yè)插件PageHelper導(dǎo)致自定義攔截器失效
- Mybatis-Plus或PageHelper多表分頁(yè)查詢總條數(shù)不對(duì)問(wèn)題的解決方法
- Mybatis分頁(yè)插件PageHelper手寫實(shí)現(xiàn)示例
- springboot?+mybatis?使用PageHelper實(shí)現(xiàn)分頁(yè)并帶條件模糊查詢功能
- Mybatis分頁(yè)查詢的實(shí)現(xiàn)(Rowbounds和PageHelper)
- Mybatis邏輯分頁(yè)與物理分頁(yè)P(yáng)ageHelper使用解析
相關(guān)文章
Spring探秘之如何妙用BeanPostProcessor
BeanPostProcessor也稱為Bean后置處理器,它是Spring中定義的接口,在Spring容器的創(chuàng)建過(guò)程中會(huì)回調(diào)BeanPostProcessor中定義的兩個(gè)方法,這篇文章主要給大家介紹了關(guān)于Spring探秘之如何妙用BeanPostProcessor的相關(guān)資料,需要的朋友可以參考下2022-01-01
Tree組件實(shí)現(xiàn)支持50W數(shù)據(jù)方法剖析
這篇文章主要為大家介紹了Tree組件實(shí)現(xiàn)支持50W數(shù)據(jù)的方法剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
springboot3+r2dbc響應(yīng)式編程實(shí)踐
本文主要介紹了springboot3+r2dbc響應(yīng)式編程實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02
Java基于阻塞隊(duì)列實(shí)現(xiàn)生產(chǎn)者消費(fèi)者模型示例詳解
這篇文章主要介紹了Java基于阻塞隊(duì)列實(shí)現(xiàn)生產(chǎn)者消費(fèi)者模型,阻塞隊(duì)列的特點(diǎn)就是阻塞兩個(gè)字,阻塞功能使得生產(chǎn)者和消費(fèi)者兩端的能力得以平衡,當(dāng)有任何一端速度過(guò)快時(shí),阻塞隊(duì)列便會(huì)把過(guò)快的速度降下來(lái),感興趣的朋友可以參考下2023-12-12
java數(shù)據(jù)結(jié)構(gòu)與算法之快速排序詳解
這篇文章主要介紹了java數(shù)據(jù)結(jié)構(gòu)與算法之快速排序,結(jié)合實(shí)例形式詳細(xì)分析了快速排序的原理、實(shí)現(xiàn)步驟、相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下2017-05-05
自己動(dòng)手寫的mybatis分頁(yè)插件(極其簡(jiǎn)單好用)
最近做了個(gè)項(xiàng)目,需要用到mybatis分頁(yè)功能,網(wǎng)上找了很多插件,都不太合適,于是就自己動(dòng)手寫了個(gè)mybatis分頁(yè)插件功能,非常不錯(cuò),代碼簡(jiǎn)單易懂,需要的朋友參考下吧2016-11-11
spring多數(shù)據(jù)源配置實(shí)現(xiàn)方法實(shí)例分析
這篇文章主要介紹了spring多數(shù)據(jù)源配置實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了spring多數(shù)據(jù)源配置相關(guān)操作技巧與使用注意事項(xiàng),需要的朋友可以參考下2019-12-12
教你快速學(xué)會(huì)JPA中所有findBy語(yǔ)法規(guī)則
這篇文章主要介紹了教你快速學(xué)會(huì)JPA中所有findBy語(yǔ)法規(guī)則,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11

