自己對分頁的理解

raorq發表於2020-04-06
        最近要啟動一個比較大的專案了。回憶以前做的那些web專案,快樂,痛苦,成功,失敗都是經歷過了。
        好久沒動那些web了,都塊忘記這麼設計了,今天在java重新找出一些關於hibernate分頁的帖子,受益良多。
        robbin大哥的說的最詳細的 www.iteye.com/topic/14657
         www.iteye.com/topic/17857
        哈哈,有時間多複習是不錯的。
         
        分頁的主要思想是:
1:構造一個Page物件,把相關的屬性設定好,比如記錄數,每頁包含條數,是否有下一頁,是否有上一頁,當前頁,總頁數等,然後通過Page工廠生成一個Page物件(構造的前題是:你必須知道記錄總數,一般從資料中獲取),最後通過對於資料庫的分頁語句得到結果,比如hibernate分頁的寫法是:
java 程式碼
 
  1. String querySentence = "FROM user in class com.adt.po.User";    
  2.        Query query = getSession().createQuery(querySentence);    
  3.       query.setFirstResult(page.getBeginIndex())    
  4.             .setMaxResults(page.getEveryPage());    
  5.         return query.list();    
這樣做的充分利用資料各自的特性,提供效能。
2:直接從資料load出所有資料,然後再對結果集進行處理。
    對所有資料的操作都是用一條語句就ok了,方便處理,缺點是,資料量大的時候效能會有影響。而且每次都去load這麼多資料,不合理。看看程式碼,很簡單
