struts+hibernate分页[转贴]

Hibernate3 提供了DetachedCriteria,使得我们可以在Web层构造detachedCriteria,然后调用业务层Bean,进行动态条件查询,根据这一功能,我设计了通用的抽象Bean基类和分页类支持,代码来自于Quake Wang的javaeye-core包的相应类,然后又做了很多修改。

分页支持类:

java代码:


package com. javaeye. common. util;

import java. util. List;

public class PaginationSupport {

public final static int PAGESIZE = 30;

private int pageSize = PAGESIZE;

private List items;

private int totalCount;

private int [ ] indexes = new int [ 0 ];

private int startIndex = 0;

public PaginationSupport ( List items, int totalCount ) {
setPageSize (PAGESIZE );
setTotalCount (totalCount );
setItems (items );
setStartIndex ( 0 );
}

public PaginationSupport ( List items, int totalCount, int startIndex ) {
setPageSize (PAGESIZE );
setTotalCount (totalCount );
setItems (items );
setStartIndex (startIndex );
}

public PaginationSupport ( List items, int totalCount, int pageSize, int startIndex ) {
setPageSize (pageSize );
setTotalCount (totalCount );
setItems (items );
setStartIndex (startIndex );
}

public List getItems ( ) {
return items;
}

public void setItems ( List items ) {
this. items = items;
}

public int getPageSize ( ) {
return pageSize;
}

public void setPageSize ( int pageSize ) {
this. pageSize = pageSize;
}

public int getTotalCount ( ) {
return totalCount;
}

public void setTotalCount ( int totalCount ) {
if (totalCount > 0 ) {
this. totalCount = totalCount;
int count = totalCount / pageSize;
if (totalCount % pageSize > 0 )
count++;
indexes = new int [count ];
for ( int i = 0; i < count; i++ ) {
indexes [i ] = pageSize * i;
}
} else {
this. totalCount = 0;
}
}

public int [ ] getIndexes ( ) {
return indexes;
}

public void setIndexes ( int [ ] indexes ) {
this. indexes = indexes;
}

public int getStartIndex ( ) {
return startIndex;
}

public void setStartIndex ( int startIndex ) {
if (totalCount <= 0 )
this. startIndex = 0;
else if (startIndex >= totalCount )
this. startIndex = indexes [indexes. length - 1 ];
else if (startIndex < 0 )
this. startIndex = 0;
else {
this. startIndex = indexes [startIndex / pageSize ];
}
}

public int getNextIndex ( ) {
int nextIndex = getStartIndex ( ) + pageSize;
if (nextIndex >= totalCount )
return getStartIndex ( );
else
return nextIndex;
}

public int getPreviousIndex ( ) {
int previousIndex = getStartIndex ( ) - pageSize;
if (previousIndex < 0 )
return 0;
else
return previousIndex;
}

}



抽象业务类
java代码:


/**
* Created on 2005-7-12
*/

package com. javaeye. common. business;

import java. io. Serializable;
import java. util. List;

import org. hibernate. Criteria;
import org. hibernate. HibernateException;
import org. hibernate. Session;
import org. hibernate. criterion. DetachedCriteria;
import org. hibernate. criterion. Projections;
import org. springframework. orm. hibernate3. HibernateCallback;
import org. springframework. orm. hibernate3. support. HibernateDaoSupport;

import com. javaeye. common. util. PaginationSupport;

