PageHelper 插件源码分析
简介: 在开发中经常使用到pagehelper分页插件,一直也只是使用没有深入去分析,今天花时间来研究一下pagehelper的实现原理的,阅读优秀的开源项目总是能有很多收获。
一、源码的获取
我们在git仓库中搜索可以找到源码仓库,之后克隆到本地:
Mybatis_PageHelper: Mybatis分页插件
本身pagehelper只是mybatis的一个插件,源码不多,今天花一天时间应该能理解透。
二、pagehelper的使用方法
在源码中我们找到了md介绍文档,这里主要展示一下springboot 中使用pagehelper插件。
引入插件依赖:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>最新版本</version>
</dependency>
Spring Boot 引入 starter 后自动生效,对分页插件进行配置时,在 Spring Boot 对应的配置文件 application.[properties|yaml]
中配置:
properties:
pagehelper.propertyName=propertyValue pagehelper.reasonable=false pagehelper.defaultCount=true
yaml:
pagehelper:
propertyName: propertyValue
reasonable: false
defaultCount: true # 分页插件默认参数支持 default-count 形式,自定义扩展的参数,必须大小写一致
分页插件默认参数支持 default-count 形式,自定义扩展的参数,必须大小写一致。
使用实例:
//获取第1页,10条内容,默认查询总数count
PageHelper.startPage(1, 10);
//紧跟着的第一个select方法会被分页
List<User> list = userMapper.selectIf(1);
assertEquals(2, list.get(0).getId());
assertEquals(10, list.size());
//分页时,实际返回的结果list类型是Page<E>,如果想取出分页信息,需要强制转换为Page<E> assertEquals(182, ((Page) list).getTotal());
这些内容都是源码md文件里面有介绍的,这里主要摘抄的springboot部分,本篇也是着重介绍与springboot集成。
三、实现原理
程序中分页我们经常这样使用PageHelper.startPage(1, 10);接下来我们就以PageHelper类切入点进行源码分析:
从源码中我们可以看到首先调用了getPageFromObject方法从对象中获取到了分页参数,到这里实际上只获取到了Page对象,那具体的分页逻辑是在哪里实现的呢,我们带着疑问接着往下面分析。我们知道mybatis插件都是需要实现拦截器接口Interceptor,我们找到了pagehelper中的实现类PageInterceptor,在这个实现类中我们找到了分页处理的逻辑:
在pageQuery方法中我们看到了分页处理的逻辑:
这里我们可以看一下调用方言生成sql的方法:
//调用方言获取分页 sql String pageSql = dialect.getPageSql(ms, boundSql, parameter, rowBounds, pageKey);
可以看到方言对象是从dialectThreadLocal对象中获取的。看到这里我们可以去深入了解一下方言对象初始化的逻辑,首先我们关注一下方言基础类PageAutoDialect,在类中通过静态代码块来注册方言的,到这里我们想到了在项目配置文件中的配置:
pagehelper: #pagehelper分页插件 helperDialect: mysql
这里我们再次回到拦截方法intercept中,在该方法中调用了一个checkDialectExists()方法:
到这里我们继续跟进setProperties方法,继续跟进阅读我们看到了数据库方言指定的代码:
到此我们把pagehelper实现原理讲解完成了。
这里讲一个使用中常见的问题:pagehelper版本升级导致pageSize为0时无法查询全部数据。
版本升级之后我们需要配置一下
pageSizeZero: true
我们看一下相应的源码:
在方法里面我们可以看到pageSizeZero参数的使用情况:
四、总结
本文主要介绍了pagehelper的实现原理和源码阅读,要理解pagehelper首先要知道mybatis插件的实现原理,之后再到git仓库把源码clone下来跟着文章介绍的思路一步步分析跟进就好了,pagehelper插件本身只是分页的小插件源码不多阅读起来简单容易理解,有兴趣可以去了解一下。