數據庫分頁的實現


前言

  這是我的首篇技術文章,文章內容其實是一年前做項目的時候寫的。今天拿出來共享一下,這篇文章適合初學者學習借用,也希望各位大神提出寶貴意見。

一、分頁技術簡介

  分頁技術主要分三種:客戶端分頁、數據庫分頁、服務器端分頁。

  客戶端分頁:客戶端分頁說的直白一點就是在前台進行分頁。這種分頁的方式減少了與數據庫的交互次數,但主要不足之處在於它要先把所有的數據從數據庫中讀出來,然后再拿到前台進行分頁,當數據量很大的時候,這種缺點暴露的就更加明顯。

  數據庫分頁:這種分頁方式剛好跟客戶端分頁相反,它是根據前台對pageSize的要求,按照pageSize的大小來查詢數據庫。當數據量很大時這種分頁方式比較適用,只在頁面上有查詢需求時,后台才去查詢數據庫。這種分頁方式加大了與數據庫的交互次數

  服務器端分頁:這種分頁方式結合了前面兩種分頁方式。先將數據一次性從數據庫中讀取出來放到緩沖區,在客戶端進行分頁。

二、數據庫分頁技術實現

  1、com.***.data

    做分頁之前,先將與分頁相關的屬性和方法封裝成一個JavaBean,在上層將這些以對象的形式呈現給客戶端。具體的實現代碼如下:    

 1 package zhu.common.data;
 2 
 3 import java.util.List;
 4 
 5 public class Pager {
 6     private int totalRows;//記錄總數
 7     private int pageSize = 5;//設置一頁顯示的記錄數
 8     private int currentPage;//當前頁碼
 9     private int totalPages;//總頁數
10 private int startRow;//當前頁碼開始記錄數
11 private List elements;//記錄列表
12 public Pager() {
13 }
14 //構造pager對象
15 public Pager(int _totalRows, int pageSize) {
16 this.pageSize=pageSize;
17 totalRows = _totalRows;
18 totalPages=totalRows/pageSize;
19 int mod=totalRows%pageSize;
20 if(mod>0){
21     totalPages++;//最后一頁不足一頁則總頁數加1
22 }
23 currentPage = 1;//初始設置當前頁為第一頁
24     startRow = 0;//初始讀取設置為0
25 }
26 
27 //點擊首頁按鈕,執行這個方法
28 public void first() {
29     currentPage = 1;
30     startRow = 0;
31 }
32 //點擊上一頁按鈕,執行這個方法
33 public void previous() {
34     if (currentPage == 1) {
35         return;
36     }
37     currentPage--;
38     startRow = (currentPage - 1) * pageSize;
39 }
40 //點擊下一頁按鈕,執行這個方法
41 public void next() {
42     if (currentPage < totalPages) {
43         currentPage++;
44     }
45     startRow = (currentPage - 1) * pageSize;
46 }
47 //點擊尾頁按鈕,執行這個方法
48 public void last() {
49     currentPage = totalPages;
50     startRow = (currentPage - 1) * pageSize;
51 }
52     
53 //做頁面跳轉時,執行這個方法
54 public void refresh(int _currentPage) {
55     currentPage = _currentPage;
56     if (currentPage > totalPages) {
57         last();//_currentPage超過了總頁數,則跳轉到最后一頁
58     }
59     if(currentPage<1){
60         first();//_currentPage不足1,則跳轉到首頁
61     }
62     startRow = (currentPage - 1) * pageSize;//重新設置起始讀取位置
63 }
64 /*此處略去35行setters和getters,但是在使用這個類時要加上*/
65 }
JavaBean

  2、com.***.utils

    將分頁類設計成公用的util,不同的模塊需要用到分頁功能,都可以使用,但是前提是我們在applicationContext-dao.xml中配置了相應的bean

      <bean id="pagerManager" class="zhu.***.utils.PagerManagerImpl">

               <property name="hibernateTemplate">

                   <ref bean="hibernateTemplate" />

               </property>

      </bean>

    具體的實現代碼如下:

    (1) interface IPagerManager

      分頁工具對外的接口定義。具體的實現代碼如下:

 1 package zhu.***.utils;
 2 
 3 import zhu.***.data.Pager;
 4 
 5 public interface IPagerManager {
 6 /*
 7  * 獲取分頁對象:
 8  * hsql:查詢語句
 9  * currentPage:當前頁
10  * pagerMethod:只有5種取值(first、previous、next、last、空值)(首頁、上一頁、下一頁、尾頁)
11  * 當pagerMethod為空值時,直接跳到currentPage所指定的頁數
12  */
13     public Pager getPager(String hsql,Integer pageSize,String currentPage,String pagerMethod);
14 
15 }
IPagerManager

    

    (2) implement PagerManagerImpl

      

      分頁工具對外的接口的實現。具體的實現代碼如下:

 1 package zhu.***.utils;
 2 import java.util.ArrayList;
 3 import java.util.List;
 4 import org.hibernate.Query;
 5 import org.hibernate.Session;
 6 import org.springframework.orm.hibernate3.SessionFactoryUtils;
 7 import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
 8 import zhu.***.data.Pager;
 9 
