哈喽,大家好,我是了不起。
Mybatis插件Pagehelper 很多人都会使用吧,这里我们一起看看其原理以及日常使用注意事项。
如何使用PageHelper
PageHelper是Mybatis-Plus中的一个插件,主要用于实现数据库的分页查询功能。其核心原理是将传入的页码和条数赋值给一个Page对象,并保存到本地线程ThreadLocal中。接下来,PageHelper会进入Mybatis的拦截器环节,在拦截器中获取并处理刚才保存在ThreadLocal中的分页参数。这些分页参数会与原本的SQL语句和内部已经定义好的SQL进行拼接,从而完成带有分页处理的SQL语句的构建。
Pagehelper 有很多种使用方式,下面列出官方给出的几种使用方式。
1 |
|
PageHelper原理
其核心原理是将传入的页码和条数赋值给一个Page对象,并保存到本地线程ThreadLocal中。
下面以常见的使用方式看一下:
1 |
|
经过一些列的循环俄罗斯套娃调用之后,来到了这里:
1 |
|
- 重点在setLocalPage(page) 这个方法,将page对象放到了静态变量ThreadLocal中。
- 查询接口进来的时候, PageHelper中的Threadlocal对象中就保存的该线程对应的分页参数,在调用查询的时候就会拿出来使用。
PageHelper 中有写了一个 com.github.pagehelper.PageInterceptor , 这里是执行分页的地方。如果你想要些其他的拦截器,也可以自定义一个拦截器,在这里对sql进行处理。
- 在PageInterceptor 中有一个主要interceptor方法,在方法中需要判断是否需要分页,如果需要分页,则获取分页信息,查询数据量等。
- 接下来,PageHelper会进入Mybatis的拦截器环节,在拦截器中获取并处理刚才保存在ThreadLocal中的分页参数。这些分页参数会与原本的SQL语句和内部已经定义好的SQL进行拼接,从而完成带有分页处理的SQL语句的构建。需要注意一点的是在finally中remove掉 ThreadLocal对象中当前线程的page对象。
- 调用skip方法, 并获取分页参数 判断是否需要分页。
- 从静态ThreadLocal中获取page对象,
PageHelper在执行这一过程时,会判断SQL的类型,只有当该SQL是查询操作时,才会进入分页逻辑。并且,在进入分页逻辑处理后,PageHelper会通过反射获取该方法的参数,判断是否存在IPage对象(这是Mybatis-Plus中的另一个分页对象)的实现类。如果存在这样的实现类,那么也会进行相应的分页处理。
PageHelper注意事项
使用pagehelper进行分页的时候推荐使用 PageHelper.startPage(1, 10); 这种方式;
另外startPage语句最好紧挨着查询语句,避免中间抛出异常,没有办法清除ThreadLocal中当前线程的page对象。
下面看一下官方给出的不安全的用法 和推荐的例子:
不安全用法: 下面的方法如果不走查询的话,page对象就会保留在当前线程中,算是一个内存泄漏,如果下一个mybatis查询方法刚好是这个线程的时候,就会被动分页。
1 |
|
推荐用法,主要是紧挨着mybatis查询方法,查询结束后,page对象就被清理,对线程后续的运行不受影响。
1 |
|