分页原理浅析
1.關(guān)于分頁
只討論分頁,即顯示數(shù)據(jù),不做任何過濾(搜索)和排序,僅僅是顯示數(shù)據(jù)
?
1.1hibernate的分頁
mysql用limit來作分頁,核心參數(shù)有兩個,start與size,即開始的位置與每頁顯示的數(shù)量,但是我們在用hibernate時發(fā)現(xiàn)使用他提供的
setFirstResult((page-1)*pageSize).setMaxResults(pageSize)也可以完成分頁
解釋下page和pageSize,page表示當前頁,也就是當前是第多少頁,pageSize依然表示本頁的數(shù)據(jù)量
page與start的關(guān)系為start=(page-1)*pageSize,以每頁2條數(shù)據(jù)為例,
select * from table limit 0,2 ---->第一頁數(shù)據(jù)是 1,2 start=0,page=1
select * from table limit 2,2 ---->第二頁數(shù)據(jù)是 3,4 start=2,page=2
select * from table limit 4,2 ---->第三頁數(shù)據(jù)是 5,6 start=4,page=3
.....
setFirstResult() -->從哪開始查
setMaxResults() -->查多少
?
1.2 實際使用
1.2.1 以jquery DataTable分頁為例
真正開發(fā)的時候我們顯示數(shù)據(jù)的時候,往往使用各種分頁插件,他們的分頁略有不同,但原理都是一樣的,即通過點擊頁碼,觸發(fā)ajax,發(fā)送當前頁碼(page)以及本頁要顯示的數(shù)據(jù)量(pageSize)給
后臺處理,以jquery DataTable為例, 其發(fā)送給后臺的參數(shù)就有start,代表第一條數(shù)據(jù)的起始位置比如 0代表第一條數(shù)據(jù),當然還有l(wèi)ength,但是你可能會見到這種寫法,這種寫法是公式的反推:page=(start / length) +1,先利用DataTable的ajax向servlet發(fā)送請求,發(fā)送的信息如下圖
?
事實上沒有必要再去計算出page,因為DataTable主動提供了start參數(shù),這里通過打印的形式來再次證明start與page的關(guān)系,(每頁顯示數(shù)據(jù)設置為2)?與我們上面1.1所寫的相互對照,發(fā)現(xiàn)打印的結(jié)果沒什么問題
具體使用請參考https://www.cnblogs.com/tele-share/p/8667434.html
?
1.2.2 以bootstrap-paginator為例
然而大多數(shù)情況下,分頁插件不會直接提供start,只會提供page參數(shù)(因為對于一個插件來說,告訴你現(xiàn)在是第幾頁更加直接明了),比如bootstrap-paginator,這個時候你可以現(xiàn)在前臺計算出start然后傳遞start和size或者傳遞page和size,在后臺進行計算
(事實上在使用bootstrap-paginator的時候你需要兩次ajax,第一次查詢數(shù)據(jù)量,第二次才是顯示數(shù)據(jù))
具體使用請參考http://www.cnblogs.com/tele-share/p/8982910.html
?
通過上面的分析我們可以發(fā)現(xiàn)分頁的核心參數(shù)是start和size,page,但是僅僅有這兩個參數(shù)顯然還不夠
?
1.2.3封裝Page類(顯示用的DataTable)
當你使用分頁插件的時候,不可避免的要去顯示""共計有多少條記錄","共計多少頁",此外你必須告訴你的分頁插件,你的數(shù)據(jù)總量,總頁數(shù)以及你每次查詢到的本頁的結(jié)果集,用戶輸入的關(guān)鍵詞在切換到下一頁
時是要仍然需要顯示在搜索框中,經(jīng)過以上的分析我們發(fā)現(xiàn)這個時候封裝一個Page類就很有必要了(當然不封裝也可以),這個page類通常包括這些屬性:總頁數(shù),總頁碼,當前頁,每頁顯示數(shù)據(jù),關(guān)鍵詞,搜索的域
以及查詢到的結(jié)果集.
1 /* 2 * 分頁對象 3 * 4 */ 5 public class Page<T> { 6 private Integer pageSize;//每頁顯示條數(shù) 7 private Integer page;//當前頁 8 private Integer pageTotal;//總頁數(shù)----->用于顯示當前共多少頁 9 private Integer recordsTotal;//總記錄數(shù)----->顯示當前共有多少條記錄 10 private String keywords;//關(guān)鍵字 假設只有一個 11 private String[] fields; 12 private List<T> list = new ArrayList<T>(); 13 14 public Integer getPageTotal() { 15 return pageTotal; 16 } 17 public void setPageTotal(Integer pageTotal) { 18 this.pageTotal = pageTotal; 19 } 20 public Integer getRecordsTotal() { 21 return recordsTotal; 22 } 23 public void setRecordsTotal(Integer recordsTotal) { 24 this.recordsTotal = recordsTotal; 25 } 26 public List<T> getList() { 27 return list; 28 } 29 public void setList(List<T> list) { 30 this.list = list; 31 } 32 public Integer getPageSize() { 33 return pageSize; 34 } 35 public void setPageSize(Integer pageSize) { 36 this.pageSize = pageSize; 37 } 38 public Integer getPage() { 39 return page; 40 } 41 public void setPage(Integer page) { 42 this.page = page; 43 } 44 public String getKeywords() { 45 return keywords; 46 } 47 public void setKeywords(String keywords) { 48 this.keywords = keywords; 49 } 50 public String[] getFields() { 51 return fields; 52 } 53 public void setFields(String[] fields) { 54 this.fields = fields; 55 } 56 }在servlet中要接收page,pageSize,keywords(關(guān)鍵字),fields(搜索域),這二者構(gòu)成了查詢條件,接下來首先要根據(jù)關(guān)鍵字和域?qū)ο笕ゲ樵兛偭?得到總數(shù)據(jù)量后要來計算總頁數(shù)
總頁數(shù)可以用Math中的ceil()方法來計算,當然if else也可以
1 //封裝page對象 2 @Override 3 public <T> Page<T> getPage(String keywords, String[] fields, Class clazz, int page, int pageSize) { 4 Page<T> pageBean = new Page<T>(); 5 pageBean.setKeywords(keywords); 6 pageBean.setFields(fields); 7 pageBean.setPageSize(pageSize); 8 pageBean.setPage(page); 9 int start = (page-1)*pageSize; 10 List list = this.Page(keywords, fields, clazz,start,pageSize);//查詢的每頁的結(jié)果集 11 pageBean.setList(list); 12 Integer recordsTotal = bookDao.getCount(keywords, fields); 13 pageBean.setRecordsTotal(recordsTotal); 14 Integer pageTotal = 0; 15 /*if(recordsTotal % pageSize == 0) { 16 pageTotal = recordsTotal / pageSize; 17 }else { 18 pageTotal = (recordsTotal / pageSize) + 1; 19 }*/ 20 pageTotal = (int) Math.ceil(recordsTotal / pageSize);//向上取整 21 pageBean.setPageTotal(pageTotal); 22 return pageBean; 23 }如果你是從數(shù)據(jù)庫取數(shù)據(jù)的話到這個地方難點已經(jīng)解決完了,因為這些分頁參數(shù)你都有了,接下來只要傳參數(shù)給數(shù)據(jù)庫就好了,但如果你沒有使用數(shù)據(jù)庫,你的數(shù)據(jù)是采集到本地磁盤上,然后用lucene建立索引庫查詢的話,你還要自己實現(xiàn)底層的分頁方法,底層的分頁處理,應當是遍歷查詢出的結(jié)果集然后封裝每一頁的數(shù)據(jù),以下是偽代碼
1 List list = new ArrayList(); 2 List<Document> docList = search(query);//docList是查詢的總數(shù)據(jù)集 3 int end = Math.min(start+size,docList.size());//也可以用if else判斷 4 for(int i=start;i<end;i++){ 5 Document document = docList.get(i); 6 Object object = document2javabean(document, clazz); 7 list.add(object); 8 }這樣做完之后,這個list里面就是每一頁的數(shù)據(jù)了
?
總結(jié):
1.封裝page類有時并不是很必要,里面的一些屬性,也是看情況添加,但只要你封裝Page對象,那么page和pageSize這兩個屬性少不了的
2.分頁插件多種多樣,各種參數(shù)眼花繚亂,但一些參數(shù)很固定,如總數(shù)據(jù)量,總頁數(shù),當前頁,每頁數(shù)據(jù)量等,把這些參數(shù)處理好,分頁基本就ok了
轉(zhuǎn)載于:https://www.cnblogs.com/tele-share/p/9174926.html
總結(jié)
- 上一篇: a:hover伪类在ios移动端浏览器内
- 下一篇: vim编辑器笔记