MyBitis自动拼接了LIMIT

27 篇文章 2 订阅
20 篇文章 4 订阅
文章讲述了在系统运营中遇到的SQL拼接错误,经排查发现是由于未正确管理的PageHelper分页插件导致。作者分析了问题原因并提供了两种处理方案:在if方法块内初始化分页插件或在else块手动清理。第一种方法被认为是更好的解决策略。
摘要由CSDN通过智能技术生成

1.前言

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

2.排查思路

2.1.第一步

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

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

2.2.第二步

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

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

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

3.问题处理

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

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

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

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

MyBatis是一个优秀的Java持久层框架,它提供了一种将SQL语句与Java代码解耦的方式。在MyBatis中,<where>标签和limit关键字用于在SQL语句中进行条件筛选和结果限制。 <where>标签用于动态生成WHERE子句,它可以根据条件的存在与否决定是否添加WHERE关键字。这个标签通常与其他条件标签(如<if>、<choose>等)一起使用,用于拼接动态的查询条件。 例如,我们可以这样使用<where>标签: ```xml <select id="getUserList" resultType="User"> SELECT * FROM user <where> <if test="username != null"> AND username = #{username} </if> <if test="email != null"> AND email = #{email} </if> </where> </select> ``` 上述示例中,根据传入的参数username和email的值是否为空,动态生成了相应的查询条件。 而limit关键字用于限制查询结果的数量。它通常与SELECT语句一起使用,用于指定返回的记录数量。在MyBatis中,我们可以通过使用limit关键字来实现结果集的分页。 例如,在MySQL中,我们可以这样使用limit关键字: ```sql SELECT * FROM user LIMIT 10 OFFSET 20; ``` 上述示例表示从user表中查询20到29条记录。 在MyBatis中,我们可以使用类似的方式来实现分页查询: ```xml <select id="getUserList" resultType="User"> SELECT * FROM user LIMIT #{offset}, #{pageSize} </select> ``` 上述示例中,我们可以通过传入offset和pageSize参数来指定查询结果的起始位置和每页的记录数,从而实现分页查询
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

大鱼>

一分也是爱

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

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

打赏作者

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

抵扣说明:

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

余额充值