Mybatis之PageHelper分页原理

PageHelper分页原理

PageHelper上文说过是一个Mybatis的分页插件,使用起来很简单,今天就来看看它背后的原理。

1、先看startPage方法,这个先生成一个Page对象,先从本地线程ThreadLocal中获取,当已经执行过orderBy的时候,取出来orderby设置到新Page对象中,最后放到本地线程中。

startPage方法

2,上面说的Page,来看看是什么结构?

Page是实现Closeable接口,并且继承了ArrayList,并且定义一些分页用到的成员变量,比如页码,每页大小,总数等。后面会说通过拦截的查询返回的对象就是Page对象。

Page类

3,PageInterceptor类中的intercept方法,如果需要分页,就是通过查询总数,并按分页查询数据。在Mybatis的系列文章中说个Invocation对象,这个类就三个变量,一个是目标对象,一个是目标方法,最后就是方法中的参数数组。我们所需要的就是从Invocation中取出来对应的变量做逻辑处理。

intercept方法

3.1、PageInterceptor中的Dialect变量,这个可以配置到拦截器的属性中,如果不配置默认就是PageHelper类。

3.2、PageHelper的setProperties方法中会创建PageParams和PageAutoDialect实例,PageAutoDialect如果没有配置方言,会自动检查,如果配置helperDialect,会用配置的方言。

3.3、在PageInterceptor类的intercept方法中会判断是否分页,调用dialect.skip方法,默认调用PageHelper的skip方法。

3.4、skip方法中,会从PageParams中获取Page,如果获取不到就返回true,否则返回false,

skip方法

3.5、pageParams.getPage方法,会从ThreadLocal获取Page,如果取不到,判断RowBound是否DEFAULT,如果不是会从rowbound获取offset和limit生成一个Page对象。

3.6、如果需要分页,先判断是否需要执行count,如果需要就会count方法,来看看怎么做count的?

生成一个新的MappedStatemen的ID,会判断是否当前的sql是否执行count,如果不是就从缓存查看,如果没有就新建一个MappedStatemen。最后执行count操作。

count方法

3.7、执行count操作的是ExecutorUtil工具类的executeAutoCount方法。这个方法主要就是调用方言获取count sql,最后调用executor执行这个sql获得count数。

executeAutoCount方法

3.8、回来再看PageInterceptor的intecepts方法,如果需要分页,会执行ExecutorUtil的pageQuery分页查询方法。首先处理参数对象,再次通过方言获取分页的sql,最后执行分页sql。

pageQuery分页方法

3.9、最后把分页的结果封装为一个Page对象,如果没反应就直接返回。上篇文章说过,Page是继承于ArrayList,可以说Page就是个集合类。

afterpage方法

分页的逻辑就大概说完了,其实里面有很多细节的处理。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200229A0FY9P00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券