PageHelper自動增加limit分頁問題
)
使用PageHelperi分頁,報錯如下:
Caused by: com.alibaba.druid.sql.parser.ParserException: syntax error, error in :’limi1 1 limit ?,?’,expect LIMIT, actual LIMIT limit
原始查詢sql(select * from t limit 1)後面有limit1,結果報錯顯示自動添加上上limit ?,?:
排查
見PageHelper 安全調用:https://github.com/pagehelper/Mybatis-PageHelper/blob/master/blob/master/wikis/zh/HowToUse.md#3-pagehelper-安全調用
PageHelper 方法使用了靜態的 ThreadLocal 參數,分頁參數和線程是綁定的。
只要你可以保證在 PageHelper 方法調用後緊跟 MyBatis 查詢方法,這就是安全的。因爲 PageHelper 在 finally 代碼段中自動清除了 ThreadLocal 存儲的對象。
線程中start的page 不能保證線程在當前執行退出時清理完page變量
重現
XXXServiceImpl {
XX method(Object xx, int pageNum, int pageSize) {
PageHelper.start(pageNum,pageSize);
if(xx!=null){
return XX;
}
xxxMapper.find();
…
}
}
在執行PageHelper.start(pageNum,pageSize);方法後,參數page變量,如xx!=null,直接返回XX,則page沒有被消費,這個參數就會一直保留在這個線程上。當這個線程再次被使用時,如果接下來執行其它sql,就可能導致不該分頁的方法去消費這個分頁參數,這就產生了莫名其妙的分頁。
如果PageHelper.start(pageNum,pageSize);之後的方法加了緩存,也會有這個問題。(就是說分頁方法一定要在緩存之後,mapper之前,mapper的sql一定要執行)
解決方法
1.使用參數方式是極其安全的2.保證在 PageHelper 方法調用後緊跟 MyBatis 查詢方法,必須保證分頁和查詢同時有效。3.調PageHelper.clearPage(); 可以手動清理 ThreadLocal 存儲的分頁參,這個是新版本里的方法 其中5.0之後版本注意:
- 配置文件中PageHelper變爲了PageInterceptor
- 不需要,自動識別數據庫