大話分頁(一)

2021-09-08 16:58:16 字數 3411 閱讀 1560

分頁是一項人性化的功能,也是檢視大量顯示資料的一種解決方案。然而就分頁功能的實現來說,分頁是多種多樣的。那我們在專案中用到的時候,我該使用哪種方式進行分頁呢?下面我將彙總一下分頁查詢的各種實現,並加以比對,當你使用時,做出較好的選擇(本文討論範疇只在真分頁,下面談到的分頁也特指真分頁)。

凡是分頁,無論使用什麼方式實現,它都是以從第幾條資料到第幾條資料這樣的思路實現的,都需要提供兩個引數:

pageno:當前頁號;

pasesize:每頁顯示的資料。

最簡單的方法就是利用mysql資料庫的limit函式進行分頁:

limit[offset],rows可以從mysql資料庫中第m條記錄開始檢索n條記錄的語句為:

select * from 表名 limit m,n

從表sys_option(主鍵為sys_id)中從第10條記錄開始檢索20條記錄,語句如下:

select * from sys_option order by sys_id limit 10,20

oracle中經常使用三層巢狀查詢:

select * from (select t.*,rownum rn from (select * from table order by id) t where rownum =(pageno-1)*pagesize

pageno為當前頁數;

pagesize為每頁顯示資料數目。

查詢的是從第(pageno-1)*pagesize條資料到第pageno*pagesize條資料。

例子:從t_student表中取出第20到40條資料

select * from (select a.*,rownum rn from (select * from t_student order by id) a where rownum <41) where rn >=20

問為什麼oracle要使用三層巢狀查詢實現分頁呢?

其實這跟oracle資料庫的特性有關,rownum的賦值預設從1開始。如果不適用巢狀查詢,我們會寫出下面的語句:

select rownum,id from (select * from t_student order by id) where rownum >=m and rownum < n; 

當執行 rownum>m 且 m>1 時,由於rownum預設為1,這也就是乙個不成立的條件,所以會查不出資料,所以採用三層巢狀語句,將rownum變成乙個臨時表的字段,這時候就沒有oracle資料特性的限制了。

查詢第一頁的五條資料比較好查詢,那麼怎樣查詢第二頁的資料呢(也就是第6到第10條記錄)?

第二頁的記錄就是緊跟這第一頁顯示的記錄之後的5條記錄,也就是通過對userid欄位進行降序排列時,它們是除了第一頁資料之後的5條記錄,也就是它們的userid不在第一頁的userid之中,在sql語句有乙個not in這個正好可以排上用場。 首先我們按照對userid進行降序排序,查詢出前面第一頁使用的資料的userid,sql語句及執行結果如下:

select top 5 * from t_user where userid not in (select 5 userid from t_user order by userid asc) order by userid asc

userid是從1開始,所以userid在1至5的記錄在第一頁顯示,userid為6至10的記錄在第二頁顯示,userid為11至15的記錄在第三頁顯示……依此類推,如果每頁顯示5條記錄,那麼第n頁顯示的資料記錄的公式應該是:

select top 5 * from t_user where userid not in (select top(n-1)*5 userid from t_user order by userid asc) order by userid asc

根據上面我們可以看出:每種資料都有自己特色的內容可以完成分頁功能。hibernate框架再此基礎上進行封裝,只需要query介面中setmaxresultsset和firstresult方法即可完成分頁。採用hibernate的好處就是:如果你使用的mysql資料庫,那麼hibernate就會按照mysql的規則生成相應的分頁語句;如果使用oracle資料庫,那麼它也會相應的生成對應的oracle分頁語句。也就是說,hibernate框架實現分頁,與具體資料庫是無關的,有利於更換資料庫。

下面看乙個hibernate實現分頁的工具類的主要方法:

public class abstractpagemanager extends hibernatedaosupport 

throw new systemexception("無效的hql查詢語句"); }

/*** 根據hql語句進行分頁查詢

* * @param hql hql語句

* @param params hql語句帶的多個引數

* @param offset 從第幾個記錄開始查詢

* @param pagesize 每頁顯示多少行

* @return

*/public pagemodel searchpaginate(string hql, object params, int offset,

int pagesize)

} // 獲取查詢條數

int intcount = ((long) query.uniqueresult()).intvalue();

// 查詢organization記錄

query = getsession().createquery(hql);

// 將hql語句帶的多個引數 賦值給query

if (params != null && params.length > 0)

} /*

* offset 設定從第幾個記錄開始查詢

* pagesize 設定每頁顯示多少行

*/query.setfirstresult(offset);

query.setmaxresults(pagesize);

//組裝pagemodel

pagemodel pagemodel = new pagemodel();

pagemodel.setdatas(query.list());

pagemodel.settotal(intcount);

return pagemodel;

}}

由上可知:mysql、oracle和sqlserver三種資料庫有通性的地方,同時也有自己特色的內容。如果使用資料庫特色的語句,是不利於資料庫的移植的。hibernate框架在此基礎上進行封裝,只需要通過setmaxresultsset()和firstresult()方法設定offset和pagesize,就能根據資料庫生成特色語句,具體實現有興趣的同學可以自行研究hibernate原始碼,我這裡就不往上貼了。

未完待續。。

大話設計記錄一

昨天自己很興奮的拿到了 大話設計模式 剛看了一點點我就感覺這本書真的很有趣。首先說從語言上擺脫了傳統的模式。作者在瞎侃當中讓我們學習了,更重要的是作者運用生活中信手拈來的小例子。其中使我感觸最深的是運用設計模式設計人生,聽上去感覺很大,但是仔細想一想這是非常有趣的事情。先不扯這本書了,下面我來記錄一...

大話儲存筆記(一)

2017 05 22 20 30 最近在寫 很扯淡的 因此沒有啥寫的意義,純屬為了給老師交差。無聊就看看書,不為別的,就只是看看,記錄一下吧 1 ssd 固態硬碟 比較常見的是基於flash介質的,乙個page是flash晶元io的最小單位,每128個page組成乙個block,每2048個bloc...

大話設計模式(一)

物件導向設計四大原則 單一原則 乙個類應該只有乙個引起它變化的原因。如果乙個類擔任的職責過多,就等於把這些職責耦合在一起,一旦乙個職責發生改變,很可能會削弱或者抑制其他職責的能力,即要求耦合度盡可能低。開放 關閉原則 對擴充套件開發,對修改關閉。在乙個軟體開發中,常常需要擴充套件專案,我們應該盡可能...