天天看點

解決Mybatis分頁插件PageHelper自動添加limit導緻分頁失敗問題

目錄

  • ​​1. 問題描述​​
  • ​​2. 解決方案​​
  • ​​2.1 方案一​​
  • ​​2.2 方案二​​
  • ​​3. 完成效果​​
  • ​​4. 一點困惑​​
  • ​​5. 參考文獻​​

1. 問題描述

今天在完善項目的時候,有一個需求就是給我的評論區實作分頁顯示評論數,但是當自己運作的時候點選檢視評論的時候出現下面圖示的結果,這就開始了我長達2個小時的改bug艱難征程。

解決Mybatis分頁插件PageHelper自動添加limit導緻分頁失敗問題

在控制台的顯示如下:

### Error querying database.  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 5
### The error may exist in file [D:\java-workspace\forums\target\forums\WEB-INF\classes\forum\mapper\ReplyMapper.xml]
### The error may involve forum.dao.ReplyMapper.getRepliesOfTopic-Inline
### The error occurred while setting parameters
### SQL: select reply.*, user.username, user.avatar         from reply, user         where reply.reply_user_id = user.id           and reply.topic_id = ?         order by create_time ASC; 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 5
; 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 5
  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 5
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at com.mysql.jdbc.Util.handleNewInstance(Util.java:411)      

2. 解決方案

既然問題出現了,我們就得給他解決,先說說自己在網上看到的幾種解決方案吧,我都親自嘗試過了。

2.1 方案一

剛開始的時候,看到網上的一段話,如下所示:

使用了Spring的PageHelper插件,發現了一個奇怪的問題,經常會給SQL無緣無故的增加Limit語句,經過調查,發現原因是沒有安全的使用PageHelper插件      

然後給出的解決方案就是:

要絕對保證PageHelper.startPage和分頁查詢語句之間不要有任何其他語句,或者在程式結束時增加PageHelper.clearPage();的調用      

嗯嗯,我就按照這個大概的意思嘗試了下,我的代碼如下:

(page.getStart(), page.getCount());
        PageHelper.clearPage();
        //擷取主題全部評論
        List<Reply> replies = replyService.getRepliesOfTopic(id);
        //分頁
        int total = (int) new PageInfo<Reply>(replies).getTotal();
        page.setTotal(total);      

再次運作,結果如下所示:

解決Mybatis分頁插件PageHelper自動添加limit導緻分頁失敗問題

嗯嗯,看起來好像實作了分頁,但是當我們選擇了一個有11條記錄的評論,按理說第一頁10條,第二頁1條,但是我們看見了第二頁與第一頁一樣都是11條,是以這種方法沒有作用。

2.2 方案二

嗯嗯,不得不說皇天不負有心人,果然還是方案二一語點醒夢中人,看到的這篇文章說先檢查下自己的SQL語句有沒有問題,嗯嗯,按照這個我測試了下好像沒有啥問題,但是控制台報的下面這句錯:

SQL: select reply.*, user.username, user.avatar  from reply, user         where reply.reply_user_id = user.id  and reply.topic_id = ?         order by create_time ASC;      

果然還是自己的SQL語句出問題了因為當我們使用PageHelper這個分頁插件的時候,會自動給我們的SQL語句加上limit,是以加上limit之後我們的SQL因為有個;号是以出現了文法錯誤,故解決方案就是将;号去掉,如下所示:

<select id="getRepliesOfTopic" resultMap="replyAndUser" parameterType="int">
        select reply.*, user.username, user.avatar
        from reply, user
        where reply.reply_user_id = user.id
          and reply.topic_id = #{topicId,jdbcType=INTEGER}
        order by create_time ASC
    </select>      

然後再次執行完美運作。

3. 完成效果

解決Mybatis分頁插件PageHelper自動添加limit導緻分頁失敗問題

4. 一點困惑

在使用PageHelper這個分頁插件的時候,我發現了一個很奇怪的問題,比如下面例子:

(page.getStart(), page.getCount());
        //擷取主題資訊
        Topic topic = topicService.selectById(id);
        //擷取主題全部評論
        List<Reply> replies = replyService.getRepliesOfTopic(id);
        //分頁
        int total = (int) new PageInfo<Reply>(replies).getTotal();
        page.setTotal(total);      

當我們的 PageHelper.offsetPage(page.getStart(), page.getCount());下面的一句代碼是Topic topic = topicService.selectById(id);那麼我們的PageHelper會對這個函數的SQL語句後面添加limit,導緻出現我們剛開始的問題,是以我暫時也不清楚具體原理,有空的時候再來研究下原理,有知道的小夥伴也可以在留言區告訴我。

5. 參考文獻

​​1. Mybatis-PageHelper 官方中文文檔​​