【PageHelper篇】深入源码分析PageHelper何时执行select count(0) from xxx查询?(结论+源码Debug分析)

pageHelper的原理

pageHelper会使用ThreadLocal获取到同一线程中的变量信息,各个线程之间的Threadlocal不会相互干扰,也就是Thread1中的ThreadLocal1之后获取到Tread1中的变量的信息,不会获取到Thread2中的信息

所以在多线程环境下,各个Threadlocal之间相互隔离,可以实现,不同thread使用不同的数据源或不同的Thread中执行不同的SQL语句。

所以,PageHelper利用这一点通过拦截器获取到同一线程中的预编译好的SQL语句之后将SQL语句包装成具有分页功能的SQL语句,并将其再次赋值给下一步操作,所以实际执行的SQL语句就是有了分页功能的SQL语句。

那么好!

PageHelper.startPage会返回一个page对象,这个对象在查询结果出来后会把页数,记录总数给page对象,你用page.getPages()和getTotal()获取页数和记录总数。

关于PageHelper何时执行select count(0)查询?(结论+源码Debug分析)

这里提到PageHelper是通过拦截mybatis执行sql并在原始SQL 拼接了" limit ?,?"来查询分页数据,那记录总数是在什么时候查询的呢。

接着我就对select count(*) from xxx这个PageHelper自动给我们查询操作进行了源码debug,才比较清楚这个自动执行查询总记录数的执行流程。


结论 +源码debug

先说结论

总结:当我们要使用开启分页查询的时候时,并不是startPage方法中执行的,如下:

在这里插入图片描述
真正的执行时机是在对应service中majorMapper执行其代理类的过程中进行的:

在这里插入图片描述
在mapper代理类中,会去执行PageHelper拦截器,由于我们之前开启了StartPage(),所以会先去解析我们待查询的sql语句,该sql语句如下所示:

select major_id, major_name
 FROM zf_major
 LIMIT 5;

接着PageHelper会从这条sql中解析其中要查询的表,然后构造出来select count(0) from zf_major这个查询表记录总数的语句,这也是为什么查询总数语句的sql在我们自己编写的select语句之前了的原因(你又没有提前配置它怎么会知道你要分页查哪张表,也在情理之中),最终的查询顺序如下:
在这里插入图片描述
PS:其查询得到的记录总数存储在一个PageHelper提供的一个ThreadLocal里,对于我们如何取PageHelper给我们查询的表记录数可以通过如下方式:

在这里插入图片描述

源码分析
注:只是截了些较为核心的代码片段,能让自己清楚大致的一个流程,并不是特别特别细

step1:首先确认执行查询总记录的sql是在哪个位置

我们在执行了红框之后的代码可以看到屏幕中就出现了两条sql语句,那么核心代码先进行定位:

在这里插入图片描述
step2:进行逐步debug进行排查

这里是走到了PageHelper基于Mybatis的拦截器里

在这里插入图片描述
二次定位核心代码,真正执行查询总记录数sql,如下图黄色框代码:在这里插入图片描述
接着重新进行debug打断点进入到该方法中,发现最终是在executeAutoCount方法中执行的:注意可以看到这是PageHelper的拦截器在这里插入图片描述
在这里可以看到代码依据我们要进行select查询的语句进行解析得到了查询该表的sql语句:
在这里插入图片描述
在这里插入图片描述
其实上面解析出来查询的语句后,后面就是基本的sql执行了,自然就是下面的preparedstatementHandler中
在这里插入图片描述
最终执行查询到该表的记录总数:

在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_Romeo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值