https://ost.51cto.com/posts/18522
简单来说就是通过 MyBatis 的拦截器和插件实现的,PageHelper 实现了 Interceptor 拦截器接口,并拦截 Executor 的 query 方法,在执行前PageHelper会在原始 SQL 前拼装分页相关的SQL。
用法
此时 commentAnalyses 为 Page 对象(PageHelper 插件包内定义的)
而 Page 对象继承自 JDK 中的 ArrayList,扩展并封装了一些 page 相关的字段,如页码,每页大小,总记录数,总页数等。
原理
我们就加了一行,它是如何帮助我们实现分页的呢?请往下看。
PageHelper.startPage 做了什么
我们看这一行 PageHelper.startPage(pageIndex, pageSize);做了什么。这个类中重载了好多个 startPage 方法,最终调用到如下的一个方法
可以看到该方法将分页信息作为构造器参数实例化 Page 对象,调用 SqlUtil.getLocalPage()获取一个旧的 Page 对象,最后调用 SqlUtil.setLocalPage(page);把新创建的 Page 对象 set 进去。
我们看看这两个方法做了什么。如下,很简单,从 ThreadLocal 中获取 Page 对象,将 Page 对象 set 到 ThreadLocal 中。知道 ThreadLocal 作用的不用多说,不知道的可以理解为用于保存本地变量,并与线程绑定。
看到这我们暂且将这一行的作用记为,创建并保存 Page 对象(分页信息)到 ThreadLocal 中。
Page 分页信息在哪使用
那么既然保存了,就有使用的地方。
我通过代码追踪的方式定位到被调用的地方,通过回溯,发现是从这个类 com.github.pagehelper.dialect.AbstractDialect 发起调用的