参考资料:

http://blog.csdn.net/zhjb1025/archive/2006/04/19/668631.aspx

http://www.cnblogs.com/HuaiHuai/archive/2005/08/09/211062.html

 

整理的代码如下:

Page.java接口

  1. package org.domain.scrm4u.helper;

  2. import java.util.List;

  3. public interface Page {

  4.     boolean isFirstPage();

  5.     boolean isLastPage();

  6.     boolean hasNextPage();

  7.     boolean hasPreviousPage();

  8.     int getLastPageNumber();

  9.     List<?> getThisPageElements();

  10.     int getTotalNumberOfElements();

  11.     int getThisPageFirstElementNumber();

  12.     int getThisPageLastElementNumber();

  13.     int getNextPageNumber();

  14.     int getPreviousPageNumber();

  15.     int getPageSize();

  16.     int getPageNumber();
  17. }

ListPage.java实现:

  1. package org.domain.scrm4u.helper.impl;

  2. import java.util.List;

  3. import org.domain.scrm4u.helper.Page;

  4. public class ListPage implements Page {

  5.     private List<?> elements;
  6.     private int pageSize;
  7.     private int pageNumber;

  8.     public ListPage(List<?> elements, int pageNumber, int pageSize) {
  9.         
  10.         this.elements = elements;
  11.         this.pageSize = pageSize;
  12.         this.pageNumber = pageNumber;
  13.         if (Integer.MAX_VALUE == this.pageNumber) this.pageNumber = (getTotalNumberOfElements() / this.pageSize);
  14.     }

  15.     public boolean isFirstPage() {
  16.         
  17.         return getPageNumber() == 0;
  18.     }

  19.     public boolean isLastPage() {
  20.         
  21.         return getPageNumber() >= getLastPageNumber();
  22.     }

  23.     public boolean hasNextPage() {
  24.         
  25.         return ((getPageNumber() + 1) * getPageSize()) < (getTotalNumberOfElements() + 1);
  26.     }

  27.     public boolean hasPreviousPage() {
  28.         
  29.         return getPageNumber() > 0;
  30.     }

  31.     public int getLastPageNumber() {

  32.         double totalResults = new Integer(getTotalNumberOfElements()).doubleValue();
  33.         return new Double(Math.floor(totalResults / getPageSize())).intValue();
  34.     }

  35.     public List<?> getThisPageElements() {

  36.         final int start = getPageNumber() * getPageSize();
  37.         return elements.subList(
  38.                     Math.min(start, getTotalNumberOfElements() + 1), 
  39.                     Math.min(start + getPageSize(), getTotalNumberOfElements() + 1)
  40.                );
  41.     }

  42.     public int getTotalNumberOfElements() {
  43.         return elements.size() - 1;
  44.     }

  45.     public int getThisPageFirstElementNumber() {
  46.         return getPageNumber() * getPageSize() + 1;
  47.     }

  48.     public int getThisPageLastElementNumber() {
  49.         int fullPage = getThisPageFirstElementNumber() + getPageSize() - 1;
  50.         return getTotalNumberOfElements() < fullPage ? getTotalNumberOfElements() : fullPage;
  51.     }

  52.     public int getNextPageNumber() {
  53.         return getPageNumber() + 1;
  54.     }

  55.     public int getPreviousPageNumber() {
  56.         return getPageNumber() - 1;
  57.     }

  58.     public int getPageSize() {
  59.         return pageSize;
  60.     }

  61.     public int getPageNumber() {
  62.         return pageNumber;
  63.     }
  64. }