10 public class PagerManagerImpl extends HibernateDaoSupport implements IPagerManager {
11 /* 獲取pager對象,用於傳到頁面
12 根據從頁面上傳過來的條件查詢數據
13 currentPage主要用於指定頁面跳轉用,pagerMethod用於首頁、前一頁、后一頁、尾頁這四種請求的跳轉
14 currentPage和pagerMethod不會同時不為空
15 */
16 public Pager getPager(String hsql,Integer pageSize, String currentPage, String pagerMethod) {
17 
18 int totalRows = 0;
19 List items = new ArrayList();
20 Pager pager = null;
21 Session session = SessionFactoryUtils.getSession(getSessionFactory(),true);
22 Query query = session.createQuery(hsql);
23 
24 totalRows = (query.list()).size(); //取得總計錄數
25 //調用構造函數,初始化各種屬性,包括currentPage=1和startRow=0
26 pager = new Pager(totalRows,pageSize);
27 //currentPage主要是做固定頁面跳轉用,從頁面獲取跳轉頁號賦給currentPage
28 //如果不為空,則根據從頁面獲取currentPage來刷新pager對象
29 if (currentPage != null) {
30 pager.refresh(Integer.parseInt(currentPage));
31 }
32 //pagerMethod有四種值即四種請求方式:首頁,前一頁,后一頁,尾頁。
33 if (pagerMethod != null) {
34     if (pagerMethod.equals("first")) {
35         pager.first();
36     } else if (pagerMethod.equals("previous")) {
37         pager.previous();
38     } else if (pagerMethod.equals("next")) {
39         pager.next();
40     } else if (pagerMethod.equals("last")) {
41         pager.last();
42     } 
43 }
44 //從當前頁記錄數開始
45 query.setFirstResult(pager.getStartRow());
46 //取出pageSize個記錄
47 query.setMaxResults(pager.getPageSize());
48 items = query.list();//根據startRow和pageSize查詢數據庫
49 pager.setList(items);//將查詢到數據列表賦值給pager對象的elements屬性
50 
51 return pager;
52 }
53 }
PagerManagerImpl

  3、com.***.dao

    在模塊中的DAO層使用分頁工具,注意要先在該模塊的dao.xml中進行配置相應的bean引用。

      <bean id="ModuleDAO" class="***">

               <property name="pagerManager">

                   <ref bean="pagerManager"/>

               </property>

      </bean>

      具體的實現代碼如下:      

 1 package zhu.***.dao;
 2 import zhu.***.data.Pager;
 3     import zhu.***.utils.IPagerManager;
 4 
 5     public class ExampleDAOImpl {
 6     private IPagerManager pagerManager;
 7 /*
 8 exampleQueryCondition:查詢條件
 9 ExampleTableName:數據表對應於持久化類類名
10 ExampleTablePropertyName:持久化類中的一個屬性名
11 */
12     public Pager find(Integer exampleQueryCondition, Integer pageSize, String currentPage, String pageMethod) {
13 
14 String hsql = " from ExampleTableName where ExampleTablePropertyName = '" + exampleQueryCondition + "'";
15 return this.pagerManager.getPager(hsql, pageSize, currentPage,
16 pageMethod);
17 }
18 }
ExampleDAOImpl

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM