以前作過不少分頁,只是拿別人的模板照抄下來。今天作一個分頁的時候本身認真分析了一下,裏面問題還挺多的。前端
業務場景:系統作一個web容器的發佈系統,須要有個發佈歷史的頁面。java
問題:web
一、分頁機制的緣由sql
二、通常的實現方式數據庫
三、本身考慮的實現方式爲何不行api
回答:mybatis
一、緣由:數據量太多,所有列出來不方便查看,對客戶端和服務端的壓力也比較大。this
好比發佈系統用了3年了有幾十萬條發佈記錄。一次列出來確定是不符合邏輯的。spa
二、通常的實現方式與原理。排序
寫一個pager類,裏面有三個屬性,分別是start,index和size。
前端傳入index和size咱們根據sql語句limit的寫法,能夠知道須要分頁須要一個偏移量和一個開始行數的。
因此咱們把start做爲開始行數,默認設爲0.用start=(index-1)*size表示分頁以後當前頁面須要顯示的開始行。
pager的代碼以下:
public class Pager {
private int size;
private int index;
private int start = 0;
public Pager(int size, int index) {
this.size = size;
this.index = index;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public int getStart() {
int startIndex = (this.index - 1) * size;//由於limit的表示是從零開始,因此咱們這裏減一
return startIndex > 0 ? startIndex : start;
}
}
limit用法:select * from tablename limit 開始偏移的行號,一次查詢的行數(一次顯示多少行)
這裏我不只須要分頁處理,並且分頁以後還要根據版本信息進行當前頁的逆序排序,好比第一頁點進去須要將第一行顯示爲當前版本。
三、本身的實現方式與問題
因此我剛開始的想法是隻用limit查出來分頁信息,而後再用java的排序對當前的全部信息進行排序。
這樣就會出現一個問題:我limit出來的信息是默認排序的,因此,第一次進入的時候就不是最新發布的版本了。
好比我有100條數據,我limit 0,10
結果會是前10條數據的按版本號逆向排序
而我須要的是最後10條數據的按版本號的逆向排序
解決辦法:還得用數據庫自帶的order by 進行排序而後在limit
由於sql語句的執行順序是:先from再select再order by 再limit,這樣就不會有上面的問題了。
這裏貼出來sql可是是mybatis下寫的sql大概能夠表達出一個意思,可是不能直接執行,但願新手仍是有必定積累在去翻閱博客,否則看起來頭疼不說,還浪費時間。
<select id="selectByEnv" resultMap="BaseResultMap" parameterType="com.mogujie.im.manager.api.entity.WinWebPublishEntity" > select <include refid="Base_Column_List" /> from WinWebPublish <where> <if test="env != null">AND env = #{env,jdbcType=VARCHAR}</if> </where> ORDER BY versions desc limit #{pager.start},#{pager.size}</select>