HibernatePage.java实现:

  1. package org.domain.scrm4u.helper.impl;

  2. import java.util.List;

  3. import org.domain.scrm4u.helper.Page;
  4. import org.hibernate.HibernateException;
  5. import org.hibernate.Query;
  6. import org.hibernate.ScrollMode;
  7. import org.hibernate.ScrollableResults;

  8. public class HibernatePage implements Page {

  9.     protected List<?> elements;
  10.     protected int pageSize;
  11.     protected int pageNumber;
  12.     protected int totalElements = 0;

  13.     private ScrollableResults scrollableResults;

  14.     private HibernatePage(int pageNumber, int pageSize) {
  15.         
  16.         this.pageNumber = pageNumber;
  17.         this.pageSize = pageSize;
  18.     }

  19.     public boolean isFirstPage() {
  20.         return getPageNumber() == 0;
  21.     }

  22.     public boolean isLastPage() {
  23.         
  24.         return getPageNumber() >= getLastPageNumber();
  25.     }

  26.     public boolean hasNextPage() {
  27.         
  28.         return elements.size() > getPageSize();
  29.     }

  30.     public boolean hasPreviousPage() {
  31.         
  32.         return getPageNumber() > 0;
  33.     }

  34.     public int getLastPageNumber() {

  35.         double totalResults = new Integer(getTotalNumberOfElements()).doubleValue();
  36.         return new Double(Math.floor(totalResults / getPageSize())).intValue();
  37.     }

  38.     public List<?> getThisPageElements() {

  39.         return hasNextPage() ? elements.subList(0, getPageSize()) : elements;
  40.     }

  41.     public int getTotalNumberOfElements() {
  42.         
  43.         return totalElements;
  44.     }

  45.     public int getThisPageFirstElementNumber() {
  46.         
  47.         return getPageNumber() * getPageSize() + 1;
  48.     }

  49.     public int getThisPageLastElementNumber() {
  50.         
  51.         int fullPage = getThisPageFirstElementNumber() + getPageSize() - 1;
  52.         return getTotalNumberOfElements() < fullPage ? getTotalNumberOfElements() : fullPage;
  53.     }

  54.     public int getNextPageNumber() {
  55.         
  56.         return getPageNumber() + 1;
  57.     }

  58.     public int getPreviousPageNumber() {
  59.         
  60.         return getPageNumber() - 1;
  61.     }

  62.     public int getPageSize() {
  63.         
  64.         return pageSize;
  65.     }

  66.     public int getPageNumber() {
  67.         
  68.         return pageNumber;
  69.     }

  70.     public static HibernatePage getScrollPage(Query query, int pageNumber, int pageSize, ScrollMode scrollMode) {
  71.         
  72.         HibernatePage sp = new HibernatePage(pageNumber, pageSize);
  73.         try {
  74.             sp.scrollableResults = query.scroll(scrollMode);
  75.             if(scrollMode == ScrollMode.SCROLL_SENSITIVE){
  76.                 sp.scrollableResults.last();
  77.                 sp.totalElements = sp.scrollableResults.getRowNumber();
  78.             } else {
  79.                 sp.totalElements = sp.calculateTotalElementsByList(query);
  80.             }
  81.             sp.determineElements(query);
  82.         } catch (HibernateException e) {
  83.             e.printStackTrace();
  84.         }
  85.         return sp;
  86.     }

  87.     private void determineElements(Query query) throws HibernateException {

  88.         if (Integer.MAX_VALUE == this.pageNumber) this.pageNumber = (getTotalNumberOfElements() / this.pageSize);
  89.         elements = query.setFirstResult(this.pageNumber * this.pageSize).setMaxResults(this.pageSize + 1).list();
  90.     }

  91.     private int calculateTotalElementsByList(Query query) throws HibernateException {
  92.         
  93.         return query.list().size();
  94.     }
  95. }

简单分析一下:

ListPage实现需要把查询的结果集全部取出来。

我们着重还是分析一下HibernatePage的实现。

测试代码如下:

  1. import java.io.IOException;
  2. import java.sql.SQLException;
  3. import java.util.List;

  4. import org.hibernate.Query;
  5. import org.hibernate.ScrollMode;
  6. import org.hibernate.Session;
  7. import org.hibernate.SessionFactory;
  8. import org.hibernate.cfg.AnnotationConfiguration;
  9. import org.hibernate.cfg.Configuration;

  10. import org.domain.scrm4u.helper.Page;
  11. import org.domain.scrm4u.helper.impl.HibernatePage;
  12. import org.domain.scrm4u.entity.TPsn;

  13. public class BusinessService {

  14.     public static void main(String[] args) throws IOException, SQLException {
  15.         
  16.         Configuration config =  new AnnotationConfiguration().configure();
  17.         SessionFactory sessionFactory = config.buildSessionFactory();      
  18.         
  19.         Session session = sessionFactory.openSession();

  20.         String Hql = "from TPsn";
  21.         Query query = session.createQuery(Hql);
  22.         
  23.         Page page = HibernatePage.getScrollPage(query, 010ScrollMode.SCROLL_SENSITIVE);
  24.         List<?> list = page.getThisPageElements();
  25.         for (int i = 0; i < list.size(); i++) {
  26.             TPsn psn = (TPsn)list.get(i);
  27.             System.out.println(psn.getPsnNo() + "\t" + psn.getPsnPnm() + "\t" + psn.getPsnBrthDt());
  28.         }  
  29.         
  30.         session.close();
  31.         sessionFactory.close();
  32.     }
  33. }

测试中发现:

使用ScrollMode.SCROLL_SENSITIVEScrollMode.FORWARD_ONLY在性能上要快很多。具体选择要看使用的JDBC驱动是否支撑了,支持scroll的话就可以使用ScrollableResults类来处理结果集了。

 

当然,我们还可以配合缓存技术让翻页更有效率。



ExtJS教程- Hibernate教程-Struts2 教程-Lucene教程