mybatis执行自定义sql时,多出一个limit

报错信息:

### Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LIMIT 10' at line 19
; bad SQL grammar []; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LIMIT 10' at line 19

执行自定义sql,在方法中没有使用任何分页插件,但是项目中其它地方有引用PageHelper,单独调试这个方法没有发现问题,在测试过程中发现偶现的sql错误问题,参考http://www.herohuang.com/2018/08/08/pagehelper-limit/ 成功解决问题。

原因:

PageHelper 方法使用了静态的 ThreadLocal 参数,分页参数和线程是绑定的。

只要你可以保证在 PageHelper 方法调用后紧跟 MyBatis 查询方法,这就是安全的。因为 PageHelper 在 finally 代码段中自动清除了 ThreadLocal 存储的对象。

线程中start的page 不能保证线程在当前执行退出时清理完page变量

复现:

在执行PageHelper.start(pageNum,pageSize);方法后,参数page变量,如xx!=null,直接返回XX,则page没有被消费,这个参数就会一直保留在这个线程上。当这个线程再次被使用时,如果接下来执行其它sql,就可能导致不该分页的方法去消费这个分页参数,这就产生了莫名其妙的分页。

如果PageHelper.start(pageNum,pageSize);之后的方法加了缓存,也会有这个问题。

解决方法:

1.使用参数方式是极其安全的
2.保证在 PageHelper 方法调用后紧跟 MyBatis 查询方法,必须保证分页和查询同时有效。
3.调PageHelper.clearPage();

什么是ThreadLocal?

MybatisPlus 和 PageHelper插件都通过使用threadLocal 来实现分页功能,那么什么是threadLocal呢?

使用方法

        ThreadLocal<Object> threadLocal = new ThreadLocal<>();
        threadLocal.remove();//清空
        threadLocal.get();//获取
        threadLocal.set(new Object());//赋值

官方解释:

/**
 * This class provides thread-local variables.  These variables differ from
 * their normal counterparts in that each thread that accesses one (via its
 * {@code get} or {@code set} method) has its own, independently initialized
 * copy of the variable.  {@code ThreadLocal} instances are typically private
 * static fields in classes that wish to associate state with a thread (e.g.,
 * a user ID or Transaction ID).
 */

ThreadLocal是一个线程内部的数据存储类,通过它可以在当前线程存储数据,其内部维护了一个ThreadLocalMap,其内部Entity继承WeakReference,key是当前threadLocal对象。

使用场景:

当某些数据是以线程为作用域并且不同线程具有不同的数据副本的时候

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值