mybatis执行的sql,两个limit

时间:2025-04-11 17:59:39

之前检查生产日志的时候发现过一个奇怪的现象,数据库报错,sql语句错了,有两个limit

这种错误不应该出现在生产日志上,有点惊讶,我都怀疑是不是有成员的代码没有经过测试就发布了

但是当我把sql拿下来查找的时候,却发现报错的代码段,sql是正常的,仅有一个limit,拿去数据库跑

结果也是符合预期的

 

这让我想到了pagehelper,这个插件的功能是帮助你分页,它会帮你加入limit

我回到业务层去找相应的代码,也没找到分页助手相关的代码,但我还是怀疑是它有问题。

我翻看它的源码,发现了下面的对象,这个线程常量是它所持有的。

protected static final ThreadLocal<Page> LOCAL_PAGE = new ThreadLocal<Page>();

还有多个线程变量被持有了,用来记录分页相关的信息。

 

pagehelper会在使用完后将它清除

public static void clearPage() {
    LOCAL_PAGE.remove();
}
@Override
public void afterAll() {
    //这个方法即使不分页也会被执行,所以要判断 null
    AbstractHelperDialect delegate = ();
    if (delegate != null) {
        ();
        ();
    }
    clearPage();
}

afterAll方法是在分页的代码里加在了拦截方法的finally代码块,如果分页报错了,仍然要把线程变量清除掉。

} finally {
    ();
}

 

但是问题也在这里,如果你使用PageHelper的时候,不是和dao层方法连在一起的,中间还有逻辑,那么中间

逻辑报错了,或者逻辑判断导致dao层代码不执行,这个PageHelper的分页信息,就留在了线程里,tomcat线程池

的线程复用的时候,就会把原本正常的请求也被PageHelper加了分页操作,报错的话还能及时察觉,不然你的整个

业务逻辑都产生了问题,根本不是分页的,自动分页处理会导致数据漏处理。

 

解决方法:使用PageHelper的时候把dao层代码写在一起,不要拆分,即使你当前确保中间没有问题,后来的人

也可能继续加入内容而导致问题,把坑留到了后面。