阅读 123

pageHelper-v4.2源码阅读-分页是怎么实现运行的?

pageHelper的分页是怎么实现运行的?

下载pageHelper源码,使用pageHelper的官方demo进行Debug试验。

源码地址:

[源码地址]  gitee.com/free/Mybati…

本文使用分支: 4.2

PageHelper.startPage(2, 10, "id desc");复制代码

image-20220125150525933

点进第一个断点

PageHelper.startPage

image-20220125142456686

<E> :Element,常表示List<E>,使用泛型的方式是得代码得到复用,达到允许放入不同List的功能。

SqlUtil.getLocalPage:

SqlUtil是BaseSqlUtil的子类,BaseSqlUtil中定义了一个TreadLocal类型的LOCAL_PAGE

protected static final ThreadLocal<Page> LOCAL_PAGE = new ThreadLocal<Page>();复制代码

TreadLocal是一个线程内部存储类,可以在指定线程内存储数据副本,数据存储后,只有特定线程可以得到存储数据。

ThreadLocal内部定义了一个静态成员类ThreadLocalMap,其存在的目的就是为了外围类提供数据存储,因此ThreadLocal类似于一个map(),key就是当前的线程,value就是需要存储的对象,可以通过get/set方法得到当前线程存储的数据(value)。

ThreadLoacl.get()

获取当前线程副本中的值。

image-20220125144633160

ThreadLocal.set()

给当前线程副本的value赋值

image-20220125144757504

自此,PageHelper.startPage(2,10)已走完,下面开始执行MyBatis的查询语句。


List<Country> list = countryMapper.selectAll();复制代码

MyBatis拦截器

在MyBatis将Java代码转化为SQL之前,会先去BaseSqlUtil中的LOCAL_PAGE变量中获取线程中的分页数据。

image-20220125151828179

而后会走到SqlUtil的doIntercept拦截。

image-20220125151954438

SqlUtil的拦截似乎跟MyBatis并无关系,可实际上在进行拦截时,是走的MyBatis的拦截方法。

image-20220125152733081

原因:

PageHelper类继承自BasePageHelper实现了MyBatis的Interceptor接口使用了MyBatis的Intercepts注解实现拦截。

image-20220125153040860

拦截器的实现在SqlUtil中。

image-20220208092439530

在boundSql这个对象中,是本次根据参数编译出需要执行的SQL语句。

image-20220208093141666

对比调用xml中的SQL:

image-20220208093237819

不能说是一模一样,可以说是完全一致。


拦截器的翻译

编写的xml文件会在本步骤被编译成SQL语句,在数据库中执行。

在执行查询SQL之前,源码中会通过runtimeDialect调用getCountSql方法,先对查询语句做一遍count,如果当然,在查询时,也可以在代码中设置不进行count。

如果统计数大于0,则带着分页参数执行SQL语句,将结果存放到LOCAL_PAGE中,返回查询结果。

image-20220208100053007

返回结果后,关闭本次sqlSession。


来自官方的使用提示:

只有紧跟在PageHelper.startPage方法后的第一个Mybatis的查询(Select) 方法会被分页。

\


作者:FirstMrRight
链接:https://juejin.cn/post/7062155783311458341


文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