首先,我們要理解分頁的算法,也要講究效率,也就是說我們不能把所有的記錄取出來,我們只取一個頁面中需要顯示的紀錄,那麼怎麼去實現是我們關心的問題!不要着急,重在理解而是單純技術實現。我採用Web框架兩種方式來實現,attention!<o:p></o:p>
分頁算法,也就是我們提供給客戶方便的操作。一般有哪些東西呢?<o:p></o:p>
上頁、下頁、首頁、末頁、導航到X頁,頁碼導航。說到這裏我們先放下,我們來說說取出頁面的記錄,也就是隻取一段的記錄。打開Hibernate API 看到Criteria 接口,public Criteria setMaxResults(int maxResults),意思爲:設置記錄對象數目的上限,第二方法,public Criteria setFirstResult setFirstResult(int firstResult),意思:設置開始取得記錄對象的下標,其中的第一對象下標爲0。這樣我們可以看出Hibernate提供很好的方法給我們實現分頁。<o:p></o:p>
我們產生了思路:我們只有設置firstResult得下標,我們這裏把它叫做遊標。我們只要控制遊標就可以控制取得的記錄就是我們想要得到的,下面要做的工作就是我們來控制index,下面我寫了一個HPage的類來實現這個工作,也就是取得一些相關的值,其中我們關係的有:當前的頁碼、當前的遊標等等,下面我們結合代碼來說明下!~~~<o:p></o:p>
實現代碼如下:
- public class HPage {
- private int countPage; //頁面的數量
- private int startIndex=0; //紀錄遊標
- private int recordPerPage; //每頁中的記錄數量
- private int pageIndex=1; //初始的頁碼
- private boolean nextPage=true;
- private boolean previousPage=false;
- private boolean firstPage=true;
- private boolean lastPage=false;
- public int getCountPage() //取得頁面的數量
- {
- return countPage;
- }
- public int getStartIndex() //取得遊標的位置
- {
- return startIndex;
- }
- public HPage(int countRecord,int recordPerPage)
- //coutRecord參數:紀錄的總數量;recordPerPage參數:設置每頁的記錄數量
- {
- this.recordPerPage=recordPerPage;
- if(countRecord % recordPerPage == 0)
- countPage=countRecord / recordPerPage;
- else
- countPage=countRecord / recordPerPage +1;
- }
- public int getPageIndex() // 取得當前頁碼
- {
- return pageIndex;
- }
- public int nextPage() // 遊標下一頁滾動
- {
- pageIndex++;
- if(isOnlyOne())
- {
- nextPage=false;
- previousPage=false;
- firstPage=false;
- lastPage=false;
- }
- else
- {
- previousPage=true;
- firstPage=true;
- }
- if(pageIndex > countPage)
- return lastPage();
- else
- {
- return (startIndex=forwardPage(pageIndex));
- }
- }
- public int previousPage() // 遊標上一頁滾動
- {
- pageIndex--;
- if(isOnlyOne())
- {
- nextPage=false;
- previousPage=false;
- firstPage=false;
- lastPage=false;
- }
- else
- {
- nextPage=true;
- lastPage=true;
- }
- if(pageIndex <= 1)
- return firstPage();
- else
- {
- return (startIndex=forwardPage(pageIndex));
- }
- }
- public int lastPage() // 遊標向末頁滾動
- {
- pageIndex=countPage;
- if(isOnlyOne())
- {
- nextPage=false;
- previousPage=false;
- firstPage=false;
- lastPage=false;
- }
- else
- {
- nextPage=false;
- previousPage=true;
- firstPage=true;
- lastPage=false;
- }
- return (startIndex=(countPage-1) * recordPerPage);
- }
- public int firstPage() // 遊標向首頁滾動
- {
- pageIndex=1;
- if(isOnlyOne())
- {
- nextPage=false;
- previousPage=false;
- firstPage=false;
- lastPage=false;
- }
- else
- {
- nextPage=true;
- previousPage=false;
- firstPage=false;
- lastPage=true;
- }
- return (startIndex=0);
- }
- public int forwardPage(int pageIndex) //導向制定頁面
- {
- if(pageIndex >= countPage)
- {
- pageIndex=countPage;
- return (startIndex=lastPage());
- }
- else if(pageIndex <= 1)
- {
- pageIndex=1;
- return startIndex=firstPage();
- }
- this.pageIndex=pageIndex;
- if(isOnlyOne())
- {
- nextPage=false;
- previousPage=false;
- firstPage=false;
- lastPage=false;
- }
- else
- {
- nextPage=true;
- previousPage=true;
- firstPage=true;
- lastPage=true;
- }
- return (startIndex=(this.pageIndex -1)* recordPerPage);
- }
- private boolean isOnlyOne() //是否只有一頁
- {
- return countPage==1 ? true : false;
- }
- public boolean isNextPage() //是否有下頁
- {
- return nextPage;
- }
- public boolean isPreviousPage() //是否有上頁
- {
- return previousPage;
- }
- public boolean isFirstPage() //是否首頁
- {
- return firstPage;
- }
- public boolean isLastPage() //是否末頁
- {
- return lastPage;
- }
- }
不是很難吧!好的,現在我們做好的工作就是取得了我們要的數值,下面要做的是加到Hibernate查詢裏面去,下面的工作很簡單。但是我們要注意幾個問題,第一個問題,我們的設計的目的不是爲了解決一個問題,而是抽象出一個方案提供給相似的問題的解決方案。這樣的話,我們最大化重利用代碼,那麼我們採用範性的特點(注意JDK5.0的特徵,以前的版本會報錯誤)。下面我分析一下代碼:<o:p></o:p>
- public class DisplayPageRecordList<t></t> { //泛型實現
- private int startIndex;
- private static final int DEFAULT_RECORD_PER_PAGE=5; //默認:每頁中5條記錄
- private List<t></t> list;
- private HPage page;
- private int recordPerPage=DEFAULT_RECORD_PER_PAGE;
- private final Session session=HibernateSessionFactory.getSession();
- private DetachedCriteria deCriteria;
- private Criteria criteria;
- private int countRecord;
- public DisplayPageRecordList(String className) throws ClassNotFoundException
- //className參數:類的全定名稱
- {
- deCriteria=DetachedCriteria.forClass(Class.forName(className)); //創造離線的查詢
- criteria=deCriteria.getExecutableCriteria(session);
- criteria.setCacheable(true);
- doInit();
- page=new HPage(countRecord,recordPerPage);
- }
- public DisplayPageRecordList(int recordPerPage,String className) throws ClassNotFoundException
- //recordPerPage參數:每頁的紀錄的條目數,className參數:同上個構造方法中
- {
- deCriteria=DetachedCriteria.forClass(Class.forName(className));
- criteria=deCriteria.getExecutableCriteria(session);
- criteria.setCacheable(true);
- this.recordPerPage=recordPerPage;
- doInit();
- page=new HPage(countRecord,recordPerPage);
- }
- public DisplayPageRecordList(int recordPerPage,String className,Criterion criterion) throws ClassNotFoundException
- //recordPerPage參數:同上個構造方法中,className參數:同上個構造方法中,criterion參數:設置查詢條件
- {
- deCriteria=DetachedCriteria.forClass(Class.forName(className));
- criteria=deCriteria.getExecutableCriteria(session);
- criteria.add(criterion);
- criteria.setCacheable(true);
- doInit();
- page=new HPage(countRecord,recordPerPage);
- }
- public void setRecordPerPage(int recordPerPage)
- {
- this.recordPerPage=recordPerPage;
- page=new HPage(countRecord,recordPerPage);
- }
- private void doInit()
- {
- this.countRecord=criteria.list().size(); //計算數據庫中所有的記錄數
- }
- public void addCriterion(Criterion criterion)
- {
- criteria=criteria.add(criterion); //更改所有所有查詢條件
- doInit();
- }
- public void setCacheable(boolean cache) //是否啓用緩存
- {
- criteria.setCacheable(cache);
- }
- public List doNextPage() //查詢出下頁中的紀錄集
- {
- startIndex=page.nextPage();
- criteria.setFirstResult(startIndex);
- criteria.setMaxResults(this.recordPerPage);
- list=criteria.list();
- return list;
- }
- public List doPreviousPage() //查詢出上頁中的紀錄集
- {
- startIndex=page.previousPage();
- criteria.setFirstResult(startIndex);
- criteria.setMaxResults(this.recordPerPage);
- list=criteria.list();
- return list;
- }
- public List doFirstPage() //查詢出首頁中的紀錄集
- {
- startIndex=page.firstPage();
- criteria.setFirstResult(startIndex);
- criteria.setMaxResults(this.recordPerPage);
- list=criteria.list();
- return list;
- }
- public List doLastPage() //查詢出末頁中的紀錄集
- {
- startIndex=page.lastPage();
- criteria.setFirstResult(startIndex);
- criteria.setMaxResults(this.recordPerPage);
- list=criteria.list();
- return list;
- }
- public List doForward(int pageIndex)
- {
- startIndex=page.forwardPage(pageIndex);
- criteria.setFirstResult(startIndex);
- criteria.setMaxResults(this.recordPerPage);
- list=criteria.list();
- return list;
- }
- public HPage getPage() //取得頁面對象
- {
- return this.page;
- }
- }
以上代碼中,實現了泛型-離線查詢的頁面的代碼。上篇完,下篇我們來使用Struts和JSTL在網頁上測試<o:p></o:p>
<o:p></o:p>