参考资料:
http://blog.csdn.net/zhjb1025/archive/2006/04/19/668631.aspx
http://www.cnblogs.com/HuaiHuai/archive/2005/08/09/211062.html
整理的代码如下:
Page.java接口
- package org.domain.scrm4u.helper;
- import java.util.List;
- public interface Page {
- boolean isFirstPage();
- boolean isLastPage();
- boolean hasNextPage();
- boolean hasPreviousPage();
- int getLastPageNumber();
- List<?> getThisPageElements();
- int getTotalNumberOfElements();
- int getThisPageFirstElementNumber();
- int getThisPageLastElementNumber();
- int getNextPageNumber();
- int getPreviousPageNumber();
- int getPageSize();
- int getPageNumber();
- }
ListPage.java实现:
- package org.domain.scrm4u.helper.impl;
- import java.util.List;
- import org.domain.scrm4u.helper.Page;
- public class ListPage implements Page {
- private List<?> elements;
- private int pageSize;
- private int pageNumber;
- public ListPage(List<?> elements, int pageNumber, int pageSize) {
- this.elements = elements;
- this.pageSize = pageSize;
- this.pageNumber = pageNumber;
- if (Integer.MAX_VALUE == this.pageNumber) this.pageNumber = (getTotalNumberOfElements() / this.pageSize);
- }
- public boolean isFirstPage() {
- return getPageNumber() == 0;
- }
- public boolean isLastPage() {
- return getPageNumber() >= getLastPageNumber();
- }
- public boolean hasNextPage() {
- return ((getPageNumber() + 1) * getPageSize()) < (getTotalNumberOfElements() + 1);
- }
- public boolean hasPreviousPage() {
- return getPageNumber() > 0;
- }
- public int getLastPageNumber() {
- double totalResults = new Integer(getTotalNumberOfElements()).doubleValue();
- return new Double(Math.floor(totalResults / getPageSize())).intValue();
- }
- public List<?> getThisPageElements() {
- final int start = getPageNumber() * getPageSize();
- return elements.subList(
- Math.min(start, getTotalNumberOfElements() + 1),
- Math.min(start + getPageSize(), getTotalNumberOfElements() + 1)
- );
- }
- public int getTotalNumberOfElements() {
- return elements.size() - 1;
- }
- public int getThisPageFirstElementNumber() {
- return getPageNumber() * getPageSize() + 1;
- }
- public int getThisPageLastElementNumber() {
- int fullPage = getThisPageFirstElementNumber() + getPageSize() - 1;
- return getTotalNumberOfElements() < fullPage ? getTotalNumberOfElements() : fullPage;
- }
- public int getNextPageNumber() {
- return getPageNumber() + 1;
- }
- public int getPreviousPageNumber() {
- return getPageNumber() - 1;
- }
- public int getPageSize() {
- return pageSize;
- }
- public int getPageNumber() {
- return pageNumber;
- }
- }
HibernatePage.java实现:
- package org.domain.scrm4u.helper.impl;
- import java.util.List;
- import org.domain.scrm4u.helper.Page;
- import org.hibernate.HibernateException;
- import org.hibernate.Query;
- import org.hibernate.ScrollMode;
- import org.hibernate.ScrollableResults;
- public class HibernatePage implements Page {
- protected List<?> elements;
- protected int pageSize;
- protected int pageNumber;
- protected int totalElements = 0;
- private ScrollableResults scrollableResults;
- private HibernatePage(int pageNumber, int pageSize) {
- this.pageNumber = pageNumber;
- this.pageSize = pageSize;
- }
- public boolean isFirstPage() {
- return getPageNumber() == 0;
- }
- public boolean isLastPage() {
- return getPageNumber() >= getLastPageNumber();
- }
- public boolean hasNextPage() {
- return elements.size() > getPageSize();
- }
- public boolean hasPreviousPage() {
- return getPageNumber() > 0;
- }
- public int getLastPageNumber() {
- double totalResults = new Integer(getTotalNumberOfElements()).doubleValue();
- return new Double(Math.floor(totalResults / getPageSize())).intValue();
- }
- public List<?> getThisPageElements() {
- return hasNextPage() ? elements.subList(0, getPageSize()) : elements;
- }
- public int getTotalNumberOfElements() {
- return totalElements;
- }
- public int getThisPageFirstElementNumber() {
- return getPageNumber() * getPageSize() + 1;
- }
- public int getThisPageLastElementNumber() {
- int fullPage = getThisPageFirstElementNumber() + getPageSize() - 1;
- return getTotalNumberOfElements() < fullPage ? getTotalNumberOfElements() : fullPage;
- }
- public int getNextPageNumber() {
- return getPageNumber() + 1;
- }
- public int getPreviousPageNumber() {
- return getPageNumber() - 1;
- }
- public int getPageSize() {
- return pageSize;
- }
- public int getPageNumber() {
- return pageNumber;
- }
- public static HibernatePage getScrollPage(Query query, int pageNumber, int pageSize, ScrollMode scrollMode) {
- HibernatePage sp = new HibernatePage(pageNumber, pageSize);
- try {
- sp.scrollableResults = query.scroll(scrollMode);
- if(scrollMode == ScrollMode.SCROLL_SENSITIVE){
- sp.scrollableResults.last();
- sp.totalElements = sp.scrollableResults.getRowNumber();
- } else {
- sp.totalElements = sp.calculateTotalElementsByList(query);
- }
- sp.determineElements(query);
- } catch (HibernateException e) {
- e.printStackTrace();
- }
- return sp;
- }
- private void determineElements(Query query) throws HibernateException {
- if (Integer.MAX_VALUE == this.pageNumber) this.pageNumber = (getTotalNumberOfElements() / this.pageSize);
- elements = query.setFirstResult(this.pageNumber * this.pageSize).setMaxResults(this.pageSize + 1).list();
- }
- private int calculateTotalElementsByList(Query query) throws HibernateException {
- return query.list().size();
- }
- }
简单分析一下:
ListPage实现需要把查询的结果集全部取出来。
我们着重还是分析一下HibernatePage的实现。
测试代码如下:
- import java.io.IOException;
- import java.sql.SQLException;
- import java.util.List;
- import org.hibernate.Query;
- import org.hibernate.ScrollMode;
- import org.hibernate.Session;
- import org.hibernate.SessionFactory;
- import org.hibernate.cfg.AnnotationConfiguration;
- import org.hibernate.cfg.Configuration;
- import org.domain.scrm4u.helper.Page;
- import org.domain.scrm4u.helper.impl.HibernatePage;
- import org.domain.scrm4u.entity.TPsn;
- public class BusinessService {
- public static void main(String[] args) throws IOException, SQLException {
- Configuration config = new AnnotationConfiguration().configure();
- SessionFactory sessionFactory = config.buildSessionFactory();
- Session session = sessionFactory.openSession();
- String Hql = "from TPsn";
- Query query = session.createQuery(Hql);
- Page page = HibernatePage.getScrollPage(query, 0, 10, ScrollMode.SCROLL_SENSITIVE);
- List<?> list = page.getThisPageElements();
- for (int i = 0; i < list.size(); i++) {
- TPsn psn = (TPsn)list.get(i);
- System.out.println(psn.getPsnNo() + "/t" + psn.getPsnPnm() + "/t" + psn.getPsnBrthDt());
- }
- session.close();
- sessionFactory.close();
- }
- }
测试中发现:
使用ScrollMode.SCROLL_SENSITIVE比ScrollMode.FORWARD_ONLY在性能上要快很多。具体选择要看使用的JDBC驱动是否支撑了,支持scroll的话就可以使用ScrollableResults类来处理结果集了。
当然,我们还可以配合缓存技术让翻页更有效率。
关于缓存请参看http://blog.csdn.net/kunshan_shenbin/archive/2008/09/03/2874992.aspx。