该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2005-08-30
看了robbin和downpour的文章,感觉非常棒,我就拿来试试.
个人觉得DetachedCriteria的动态查询(QBC)还是优于HQL的,所以觉得采用QBC来进行查询.但是downpour的层次性好,而且把page分页类的初始化和操作分开,将页面对象化,那么涉及到页面的时候只要传一个page对象,至于内部page是如何的可以不用管了,又更好的封装性.但是从算法而言,两位牛人的应该是一样的. 所以我想把两个结合一下,利用downpour GG的层次结构,用QBC(DetachedCriteria)查询条件...前面的原封不动,只要在DAO实现这里修改一下就行了.但是具体实现有问题,我是个初学者,对这些东西的原理还不是很清楚. /*Created on 2005-7-15*/ package com.adt.dao.impl; import java.util.List; import org.flyware.util.page.Page; import net.sf.hibernate.HibernateException; import net.sf.hibernate.Query; import com.adt.dao.UserDAO; /** * @author Joa */ public class UserDAOImpl extends BaseDAOHibernateImpl implements UserDAO { /* (non-Javadoc); * @see com.adt.dao.UserDAO#getUserByName(java.lang.String); */ public List getUserByName(String name); throws HibernateException { String querySentence = "FROM user in class com.adt.po.User WHERE user.name=:name"; Query query = getSession();.createQuery(querySentence);; query.setParameter("name", name);; return query.list();; } /* (non-Javadoc); * @see com.adt.dao.UserDAO#getUserCount(); */ public int getUserCount(); throws HibernateException { int count = 0; String querySentence = "SELECT count(*); FROM user in class com.adt.po.User"; Query query = getSession();.createQuery(querySentence);; count = ((Integer);query.iterate();.next(););.intValue();; return count; } /* (non-Javadoc); * @see com.adt.dao.UserDAO#getUserByPage(org.flyware.util.page.Page); */ public List getUserByPage(Page page); throws HibernateException { String querySentence = "FROM user in class com.adt.po.User"; Query query = getSession();.createQuery(querySentence);; query.setFirstResult(page.getBeginIndex();); .setMaxResults(page.getEveryPage(););; return query.list();; } } 下面是我写的一点,把上面的HQL转换成QBC..很明显有问题,希望懂的达人帮忙给我看看 public List getStudentByPage(Page page); throws HibernateException { //HQL实现 String querySentence = "FROM user in class com.adt.po.User"; Query query = getSession();.createQuery(querySentence);; //DetachedCriteria实现 //处理JSF参数 studentId = FacesUtils.getRequestParameter("query:stuId");; studentName = FacesUtils.getRequestParameter("query:stuName");; studentSex = FacesUtils.getRequestParameter("query:sex");; studentDegree = FacesUtils.getRequestParameter("query:degree");; studentProvince = FacesUtils.getRequestParameter("query:province");; this.logger.debug("------------studentName----> "+ studentId);; this.logger.debug("------------studentName----> "+ studentName);; this.logger.debug("------------studentName----> "+ studentSex);; this.logger.debug("------------studentName----> "+ studentDegree);; this.logger.debug("------------studentName----> "+ studentProvince);; //设置页面 int pageSize = 10; int startIndex = 0; //构造DetachedCriteria DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Student.class);; detachedCriteria.add(Restrictions.eq("stuName", studentName););; Criteria criteria = null;//这里不知道怎么写,肯定不是这样写的 criteria.setFirstResult(page.getBeginIndex();); .setMaxResults(page.getEveryPage(););; return criteria.list();; } Criteria criteria = null;//这里该怎么写???在看到的资料都要涉及到session...DetachedCriteria好像没setFirstResult和setMaxResults..如何讲Criteria和DetachedCriteria联系起来,还是有其他的方法写这个??? |
|
返回顶楼 | |
发表时间:2005-08-30
我也用了robbin的方法来做,直接QBC查询
在bean里面的action里实现分页 public String queryAction();{ this.logger.debug("get into queryAction!!!!!!!!!");; try{ //处理JSF参数 studentId = FacesUtils.getRequestParameter("query:stuId");; studentName = FacesUtils.getRequestParameter("query:stuName");; studentSex = FacesUtils.getRequestParameter("query:sex");; studentDegree = FacesUtils.getRequestParameter("query:degree");; studentProvince = FacesUtils.getRequestParameter("query:province");; this.logger.debug("------------studentName----> "+ studentId);; this.logger.debug("------------studentName----> "+ studentName);; this.logger.debug("------------studentName----> "+ studentSex);; this.logger.debug("------------studentName----> "+ studentDegree);; this.logger.debug("------------studentName----> "+ studentProvince);; //设置页面 int pageSize = 10; int startIndex = 0; //构造DetachedCriteria DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Student.class);; detachedCriteria.add(Restrictions.eq("stuName", studentName););; // //直接查询 // PaginationSupport ps = AbstractManager.findPageByCriteria(DetachedCriteria // .forClass(Student.class);, PageUtil.getEveryPage(pageSize);, PageUtil.getBeginIndex(startIndex););; PaginationSupport ps = AbstractManager.findPageByCriteria(detachedCriteria, pageSize, startIndex);; ps.getItems();; //得到已分页好的结果集 ps.getIndexes();; //得到分页索引的数组 ps.getTotalCount();; //得到总结果数 ps.getStartIndex();; //当前分页索引 ps.getNextIndex();; //下一页索引 ps.getPreviousIndex();; //上一页索引 //调用service List listStu = this.serviceLocator.getStudentService();.getStudents(detachedCriteria);; //List listStu = this.serviceLocator.getStudentService();.findStudent(stuId,stuName);; // this.logger.debug("listStu.size(); = "+ listStu.size(); );; //处理返回的纪录集 for (int i=0; i<listStu.size();; i++); { Student stu = (Student);listStu.get(i);; StudentBean studentBean = StudentBuilder.createStudentBean(stu);; studentBean.setServiceLocator(this.serviceLocator);; this.studentBeans.add(studentBean);; this.logger.debug("listStu==i= "+i );; } }catch (AppException ce); { String msg = "Could not retrieve Students " ; this.logger.debug(msg, ce);; throw new FacesException(msg, ce);; } return "QUERY_SUCCESS" ; } PaginationSupport ps = AbstractManager.findPageByCriteria(detachedCriteria, pageSize, startIndex);;这里说返回类型不对,static和non-static..应该是返回的类型不对吧... 这个有问题吗??有什么不规范和不对的地方吗???? |
|
返回顶楼 | |
发表时间:2005-09-19
/** * 分页信息接口 */ public interface Page <E>extends Serializable,Iterable { /** * 是否是首页(第一页),第一页页码为1 * * @return 首页标识 */ public boolean isFirstPage();; /** * 是否是最后一页 * * @return 末页标识 */ public boolean isLastPage();; /** * 是否有下一页 * * @return 下一页标识 */ public boolean hasNextPage();; /** * 是否有上一页 * * @return 上一页标识 */ public boolean hasPreviousPage();; /** * 获取最后一页页码,也就是总页数 * * @return 最后一页页码 */ public int getLastPageNumber();; /** * 当前页包含的数据,不同的情况可能返回的数据类型不一样,如List,RowSet等,请参考具体的实现 * * @return 当前页数据源 */ public E getThisPageElements();; /** * 总的数据条目数量,0表示没有数据 * * @return 总数量 */ public int getTotalNumberOfElements();; /** * 获取当前页的首条数据的行编码 * * @return 当前页的首条数据的行编码 */ public int getThisPageFirstElementNumber();; /** * 获取当前页的末条数据的行编码 * * @return 当前页的末条数据的行编码 */ public int getThisPageLastElementNumber();; /** * 获取下一页编码 * * @return 下一页编码 */ public int getNextPageNumber();; /** * 获取上一页编码 * * @return 上一页编码 */ public int getPreviousPageNumber();; /** * 每一页显示的条目数 * * @return 每一页显示的条目数 */ public int getPageSize();; /** * 当前页的页码 * * @return 当前页的页码 */ public int getThisPageNumber();; } BasePage用于其它的page子类继承 /** * 高层的Page接口实现 * * @author QIU */ public class BasePage<E> implements Page { protected E elements; protected int pageSize; protected int pageNumber; protected int totalElements = 0; public BasePage(int pageNumber, int pageSize, int totalElements); { this.pageNumber = pageNumber; this.pageSize = pageSize; this.totalElements = totalElements; recomputePageNumber();; } public BasePage(int pageNumber, int pageSize); { this.pageNumber = pageNumber; this.pageSize = pageSize; } /** * 重新计算当前页的号码 */ protected void recomputePageNumber(); { if (Integer.MAX_VALUE == this.pageNumber || this.pageNumber > getLastPageNumber();); { //last page this.pageNumber = getLastPageNumber();; } } public boolean isFirstPage(); { return getThisPageNumber(); == 1; } public boolean isLastPage(); { return getThisPageNumber(); >= getLastPageNumber();; } public boolean hasNextPage(); { return getLastPageNumber(); > getThisPageNumber();; } public boolean hasPreviousPage(); { return getThisPageNumber(); > 1; } public int getLastPageNumber(); { return totalElements % this.pageSize == 0 ? totalElements/ this.pageSize : totalElements / this.pageSize + 1; } public E getThisPageElements(); { return elements; } public int getTotalNumberOfElements(); { return totalElements; } public int getThisPageFirstElementNumber(); { return (getThisPageNumber(); - 1); * getPageSize(); + 1; } public int getThisPageLastElementNumber(); { int fullPage = getThisPageFirstElementNumber(); + getPageSize(); - 1; return getTotalNumberOfElements(); < fullPage ? getTotalNumberOfElements(); : fullPage; } public int getNextPageNumber(); { return getThisPageNumber(); + 1; } public int getPreviousPageNumber(); { return getThisPageNumber(); - 1; } public int getPageSize(); { return pageSize; } public int getThisPageNumber(); { return pageNumber; } /** * 实现Iterable遍历接口 * @return 等价((Iterable);getThisPageElements(););.iterator(); * @throws UnsupportedOperationException * 当getThisPageElements();不是Iterable接口 * @See java.lang.Iterable */ public Iterator iterator(); { if(getThisPageElements(); instanceof Iterable); { return ((Iterable);getThisPageElements(););.iterator();; } else { throw new UnsupportedOperationException("iterator(); method is unsupported");; } } } 现在我们的HibernatePage实现类,只需简单的执行一下查询就行了 /** * Hibernate分页信息 * @see BasePage */ public class HibernatePage extends BasePage implements Page { /** * 构建HibernatePage对象,完成Hibernate的Query数据的分页处理 * * @param query Hibernate的Query对象 * @param pageNumber 当前页编码,从1开始,如果传的值为Integer.MAX_VALUE表示获取最后一页。 * 如果你不知道最后一页编码,传Integer.MAX_VALUE即可。如果当前页超过总页数,也表示最后一页。 * 这两种情况将重新更改当前页的页码,为最后一页编码。 * @param pageSize 每一页显示的条目数 */ public HibernatePage(Query query, int pageNumber, int pageSize); { super(pageNumber,pageSize);; try { ScrollableResults scrollableResults = query.scroll();; //get the total elements number scrollableResults.last();; this.totalElements = scrollableResults.getRowNumber();; recomputePageNumber();; elements = query.setFirstResult((this.pageNumber - 1); * this.pageSize);.setMaxResults(this.pageSize + 1);.list();; } catch (HibernateException e); { throw new RuntimeException(e);; } } /** * 构建HibernatePage对象,完成Hibernate的Query数据的分页处理 * * @param selectQuery Hibernate的查询Query对象 * @param countQuery Hibernate的查询总数据行数的Query对象 * @param pageNumber 当前页编码,从1开始,如果传的值为Integer.MAX_VALUE表示获取最后一页。 * 如果你不知道最后一页编码,传Integer.MAX_VALUE即可。如果当前页超过总页数,也表示最后一页。 * 这两种情况将重新更改当前页的页码,为最后一页编码。 * @param pageSize 每一页显示的条目数 */ public HibernatePage(Query selectQuery, Query countQuery,int pageNumber, int pageSize); { super(pageNumber,pageSize);; try { //得到总记录数 this.totalElements = ((Integer);countQuery.uniqueResult(););.intValue();; recomputePageNumber();; elements = selectQuery .setFirstResult((this.pageNumber - 1); * this.pageSize); .setMaxResults(this.pageSize + 1); .list();; } catch (HibernateException e); { throw new RuntimeException(e);; } } } EJB3.0的Page接口实现EJBPage /** * EJB分页信息 * @author QIU * @see BasePage */ public class EJBPage extends BasePage { public EJBPage(Query selectQuery,Query countQuery,int pageNumber,int pageSize); { super(pageNumber,pageSize);; this.totalElements = (Integer);countQuery.getSingleResult();; recomputePageNumber();; this.elements = selectQuery .setFirstResult((this.pageNumber - 1); * this.pageSize); .setMaxResults(this.pageSize + 1); .getResultList();; } } |
|
返回顶楼 | |
发表时间:2005-09-19
JDBCPage
/** * Jdbc分页信息,需要Jdk 1.5的支持 * @see Page * @see BasePage */ public class JdbcPage extends BasePage //implements Page { // private CachedRowSet elements; // private int pageSize; // private int pageNumber; // private int totalElements = 0; /** * 构建JdbcPage对象,完成JDBC的ResultSet分页处理 * * @param rs ResultSet对象,ResultSet必须是可滚动的数据集,可以通过以下的Statement执行查询。 * Statement stmt = conn.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); * @param pageNumber 当前页编码,从1开始,如果传的值为Integer.MAX_VALUE表示获取最后一页。 * 如果你不知道最后一页编码,传Integer.MAX_VALUE即可。如果当前页超过总页数,也表示最后一页。 * 这两种情况将重新更改当前页的页码,为最后一页编码。 * @param pageSize 每一页显示的条目数 */ public JdbcPage(ResultSet rs, int pageNumber, int pageSize) { super(pageNumber,pageSize); try { //get the total elements number rs.last(); totalElements = rs.getRow(); // if (this.pageNumber == Integer.MAX_VALUE || this.pageNumber > getLastPageNumber()) // { // this.pageNumber = getLastPageNumber(); // } recomputePageNumber(); CachedRowSet elements = new CachedRowSetImpl(); elements.setMaxRows(this.pageSize); elements.setPageSize(this.pageSize); elements.populate(rs, (this.pageNumber - 1) * this.pageSize); this.elements = elements; } catch (SQLException e) { throw new RuntimeException(e); } } /** * 构建JdbcPage对象,完成JDBC的ResultSet分页处理 * * @param rs ResultSet对象,ResultSet必须是可滚动的数据集,可以通过以下的Statement执行查询。 * Statement stmt = conn.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); * @param pageNumber 当前页编码,从1开始,如果传的值为Integer.MAX_VALUE表示获取最后一页。 * 如果你不知道最后一页编码,传Integer.MAX_VALUE即可。如果当前页超过总页数,也表示最后一页。 * 这两种情况将重新更改当前页的页码,为最后一页编码。 * @param pageSize 每一页显示的条目数 */ public JdbcPage(ResultSet rs,BusinessObjectCreator creator, int pageNumber, int pageSize) { super(pageNumber,pageSize); try { //get the total elements number rs.last(); totalElements = rs.getRow(); recomputePageNumber(); this.elements = populateIntoList(rs,creator,pageNumber,pageSize); } catch (SQLException e){ throw new RuntimeException(e); } } private static List populateIntoList(ResultSet rs, BusinessObjectCreator factory, int pageNumber, int pageSize) throws SQLException { List result = new ArrayList(); //移动到页码的第一条记录,忽略第一页 if(pageNumber>1){ rs.absolute(((pageNumber-1)*pageSize)); } for(int i=0;i<pageSize;i++){ if(rs.next()){ result.add(factory.getBusinessObject(rs)); } else{ if(i==0){ //没有记录的情况 return null; } break; } } return result; } } BusinessObjectCreator接口 /** * 业务对象创建接口,用于JDBCPage创建对象方法回调 * @author QIU * */ public interface BusinessObjectCreator { public Object getBusinessObject(ResultSet rs);; } |
|
返回顶楼 | |
发表时间:2005-09-20
/** * Hibernate使用Criteria分页信息 * @author QIU * */ public class CriteriaPage extends BasePage{ public CriteriaPage(Criteria criteria,int pageNumber, int pageSize); { super(pageNumber,pageSize);; //得到总记录数 ScrollableResults scrollableResults = criteria.scroll();; scrollableResults.last();; this.totalElements = scrollableResults.getRowNumber();; recomputePageNumber();; elements = criteria .setFirstResult((this.pageNumber - 1); * this.pageSize); .setMaxResults(this.pageSize + 1);.list();; } } 重贴JdbcPage /** * Jdbc分页信息,需要Jdk 1.5的支持 * @see Page * @see BasePage */ public class JdbcPage extends BasePage //implements Page { // private CachedRowSet elements; // private int pageSize; // private int pageNumber; // private int totalElements = 0; /** * 构建JdbcPage对象,完成JDBC的ResultSet分页处理 * * @param rs ResultSet对象,ResultSet必须是可滚动的数据集,可以通过以下的Statement执行查询。 * Statement stmt = conn.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);; * @param pageNumber 当前页编码,从1开始,如果传的值为Integer.MAX_VALUE表示获取最后一页。 * 如果你不知道最后一页编码,传Integer.MAX_VALUE即可。如果当前页超过总页数,也表示最后一页。 * 这两种情况将重新更改当前页的页码,为最后一页编码。 * @param pageSize 每一页显示的条目数 */ public JdbcPage(ResultSet rs, int pageNumber, int pageSize); { super(pageNumber,pageSize);; try { //get the total elements number rs.last();; totalElements = rs.getRow();; // if (this.pageNumber == Integer.MAX_VALUE || this.pageNumber > getLastPageNumber();); // { // this.pageNumber = getLastPageNumber();; // } recomputePageNumber();; CachedRowSet elements = new CachedRowSetImpl();; elements.setMaxRows(this.pageSize);; elements.setPageSize(this.pageSize);; elements.populate(rs, (this.pageNumber - 1); * this.pageSize);; this.elements = elements; } catch (SQLException e); { throw new RuntimeException(e);; } } /** * 构建JdbcPage对象,完成JDBC的ResultSet分页处理 * * @param rs ResultSet对象,ResultSet必须是可滚动的数据集,可以通过以下的Statement执行查询。 * Statement stmt = conn.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);; * @param pageNumber 当前页编码,从1开始,如果传的值为Integer.MAX_VALUE表示获取最后一页。 * 如果你不知道最后一页编码,传Integer.MAX_VALUE即可。如果当前页超过总页数,也表示最后一页。 * 这两种情况将重新更改当前页的页码,为最后一页编码。 * @param pageSize 每一页显示的条目数 */ public JdbcPage(ResultSet rs,BusinessObjectCreator creator, int pageNumber, int pageSize); { super(pageNumber,pageSize);; try { //get the total elements number rs.last();; totalElements = rs.getRow();; recomputePageNumber();; this.elements = populateIntoList(rs,creator,pageNumber,pageSize);; } catch (SQLException e);{ throw new RuntimeException(e);; } } private static List populateIntoList(ResultSet rs, BusinessObjectCreator factory, int pageNumber, int pageSize); throws SQLException { List result = new ArrayList();; //移动到页码的第一条记录,忽略第一页 if(pageNumber>1);{ rs.absolute(((pageNumber-1);*pageSize););; } for(int i=0;i<pageSize;i++);{ if(rs.next(););{ result.add(factory.getBusinessObject(rs););; } else{ if(i==0);{ //没有记录的情况 return null; } break; } } return result; } } /** * 业务对象创建接口,用于JDBCPage创建对象方法回调 * @author QIU * */ public interface BusinessObjectCreator { public Object getBusinessObject(ResultSet rs);; } 其它的Page接口实现,我们只需简单的继承BasePage,轻松的就可以增加对Page的实现.Page接口详细可以查看Hibernate官网上的描述 |
|
返回顶楼 | |
发表时间:2005-09-21
用
ScrollableResults scrollableResults = query.scroll(); //get the total elements number scrollableResults.last(); this.totalElementsCount = scrollableResults.getRowNumber() + 1; 我使用oracle9i + oracle10 jdbc driver, 在数据量大的情况下,会有outofmemery exception的 |
|
返回顶楼 | |
发表时间:2005-10-18
今天试了一下robbin的分页方法,发现一个问题
方法代码: 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();; [b]criteria.setProjection(null);;[/b] List items = criteria.setFirstResult(startIndex);.setMaxResults(pageSize);.list();; PaginationSupport ps = new PaginationSupport(items, totalCount, pageSize, startIndex);; return ps; } }, true);; } 调用代码: DetachedCriteria dc=DetachedCriteria .forClass(Cat.class);; dc.createAlias("mate","mt"); .add(Property.forName("mt.name");.like("miaomiao",MatchMode.ANYWHERE););; PaginationSupport ps = findPageByCriteria(dc,20,0);; List list = ps.getItems();; [b]Object[] objects = Object[] list.get(0);;[/b] 发现返回的List里面放的不是我本来想要的Cat, 而是Object[]. |
|
返回顶楼 | |
发表时间:2005-10-18
经过测试,看来问题出在 criteria.setProjection(null); 上。
|
|
返回顶楼 | |
发表时间:2005-12-23
有没有解决方案啊?
|
|
返回顶楼 | |
发表时间:2005-12-23
goldapple 写道 有没有解决方案啊?
package com.skyon.cams.util; import java.lang.reflect.Field; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.Criteria; import org.hibernate.HibernateException; import org.hibernate.Session; import org.hibernate.criterion.CriteriaSpecification; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Projection; import org.hibernate.criterion.Projections; import org.hibernate.impl.CriteriaImpl; import org.hibernate.impl.CriteriaImpl.OrderEntry; import org.springframework.dao.DataAccessException; import org.springframework.orm.hibernate3.HibernateCallback; import org.springframework.orm.hibernate3.HibernateTemplate; import org.springframework.util.Assert; import com.skyon.framework.core.SkyonException; import com.skyon.framework.dao.PaginationSupport; /** * 一些常用的 Hibernate 方法, 注意, 一些方法可能只适用于 Hibernate3.0.5 !!! * @see org.springframework.orm.hibernate3.HibernateTemplate * @since 2005-9-13 * @author 王政 * @version $Id: HibernateUtils.java,v 1.4 2005/09/19 01:00:28 wangzheng Exp $ */ public abstract class HibernateUtils { private static Log logger = LogFactory.getLog(HibernateUtils.class);; public static final String CRITERIA_ASSERT_ERROR_MESSAGE = " 's type is not " + CriteriaImpl.class + ", please make sure you are using Hibernate3.0.5!!! "; /** * 将 Criteria 加上分页条件并输出结果 * @param criteria the criteria * @param offset the offset * @param maxPageItems the maxPageItems * @return the result list */ public static List getPageResult(Criteria criteria, int offset, int maxPageItems); throws HibernateException { criteria.setFirstResult(offset);; criteria.setMaxResults(maxPageItems);; return criteria.list();; } /** * 根据 DetachedCriteria 得 到 分页结果, 运行期间会根据 criteria 自动运算总行数, 注意如果 criteria 中 set 了 Projection, 则返回结果 List 中为 Projection 指定类型 * @param hibernateTemplate the hibernateTemplate * @param criteria the criteria * @param firstResult the first result row number * @param maxResults the max result * @return the pagination support * @throws org.springframework.dao.DataAccessException in case of Hibernate errors */ public static PaginationSupport findByCriteria(HibernateTemplate hibernateTemplate, final DetachedCriteria criteria, final int firstResult, final int maxResults); throws DataAccessException { return (PaginationSupport); hibernateTemplate.execute(new HibernateCallback(); { public Object doInHibernate(Session session); throws HibernateException, SQLException { Criteria executableCriteria = criteria.getExecutableCriteria(session);; // Get the orginal orderEntries OrderEntry[] orderEntries = HibernateUtils.getOrders(executableCriteria);; // Remove the orders executableCriteria = HibernateUtils.removeOrders(executableCriteria);; // get the original projection Projection projection = HibernateUtils.getProjection(executableCriteria);; int totalCount = ((Integer); executableCriteria.setProjection(Projections.rowCount(););.uniqueResult(););.intValue();; executableCriteria.setProjection(projection);; if (projection == null); { // Set the ResultTransformer to get the same object structure with hql executableCriteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);; } // Add the orginal orderEntries executableCriteria = HibernateUtils.addOrders(executableCriteria, orderEntries);; // Now, the Projection and the orderEntries have been resumed List items = HibernateUtils.getPageResult(executableCriteria, firstResult, maxResults);; return new PaginationSupport(items, totalCount, firstResult, maxResults);; } }, true);; } /** * 根据 hql 得 到 总行数 * @param hibernateTemplate * @param queryString hql * @param isNamedQuery 是否是 named query * @param paramNames 如果是 named query, 为 named query 中的参数名称, 否则无意义 * @param paramValues 参数值 * @return 满足条件的总行数 * @throws IllegalArgumentException if queryString is blank * @throws org.springframework.dao.DataAccessException in case of Hibernate errors */ public static int getTotalCount(HibernateTemplate hibernateTemplate, String queryString, boolean isNamedQuery, String[] paramNames, Object[] paramValues); throws IllegalArgumentException, DataAccessException { if (StringUtils.isBlank(queryString);); { throw new IllegalArgumentException(" queryString can't be blank ");; } String countQueryString = " select count (*); " + JdbcUtils.removeSelect(JdbcUtils.removeOrders(queryString););; List countList; if (isNamedQuery); { countList = hibernateTemplate.findByNamedParam(countQueryString, paramNames, paramValues);; } else { countList = hibernateTemplate.find(countQueryString, paramValues);; } return ((Integer); countList.get(0););.intValue();; } /** * 从 criteria 中取得 {@link Projection}, 接口中没有公开此方法, 因此从 {@link CriteriaImpl} 中取得 * @see CriteriaImpl#getProjection(); * @param criteria the criteria * @return the Projection */ public static Projection getProjection(Criteria criteria); { assertType(criteria);; CriteriaImpl impl = (CriteriaImpl); criteria; return impl.getProjection();; } private static void assertType(Criteria criteria); { Assert.notNull(criteria, " criteria is required. ");; String message = criteria + CRITERIA_ASSERT_ERROR_MESSAGE; if (! CriteriaImpl.class.isInstance(criteria);); { if (logger.isDebugEnabled();); { logger.debug(message);; } throw new SkyonException(message);; } } /** * 得到 criteria 中的 OrderEntry[] * @param criteria the criteria * @return the OrderEntry[] */ public static OrderEntry[] getOrders(Criteria criteria); { assertType(criteria);; CriteriaImpl impl = (CriteriaImpl); criteria; Field field = getOrderEntriesField(criteria);; try { return (OrderEntry[]); ((List); field.get(impl););.toArray(new OrderEntry[0]);; } catch (Exception e); { logAndThrowException(criteria, e);; throw new InternalError(" Runtime Exception impossibility can't throw ");; } } /** * 移除 criteria 中的 OrderEntry[] * @param criteria the criteria * @return the criteria after removed OrderEntry[] */ public static Criteria removeOrders(Criteria criteria); { assertType(criteria);; CriteriaImpl impl = (CriteriaImpl); criteria; try { Field field = getOrderEntriesField(criteria);; field.set(impl, new ArrayList(););; return impl; } catch (Exception e); { logAndThrowException(criteria, e);; throw new InternalError(" Runtime Exception impossibility can't throw ");; } } /** * 为 criteria 增加 OrderEntry[] * @param criteria the criteria * @param orderEntries the OrderEntry[] * @return the criteria after add OrderEntry[] */ public static Criteria addOrders(Criteria criteria, OrderEntry[] orderEntries); { assertType(criteria);; CriteriaImpl impl = (CriteriaImpl); criteria; try { Field field = getOrderEntriesField(criteria);; for (int i = 0; i < orderEntries.length; i++); { List innerOrderEntries = (List); field.get(criteria);; innerOrderEntries.add(orderEntries[i]);; } return impl; } catch (Exception e); { logAndThrowException(criteria, e);; throw new InternalError(" Runtime Exception impossibility can't throw ");; } } private static void logAndThrowException(Criteria criteria, Exception e); { String message = criteria + CRITERIA_ASSERT_ERROR_MESSAGE; if (logger.isDebugEnabled();); { logger.debug(message, e);; } throw new SkyonException(message, e);; } private static Field getOrderEntriesField(Criteria criteria); { Assert.notNull(criteria, " criteria is requried. " );; try { Field field = CriteriaImpl.class.getDeclaredField("orderEntries");; field.setAccessible(true);; return field; } catch (Exception e); { logAndThrowException(criteria, e);; throw new InternalError();; } } } |
|
返回顶楼 | |