分頁是一項人性化的功能,也是檢視大量顯示資料的一種解決方案。然而就分頁功能的實現來說,分頁是多種多樣的。那我們在專案中用到的時候,我該使用哪種方式進行分頁呢?下面我將彙總一下分頁查詢的各種實現,並加以比對,當你使用時,做出較好的選擇(本文討論範疇只在真分頁,下面談到的分頁也特指真分頁)。
凡是分頁,無論使用什麼方式實現,它都是以從第幾條資料到第幾條資料這樣的思路實現的,都需要提供兩個引數:
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...
大話設計模式(一)
物件導向設計四大原則 單一原則 乙個類應該只有乙個引起它變化的原因。如果乙個類擔任的職責過多,就等於把這些職責耦合在一起,一旦乙個職責發生改變,很可能會削弱或者抑制其他職責的能力,即要求耦合度盡可能低。開放 關閉原則 對擴充套件開發,對修改關閉。在乙個軟體開發中,常常需要擴充套件專案,我們應該盡可能...