public abstract class AbstractManager extends HibernateDaoSupport {

private boolean cacheQueries = false;

private String queryCacheRegion;

public void setCacheQueries ( boolean cacheQueries ) {
this. cacheQueries = cacheQueries;
}

public void setQueryCacheRegion ( String queryCacheRegion ) {
this. queryCacheRegion = queryCacheRegion;
}

public void save ( final Object entity ) {
getHibernateTemplate ( ). save (entity );
}

public void persist ( final Object entity ) {
getHibernateTemplate ( ). save (entity );
}

public void update ( final Object entity ) {
getHibernateTemplate ( ). update (entity );
}

public void delete ( final Object entity ) {
getHibernateTemplate ( ). delete (entity );
}

public Object load ( final Class entity, final Serializable id ) {
return getHibernateTemplate ( ). load (entity, id );
}

public Object get ( final Class entity, final Serializable id ) {
return getHibernateTemplate ( ). get (entity, id );
}

public List findAll ( final Class entity ) {
return getHibernateTemplate ( ). find ( "from " + entity. getName ( ) );
}

public List findByNamedQuery ( final String namedQuery ) {
return getHibernateTemplate ( ). findByNamedQuery (namedQuery );
}

public List findByNamedQuery ( final String query, final Object parameter ) {
return getHibernateTemplate ( ). findByNamedQuery (query, parameter );
}

public List findByNamedQuery ( final String query, final Object [ ] parameters ) {
return getHibernateTemplate ( ). findByNamedQuery (query, parameters );
}

public List find ( final String query ) {
return getHibernateTemplate ( ). find (query );
}

public List find ( final String query, final Object parameter ) {
return getHibernateTemplate ( ). find (query, parameter );
}

public PaginationSupport findPageByCriteria ( final DetachedCriteria detachedCriteria ) {
return findPageByCriteria (detachedCriteria, PaginationSupport. PAGESIZE, 0 );
}

public PaginationSupport findPageByCriteria ( final DetachedCriteria detachedCriteria, final int startIndex ) {
return findPageByCriteria (detachedCriteria, PaginationSupport. PAGESIZE, startIndex );
}

public PaginationSupport findPageByCriteria ( final DetachedCriteria detachedCriteria, final int pageSize,
final int startIndex ) {
return (PaginationSupport ) getHibernateTemplate ( ). execute ( new HibernateCallback ( ) {
public Object doInHibernate (Session session ) throws HibernateException {
Criteria criteria = detachedCriteria. getExecutableCriteria (session );
int totalCount = ( ( Integer ) criteria. setProjection (Projections. rowCount ( ) ). uniqueResult ( ) ). intValue ( );
criteria. setProjection ( null );
List items = criteria. setFirstResult (startIndex ). setMaxResults (pageSize ). list ( );
PaginationSupport ps = new PaginationSupport (items, totalCount, pageSize, startIndex );
return ps;
}
}, true );
}

public List findAllByCriteria ( final DetachedCriteria detachedCriteria ) {
return ( List ) getHibernateTemplate ( ). execute ( new HibernateCallback ( ) {
public Object doInHibernate (Session session ) throws HibernateException {
Criteria criteria = detachedCriteria. getExecutableCriteria (session );
return criteria. list ( );
}
}, true );
}

public int getCountByCriteria ( final DetachedCriteria detachedCriteria ) {
Integer count = ( Integer ) getHibernateTemplate ( ). execute ( new HibernateCallback ( ) {
public Object doInHibernate (Session session ) throws HibernateException {
Criteria criteria = detachedCriteria. getExecutableCriteria (session );
return criteria. setProjection (Projections. rowCount ( ) ). uniqueResult ( );
}
}, true );
return count. intValue ( );
}
}




用户在web层构造查询条件detachedCriteria,和可选的startIndex,调用业务bean的相应findByCriteria方法,返回一个PaginationSupport的实例ps。

ps.getItems()得到已分页好的结果集
ps.getIndexes()得到分页索引的数组
ps.getTotalCount()得到总结果数
ps.getStartIndex()当前分页索引
ps.getNextIndex()下一页索引
ps.getPreviousIndex()上一页索引






连续看了两篇robbin有关DetachedCriteria的介绍,感觉真的不错,尤其是上面的示例代码,让我着实觉得该对我原来的分页查询做一下代码重构了。

我把原本我的做法也提供出来供大家讨论吧:

首先,为了实现分页查询,我封装了一个Page类:
java代码:


/*Created on 2005-4-14*/
package org. flyware. util. page;

/**
* @author Joa
*
*/

