Hibernate3的DetachedCriteria实现分页查询
2007-08-06 09:47
627 查看
Hibernate3提供了DetachedCriteria,使得我们可以在Web层构造detachedCriteria,然后调用业务层Bean,进行动态条件查询,根据这一功能,我设计了通用的抽象Bean基类和分页类支持,代码来自于Quake Wang的javaeye-core包的相应类,然后又做了很多修改。 分页支持类: java 代码 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(); } } render_code(); 用户在web层构造查询条件detachedCriteria,和可选的startIndex,调用业务bean的相应findByCriteria方法,返回一个PaginationSupport的实例ps。 ps.getItems()得到已分页好的结果集 ps.getIndexes()得到分页索引的数组 ps.getTotalCount()得到总结果数 ps.getStartIndex()当前分页索引 ps.getNextIndex()下一页索引 ps.getPreviousIndex()上一页索引 |
相关文章: Tomcat+Mysql+UltraEdit,10分钟Hibernate初体验 Hibernate Iterator的问题
评论 共 46 条 | 发表评论 |
连续看了两篇robbin有关DetachedCriteria的介绍,感觉真的不错,尤其是上面的示例代码,让我着实觉得该对我原来的分页查询做一下代码重构了。 我把原本我的做法也提供出来供大家讨论吧: 首先,为了实现分页查询,我封装了一个Page类: 代码 代码 /*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; } } render_code(); 上面的这两个对象与具体的业务逻辑无关,可以独立和抽象。 面对一个具体的业务逻辑:分页查询出User,每页10个结果。具体做法如下: 1. 编写一个通用的结果存储类Result,这个类包含一个Page对象的信息,和一个结果集List: 代码 代码 /*Created on 2005-7-15*/ package com.adt.service; import net.sf.hibernate.HibernateException; import org.flyware.util.page.Page; import com.adt.bo.Result; /** * @author Joa */ public interface UserManager { public Result listUser(Page page) throws HibernateException; } render_code(); 代码 代码 /*Created on 2005-7-15*/ package com.adt.dao; import java.util.List; import org.flyware.util.page.Page; import net.sf.hibernate.HibernateException; /** * @author Joa */ public interface UserDAO extends BaseDAO { public List getUserByName(String name) throws HibernateException; public int getUserCount() throws HibernateException; public List getUserByPage(Page page) throws HibernateException; } render_code(); 代码 代码 /*Created on 2005-6-17*/ package com.adt.action.user; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.flyware.util.page.Page; import com.adt.bo.Result; import com.adt.service.UserService; import com.opensymphony.xwork.Action; /** * @author Joa */ public class ListUser implements Action { private static final Log logger = LogFactory.getLog(ListUser.class); private UserService userService; private Page page; private List users; /* * (non-Javadoc) * * @see com.opensymphony.xwork.Action#execute() */ public String execute() throws Exception { Result result = userService.listUser(page); page = result.getPage(); users = result.getContent(); return SUCCESS; } /** * @return Returns the page. */ public Page getPage() { return page; } /** * @return Returns the users. */ public List getUsers() { return users; } /** * @param page * The page to set. */ public void setPage(Page page) { this.page = page; } /** * @param users * The users to set. */ public void setUsers(List users) { this.users = users; } /** * @param userService * The userService to set. */ public void setUserService(UserService userService) { this.userService = userService; } } render_code(); 上面的代码似乎看不出什么地方设置了page的相关初值,事实上,可以通过配置文件来进行配置,例如,我想每页显示10条记录,那么只需要: 代码 <?xml version="1.0"?> <!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "http://www.opensymphony.com/xwork/xwork-1.0.dtd"> <xwork> <package name="user" extends="webwork-interceptors"> <!-- The default interceptor stack name --> <default-interceptor-ref name="myDefaultWebStack"/> <action name="listUser" class="com.adt.action.user.ListUser"> <param name="page.everyPage">10</param> <result name="success">/user/user_list.jsp</result> </action> </package> </xwork> render_code(); 这样就可以通过配置文件和OGNL的共同作用来对page对象设置初值了。并可以通过随意修改配置文件来修改每页需要显示的记录数。 注:上面的<param>的配置,还需要webwork和Spring整合的配合。 |
相关文章推荐
- 应用Hibernate3的DetachedCriteria实现分页查询
- 应用Hibernate3的DetachedCriteria实现分页查询
- 应用Hibernate3的DetachedCriteria实现分页查询
- 应用Hibernate3的DetachedCriteria实现分页查询
- Hibernate里面如何使用DetachedCriteriaCriteria 实现多条件分页查询
- 应用Hibernate3的DetachedCriteria实现分页查询
- 应用Hibernate3的DetachedCriteria实现分页查询 (来自JAVA视线)
- 应用Hibernate3的DetachedCriteria实现分页查询
- Hibernate DetachedCriteria方式分页查询返回总记录数
- 使用Hibernate criteria进行分页查询时,如何实现一次查询取得总记录数和分页后结果集
- 应用Hibernate3的DetachedCriteria实现分页查询
- DetachedCriteria离线查询离线查询---实现模糊查询 Hibernate
- hibernate查询之Criteria实现分页方法(GROOVY语法)
- hibernate查询之Criteria实现分页方法(GROOVY语法)
- 实现Hibernate分页查询原理解读
- Hibernate使用Criteria实现查询
- Hibernate3的动态条件查询DetachedCriteria
- Hibernate中criteria一对多关联查询时distinct的分页和数量问题
- hibernate分页查询的实现
- 灵活使用Hibernate的查询对象DetachedCriteria