pagehelper使用笔记及原理

1-引入分页插件

这里使用maven的方式

<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>最新版本</version>
</dependency>

 

2-配置拦截器插件PageInterceptor

新版拦截器是com.github.pagehelper.PageInterceptor

可以在MyBatis.xml中配置拦截器插件,也可以在Spring配置中配置

  • MyBatis中配置方式

<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 使用下面的方式配置参数,参数可以去官网查询 -->
<property name="param1" value="value1"/>
</plugin>
</plugins>

  • Spring配置方式

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注意其他配置 -->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<!--使用下面的方式配置参数,一行配置一个 -->
<value>
params=value1
</value>
</property>
</bean>
</array>
</property>
</bean>

  • 我们的项目采用的是封装MySql配置,所以要在定义SqlSessionFactory的时候进行拦截插件的配置

Interceptor[] interceptors = {new PageInterceptor()};
factoryBean.setPlugins(interceptors);

 

3-代码中的使用

// 第一种,RowBounds方式的调用 ---------------------------------------------------
List<Country> list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(0, 10));

// 第二种,Mapper接口方式的调用,推荐这种使用方式。---------------------------
PageHelper.startPage(1, 10);
List<Country> list = countryMapper.selectIf(1);

// 第三种,Mapper接口方式的调用,推荐这种使用方式。---------------------------
PageHelper.offsetPage(1, 10);
List<Country> list = countryMapper.selectIf(1);

// 第四种,参数方法调用---------------------------------------------------------------
//存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数
public interface CountryMapper {
List<Country> selectByPageNumSize(
@Param("user") User user,
@Param("pageNum") int pageNum,
@Param("pageSize") int pageSize);
}
// 配置supportMethodsArguments=true
// 在代码中直接调用:
List<Country> list = countryMapper.selectByPageNumSize(user, 1, 10);

// 第五种,参数对象-------------------------------------------------------------------
//如果 pageNum 和 pageSize 存在于 User 对象中,只要参数有值,也会被分页
//有如下 User 对象
public class User {
// 其他fields
// 下面两个参数名和 params 配置的名字一致
private Integer pageNum;
private Integer pageSize;
}
// 存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数
public interface CountryMapper {
List<Country> selectByPageNumSize(User user);
}
// 当 user 中的 pageNum!= null && pageSize!= null 时,会自动分页
List<Country> list = countryMapper.selectByPageNumSize(user);

// 第六种,ISelect 接口方式-----------------------------------------------------------
// jdk6,7用法,创建接口
Page<Country> page = PageHelper.startPage(1, 10).doSelectPage(new ISelect() {
@Override
public void doSelect() {
countryMapper.selectGroupBy();
}
});
// jdk8 lambda用法
Page<Country> page = PageHelper.startPage(1, 10).doSelectPage(()-> countryMapper.selectGroupBy());

//也可以直接返回PageInfo,注意doSelectPageInfo方法和doSelectPage
pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(new ISelect() {
@Override
public void doSelect() {
countryMapper.selectGroupBy();
}
});
// 对应的lambda用法
pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(() -> countryMapper.selectGroupBy());

// count查询,返回一个查询语句的count数
long total = PageHelper.count(new ISelect() {
@Override
public void doSelect() {
countryMapper.selectLike(country);
}
});
// lambda
total = PageHelper.count(()->countryMapper.selectLike(country));

 

4-原理和注意事项

PageHelper.offsetPage(PAGE_NUM, PAGE_SIZE)实际做的事情是在 ThreadLocal中设置了分页参数,之后在查询执行的时候,获取当线程中的分页参数,执行查询的时候通过拦截器在sql语句中添加分页参数,之后实现分页查询,查询结束后在 finally 语句中清除ThreadLocal中的查询参数

PageInterceptor

最核心的逻辑在 PageInterceptor 中,PageInterceptor 是一个拦截器。

Mybatis四个拦截机会

  1. Executor
  2. ParameterHandler
  3. ResultSetHandler
  4. StatementHandler

分页插件拦截的是 Executor ,也就是在sql执行的时候

 

Mybatis插件加载流程

读取配置文件到Congiguration实例
生成全局公用的 SqlSessionTemplate以SqlSessionFactory实例
获取接口的代理对象MapperProxy
执行增删改查方法
那么在configuration.newExecutor()方法会加载拦截链,也就是PageInterceptor。

注意

PageHelper方法使用了静态的ThreadLocal参数,分页参数和线程是绑定的。

只要你可以保证在PageHelper方法调用后紧跟 MyBatis 查询方法,这就是安全的。因为PageHelper在finally代码段中自动清除了ThreadLocal存储的对象。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值