public class Page {

/** imply if the page has previous page */
private boolean hasPrePage;

/** imply if the page has next page */
private boolean hasNextPage;

/** the number of every page */
private int everyPage;

/** the total page number */
private int totalPage;

/** the number of current page */
private int currentPage;

/** the begin index of the records by the current query */
private int beginIndex;


/** The default constructor */
public Page ( ) {

}

/** construct the page by everyPage
* @param everyPage
* */

public Page ( int everyPage ) {
this. everyPage = everyPage;
}

/** The whole constructor */
public Page ( boolean hasPrePage, boolean hasNextPage,
int everyPage, int totalPage,
int currentPage, int beginIndex ) {
this. hasPrePage = hasPrePage;
this. hasNextPage = hasNextPage;
this. everyPage = everyPage;
this. totalPage = totalPage;
this. currentPage = currentPage;
this. beginIndex = beginIndex;
}

/**
* @return
* Returns the beginIndex.
*/

public int getBeginIndex ( ) {
return beginIndex;
}

/**
* @param beginIndex
* The beginIndex to set.
*/

public void setBeginIndex ( int beginIndex ) {
this. beginIndex = beginIndex;
}

/**
* @return
* Returns the currentPage.
*/

public int getCurrentPage ( ) {
return currentPage;
}

/**
* @param currentPage
* The currentPage to set.
*/

public void setCurrentPage ( int currentPage ) {
this. currentPage = currentPage;
}

/**
* @return
* Returns the everyPage.
*/

public int getEveryPage ( ) {
return everyPage;
}

/**
* @param everyPage
* The everyPage to set.
*/

public void setEveryPage ( int everyPage ) {
this. everyPage = everyPage;
}

/**
* @return
* Returns the hasNextPage.
*/

public boolean getHasNextPage ( ) {
return hasNextPage;
}

/**
* @param hasNextPage
* The hasNextPage to set.
*/

public void setHasNextPage ( boolean hasNextPage ) {
this. hasNextPage = hasNextPage;
}

/**
* @return
* Returns the hasPrePage.
*/

public boolean getHasPrePage ( ) {
return hasPrePage;
}

/**
* @param hasPrePage
* The hasPrePage to set.
*/

public void setHasPrePage ( boolean hasPrePage ) {
this. hasPrePage = hasPrePage;
}

/**
* @return Returns the totalPage.
*
*/

public int getTotalPage ( ) {
return totalPage;
}

/**
* @param totalPage
* The totalPage to set.
*/

public void setTotalPage ( int totalPage ) {
this. totalPage = totalPage;
}

}



上面的这个Page类对象只是一个完整的Page描述,接下来我写了一个PageUtil,负责对Page对象进行构造:
java代码:


/*Created on 2005-4-14*/
package org. flyware. util. page;

import org. apache. commons. logging. Log;
import org. apache. commons. logging. LogFactory;

/**
* @author Joa
*
*/

public class PageUtil {

private static final Log logger = LogFactory. getLog (PageUtil. class );

/**
* Use the origin page to create a new page
* @param page
* @param totalRecords
* @return
*/

public static Page createPage (Page page, int totalRecords ) {
return createPage (page. getEveryPage ( ), page. getCurrentPage ( ), totalRecords );
}

/**
* the basic page utils not including exception handler
* @param everyPage
* @param currentPage
* @param totalRecords
* @return page
*/

public static Page createPage ( int everyPage, int currentPage, int totalRecords ) {
everyPage = getEveryPage (everyPage );
currentPage = getCurrentPage (currentPage );
int beginIndex = getBeginIndex (everyPage, currentPage );
int totalPage = getTotalPage (everyPage, totalRecords );
boolean hasNextPage = hasNextPage (currentPage, totalPage );
boolean hasPrePage = hasPrePage (currentPage );

return new Page (hasPrePage, hasNextPage,
everyPage, totalPage,
currentPage, beginIndex );
}

private static int getEveryPage ( int everyPage ) {
return everyPage == 0 ? 10 : everyPage;
}

private static int getCurrentPage ( int currentPage ) {
return currentPage == 0 ? 1 : currentPage;
}

private static int getBeginIndex ( int everyPage, int currentPage ) {
return (currentPage - 1 ) * everyPage;
}

private static int getTotalPage ( int everyPage, int totalRecords ) {
int totalPage = 0;

if (totalRecords % everyPage == 0 )
totalPage = totalRecords / everyPage;
else
totalPage = totalRecords / everyPage + 1 ;

return totalPage;
}

private static boolean hasPrePage ( int currentPage ) {
return currentPage == 1 ? false : true;
}

private static boolean hasNextPage ( int currentPage, int totalPage ) {
return currentPage == totalPage || totalPage == 0 ? false : true;
}


}



上面的这两个对象与具体的业务逻辑无关,可以独立和抽象。

面对一个具体的业务逻辑:分页查询出User,每页10个结果。具体做法如下:
1. 编写一个通用的结果存储类Result,这个类包含一个Page对象的信息,和一个结果集List:
java代码:


/*Created on 2005-6-13*/
package com. adt. bo;

import java. util. List;

import org. flyware. util. page. Page;

/**
* @author Joa
*/

public class Result {

private Page page;

private List content;

/**
* The default constructor
*/

public Result ( ) {
super ( );
}

/**
* The constructor using fields
*
* @param page
* @param content
*/

public Result (Page page, List content ) color: rgb(0,
分享到:
评论
z75148885
  • 浏览: 86386 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

你可能感兴趣的:(apache,Hibernate,bean,struts,orm)