java 程式碼
 
  1. /** 
  2.  * @author wuhua 
  3.  *  
  4.  * 分頁程式碼,實現策略是,用List類來儲存所有物件,並以page為分頁標記 
  5.  */  
  6.   
  7. import java.util.List;  
  8.   
  9. public class PageModel {  
  10.     private int page = 1// 當前頁  
  11.   
  12.     public int totalPages = 0// 總頁數  
  13.   
  14.     private int pageRecorders;// 每頁5條資料  
  15.   
  16.     private int totalRows = 0// 總資料數  
  17.   
  18.     private int pageStartRow = 0;// 每頁的起始數  
  19.   
  20.     private int pageEndRow = 0// 每頁顯示資料的終止數  
  21.   
  22.     private boolean hasNextPage = false// 是否有下一頁  
  23.   
  24.     private boolean hasPreviousPage = false// 是否有前一頁  
  25.   
  26.     private List list;  
  27.   
  28.     // private Iterator it;  
  29.   
  30.     public PageModel(List list, int pageRecorders) {  
  31.         init(list, pageRecorders);// 通過物件集,記錄總數劃分  
  32.     }  
  33.   
  34.     /** 
  35.      *  
  36.      */  
  37.     public PageModel() {  
  38.     }  
  39.   
  40.     /** 
  41.      * @param list 
  42.      * @param pageRecorders 
  43.      */  
  44.     public void init(List list, int pageRecorders) {  
  45.         this.pageRecorders = pageRecorders;  
  46.         this.list = list;  
  47.         totalRows = list.size();  
  48.         // it = list.iterator();  
  49.         hasPreviousPage = false;  
  50.         if ((totalRows % pageRecorders) == 0) {  
  51.             totalPages = totalRows / pageRecorders;  
  52.         } else {  
  53.             totalPages = totalRows / pageRecorders + 1;  
  54.         }  
  55.   
  56.         if (page >= totalPages) {  
  57.             hasNextPage = false;  
  58.         } else {  
  59.             hasNextPage = true;  
  60.         }  
  61.   
  62.         if (totalRows < pageRecorders) {  
  63.             this.pageStartRow = 0;  
  64.             this.pageEndRow = totalRows;  
  65.         } else {  
  66.             this.pageStartRow = 0;  
  67.             this.pageEndRow = pageRecorders;  
  68.         }  
  69.     }  
  70.   
  71.     /** 
  72.      * @return 返回 page。 
  73.      */  
  74.     public int getPage() {  
  75.         return page;  
  76.     }  
  77.   
  78.     /** 
  79.      * @param page 
  80.      *            要設定的 page。 
  81.      */  
  82.     public void setPage(int page) {  
  83.         this.page = page;  
  84.     }  
  85.   
  86.     /** 
  87.      * @return Returns the pageRecorders. 
  88.      */  
  89.     public int getPageRecorders() {  
  90.         return pageRecorders;  
  91.     }  
  92.   
  93.     /** 
  94.      * @param pageRecorders 
  95.      *            The pageRecorders to set. 
  96.      */  
  97.     public void setPageRecorders(int pageRecorders) {  
  98.         this.pageRecorders = pageRecorders;  
  99.     }  
  100.   
  101.     /** 
  102.      * @return Returns the pageEndRow. 
  103.      */  
  104.     public int getPageEndRow() {  
  105.         return pageEndRow;  
  106.     }  
  107.   
  108.     /** 
  109.      * @return Returns the pageStartRow. 
  110.      */  
  111.     public int getPageStartRow() {  
  112.         return pageStartRow;  
  113.     }  
  114.   
  115.     /** 
  116.      * @return Returns the totalPages. 
  117.      */  
  118.     public String getTotalPages() {  
  119.         return this.toString(totalPages);  
  120.     }  
  121.   
  122.     /** 
  123.      * @return Returns the totalRows. 
  124.      */  
  125.     public String getTotalRows() {  
  126.         return this.toString(totalRows);  
  127.     }  
  128.   
  129.     /** 
  130.      * @return Returns the hasNextPage. 
  131.      */  
  132.     public boolean isHasNextPage() {  
  133.         return hasNextPage;  
  134.     }  
  135.   
  136.     /** 
  137.      * @param hasNextPage 
  138.      *            The hasNextPage to set. 
  139.      */  
  140.     public void setHasNextPage(boolean hasNextPage) {  
  141.         this.hasNextPage = hasNextPage;  
  142.     }  
  143.   
  144.     /** 
  145.      * @return Returns the hasPreviousPage. 
  146.      */  
  147.     public boolean isHasPreviousPage() {  
  148.         return hasPreviousPage;  
  149.     }  
  150.   
  151.     // 判斷要不要分頁  
  152.     public boolean isNext() {  
  153.         return list.size() > 8;  
  154.     }  
  155.   
  156.     /** 
  157.      * @param hasPreviousPage 
  158.      *            The hasPreviousPage to set. 
  159.      */  
  160.     public void setHasPreviousPage(boolean hasPreviousPage) {  
  161.         this.hasPreviousPage = hasPreviousPage;  
  162.     }  
  163.   
  164.     public String toString(int temp) {  
  165.         String str = Integer.toString(temp);  
  166.         return str;  
  167.     }  
  168.   
  169.     public void description() {  
  170.   
  171.         String description = "共有資料數:" + this.getTotalRows() +  
  172.   
  173.         "共有頁數: " + this.getTotalPages() +  
  174.   
  175.         "當前頁數為:" + this.getPage() +  
  176.   
  177.         " 是否有前一頁: " + this.isHasPreviousPage() +  
  178.   
  179.         " 是否有下一頁:" + this.isHasNextPage() +  
  180.   
  181.         " 開始行數:" + this.getPageStartRow() +  
  182.   
  183.         " 終止行數:" + this.getPageEndRow();  
  184.   
  185.         System.out.println(description);  
  186.     }  
  187.   
  188.     public List getNextPage() {  
  189.         page = page + 1;  
  190.   
  191.         disposePage();  
  192.   
  193.         System.out.println("使用者凋用的是第" + page + "頁");  
  194.         this.description();  
  195.         return getObjects(page);  
  196.     }  
  197.   
  198.     /** 
  199.      * 處理分頁 
  200.      */  
  201.     private void disposePage() {  
  202.   
  203.         if (page == 0) {  
  204.             page = 1;  
  205.         }  
  206.   
  207.         if ((page - 1) > 0) {  
  208.             hasPreviousPage = true;  
  209.         } else {  
  210.             hasPreviousPage = false;  
  211.         }  
  212.   
  213.         if (page >= totalPages) {  
  214.             hasNextPage = false;  
  215.         } else {  
  216.             hasNextPage = true;  
  217.         }  
  218.     }  
  219.   
  220.     public List getPreviousPage() {  
  221.   
  222.         page = page - 1;  
  223.   
  224.         if ((page - 1) > 0) {  
  225.             hasPreviousPage = true;  
  226.         } else {  
  227.             hasPreviousPage = false;  
  228.         }  
  229.         if (page >= totalPages) {  
  230.             hasNextPage = false;  
  231.         } else {  
  232.             hasNextPage = true;  
  233.         }  
  234.         this.description();  
  235.         return getObjects(page);  
  236.     }  
  237.   
  238.     /** 
  239.      * 獲取第幾頁的內容 
  240.      *  
  241.      * @param page 
  242.      * @return 
  243.      */  
  244.     public List getObjects(int page) {  
  245.         if (page == 0)  
  246.             this.setPage(1);  
  247.         else  
  248.             this.setPage(page);  
  249.         this.disposePage();  
  250.         if (page * pageRecorders < totalRows) {// 判斷是否為最後一頁  
  251.             pageEndRow = page * pageRecorders;  
  252.             pageStartRow = pageEndRow - pageRecorders;  
  253.         } else {  
  254.             pageEndRow = totalRows;  
  255.             pageStartRow = pageRecorders * (totalPages - 1);  
  256.         }  
  257.   
  258.         List objects = null;  
  259.         if (!list.isEmpty()) {  
  260.             objects = list.subList(pageStartRow, pageEndRow);  
  261.         }  
  262.         this.description();  
  263.         return objects;  
  264.     }  
  265.   
  266.     public List getFistPage() {  
  267.         if (this.isNext()) {  
  268.             return list.subList(0, pageRecorders);  
  269.         } else {  
  270.             return list;  
  271.         }  
  272.     }  
  273.   
  274.     /** 
  275.      * @return 返回 list。 
  276.      */  
  277.     public List getList() {  
  278.         return list;  
  279.     }  
  280.   
  281.     /** 
  282.      * @param list 
  283.      *            要設定的 list。 
  284.      */  
  285.     public void setList(List list) {  
  286.         this.list = list;  
  287.     }  
  288.   
  289.     /** 
  290.      * @param totalRows 
  291.      *            要設定的 totalRows。 
  292.      */  
  293.     public void setTotalRows(int totalRows) {  
  294.         this.totalRows = totalRows;  
  295.     }  
  296. }  

3:採用快取的機制,使用者在第一次查詢的時候把查詢結果存入快取中,這樣使用者下載下一頁的時候,就不用再去從資料庫中查詢,也可以通過第一中方法,先查詢,然後在存入快取,可以這樣理解,智慧的記錄使用者的操作,如果使用者有重複操作就可以把上次的操作結果展示給使用者



     

相關文章