Hibernate Criteria分页产生的题目大师都知道做分页必必要知道总记录数,这就为我们出了一到小题儿,往往我们直接用Criteria调用list办法就返回全部查询成果了,然则分页必须在返回列表之前获得总行数。我之前的做法是写两个办法,参数完全一样,一个返回Integer,也就是记录数,一个返回List,成果集。如许写感触感染挺麻烦的,还有人直接用criteria.list()返回记录数,再设置分页属性,那样还叫什么分页啊,调用list已经将数据加载到内存了,那不又成了内存分页,这种做法法度处理惩罚简单了,机能降下来了。
今天在网上闲逛发了然一个新招,代码如下(只贴出回调函数里的代码了):
灰色斜体为营业相干代码,请疏忽
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Criteria criteria = session.createCriteria(XtLog.class);
Criteria userCriteria = criteria.createCriteria("xtUser");
Criteria lcCriteria = criteria.createCriteria("xtLogClass");
if (StringUtils.isNotBlank(userId)) {
userCriteria.add(Restrictions.like("userId", userId, MatchMode.START));
}
if (StringUtils.isNotBlank(logClassId)) {
lcCriteria.add(Restrictions.eq("logClassId", logClassId));
}
if (beginDate != null && endDate != null) {
criteria.add(Restrictions.between("xtOplogtime", beginDate, endDate));
}
int totalRows =((Integer) criteria.setProjection(Projections.rowCount()).uniqueResult()).intValue();
psm.setTotalRows(totalRows); // 营业代码,请疏忽
criteria.setProjection(null);
criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
Map<String, String> orderMap = psm.getOrderMap();
if(orderMap != null){
setOrder(criteria, userCriteria, lcCriteria, orderMap);
}
if(!psm.isAll()){ // 分页
criteria.setFirstResult(psm.getRowStart());
criteria.setMaxResults(psm.getPageSize());
}
// List<XtLog> logs = new ArrayList<XtLog>(); // 返回日记列表
// List<Object[]> list = criteria.list();
// for (Object[] o : list) {
// logs.add((XtLog) o[2]);
// }
// return logs;
return criteria.list();
}
请重视绿色加粗那两行代码,那就是hibernate获取记录总行数的写法,直接和获取列表的办法写在一路,貌似很简洁,很给力,若是你查询的就是一张表,那么没事了,但我查询的日记是要接洽关系到用户和日记分类的,最上方那三行代码就是接洽关系了,这时发明返回到页面后报错了,原因是返回的并不是我要的日记List,而是Object[]的List,每个List里三个对象数组,主表的数组下标是最后一个,这时我就得应用蓝色字体的代码从头封装后返回,我感触感染如许固然解决了该题目,但还是不给力,不完美,不perfect,就是不爽,于是请将重视力转移到红色加粗字体上,写上它就OK了。
1、criteria.setProjection(null);
取得了总数后,为了可以或许再次取得对象列表。
2、detachedCriteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
当hibernate采取接洽关系的时辰不应用这个返回的是个对象数组,加上这个返回的是当前列表的对象。
今天在网上闲逛发了然一个新招,代码如下(只贴出回调函数里的代码了):
灰色斜体为营业相干代码,请疏忽
public Object doInHibernate(Session session) throws HibernateException, SQLException {
Criteria criteria = session.createCriteria(XtLog.class);
Criteria userCriteria = criteria.createCriteria("xtUser");
Criteria lcCriteria = criteria.createCriteria("xtLogClass");
if (StringUtils.isNotBlank(userId)) {
userCriteria.add(Restrictions.like("userId", userId, MatchMode.START));
}
if (StringUtils.isNotBlank(logClassId)) {
lcCriteria.add(Restrictions.eq("logClassId", logClassId));
}
if (beginDate != null && endDate != null) {
criteria.add(Restrictions.between("xtOplogtime", beginDate, endDate));
}
int totalRows =((Integer) criteria.setProjection(Projections.rowCount()).uniqueResult()).intValue();
psm.setTotalRows(totalRows); // 营业代码,请疏忽
criteria.setProjection(null);
criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
Map<String, String> orderMap = psm.getOrderMap();
if(orderMap != null){
setOrder(criteria, userCriteria, lcCriteria, orderMap);
}
if(!psm.isAll()){ // 分页
criteria.setFirstResult(psm.getRowStart());
criteria.setMaxResults(psm.getPageSize());
}
// List<XtLog> logs = new ArrayList<XtLog>(); // 返回日记列表
// List<Object[]> list = criteria.list();
// for (Object[] o : list) {
// logs.add((XtLog) o[2]);
// }
// return logs;
return criteria.list();
}
请重视绿色加粗那两行代码,那就是hibernate获取记录总行数的写法,直接和获取列表的办法写在一路,貌似很简洁,很给力,若是你查询的就是一张表,那么没事了,但我查询的日记是要接洽关系到用户和日记分类的,最上方那三行代码就是接洽关系了,这时发明返回到页面后报错了,原因是返回的并不是我要的日记List,而是Object[]的List,每个List里三个对象数组,主表的数组下标是最后一个,这时我就得应用蓝色字体的代码从头封装后返回,我感触感染如许固然解决了该题目,但还是不给力,不完美,不perfect,就是不爽,于是请将重视力转移到红色加粗字体上,写上它就OK了。
return (PageSupport) getHibernateTemplate().execute(
new HibernateCallback() ...{
public Object doInHibernate(Session session)
throws HibernateException ...{
Criteria criteria = detachedCriteria
.getutableCriteria(session);
CriteriaImpl impl = (CriteriaImpl) criteria;
//先把Projection和OrderBy前提取出来,清空两者来履行Count操纵
Projection projection = impl.getProjection();
logger.debug("SQL: " + Projections.rowCount());
//履行查询
int totalCount = ((Integer) criteria.setProjection(Projections.rowCount()).uniqueResult()).intValue();
//将之前的Projection和OrderBy前提从头设归去
criteria.setProjection(projection);
if (projection == null) ...{
criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
}
List items = criteria.setFirstResult(startIndex)
.setMaxResults(pageSize).list();
PageSupport ps = new PageSupport(items, totalCount,
pageSize, startIndex);
return ps;
}
}, true);
1、criteria.setProjection(null);
取得了总数后,为了可以或许再次取得对象列表。
2、detachedCriteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
当hibernate采取接洽关系的时辰不应用这个返回的是个对象数组,加上这个返回的是当前列表的对象。