目錄
- 1. 問題描述
- 2. 解決方案
- 2.1 方案一
- 2.2 方案二
- 3. 完成效果
- 4. 一點困惑
- 5. 參考文獻
1. 問題描述
今天在完善項目的時候,有一個需求就是給我的評論區實作分頁顯示評論數,但是當自己運作的時候點選檢視評論的時候出現下面圖示的結果,這就開始了我長達2個小時的改bug艱難征程。

在控制台的顯示如下:
### 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);
再次運作,結果如下所示:
嗯嗯,看起來好像實作了分頁,但是當我們選擇了一個有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. 完成效果
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 官方中文文檔