前言
這是我的首篇技術文章,文章內容其實是一年前做項目的時候寫的。今天拿出來共享一下,這篇文章適合初學者學習借用,也希望各位大神提出寶貴意見。
一、分頁技術簡介
分頁技術主要分三種:客戶端分頁、數據庫分頁、服務器端分頁。
客戶端分頁:客戶端分頁說的直白一點就是在前台進行分頁。這種分頁的方式減少了與數據庫的交互次數,但主要不足之處在於它要先把所有的數據從數據庫中讀出來,然后再拿到前台進行分頁,當數據量很大的時候,這種缺點暴露的就更加明顯。
數據庫分頁:這種分頁方式剛好跟客戶端分頁相反,它是根據前台對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 }
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 }
(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 }
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 }