MyBitis自动拼接了LIMIT

1.前言

最近系统在运营的过程中发现一个很奇怪的问题,莫名其妙的SQL语句会被拼接上一小段SQL,但是发现这被拼接的SQL并不是当前这个API所使用的SQL,因此导致select语句出错。

2.排查思路

2.1.第一步

首先我排查了打印日志里面的错误对应的Mapper,发现这个动态拼接的SQL正常情况下不是此Mapper能够产生的。

MyBitis自动拼接了LIMIT_第1张图片

找到自动拼接的SQL后,首先我先对全文搜索"order by a.createTime desc",发现并没有哪个函数使用了这个语句,看结构“order by xxxxx limit”有点像被分页插件PageHelper自动拼接上的。

2.2.第二步

然后我就缩小查询范围,检索“a.createTime desc”,发现确实有几个方法使用到,一个个排查,发现其中一个方法引起了我的注意。

MyBitis自动拼接了LIMIT_第2张图片

这里使用到了分页插件PageHelper,并且使用了orderBy进行排序,比较符合当前自动拼接的现象。但是为什么这个拼接会被其他Mapper使用呢?这里我们就需要了解一下PageHelper的底层实现了。

MyBitis自动拼接了LIMIT_第3张图片

MyBitis自动拼接了LIMIT_第4张图片

在看我们代码,我们在if之前已经初始化了PageHelper,这时候分页插件LOCAL_PAGE.set(page);已经被赋值了,但是如果我们的if不满足要求,则会直接跳转到else并返回null。整个流程虽然PageHelper已经被赋值,但是未被使用,因此未被销毁。因此我们执行下个select语句的时候就可能被这个语句给拼接上,导致查询出错。

MyBitis自动拼接了LIMIT_第5张图片

3.问题处理

我们定位到问题原因了,那么就好排查了,我们可以通过两种方式处理这个问题。

第一种,将分页插件的初始化在if方法块里面,即:

MyBitis自动拼接了LIMIT_第6张图片

第二种,在else方法块里面手动清理一次,即:

MyBitis自动拼接了LIMIT_第7张图片

显然,第一种方法更好些,用到的时候再进行初始化。

你可能感兴趣的:(Java,IOT套件笔记,Spring,Boot,java,mybatis,数据库)