`
Hillen.chan
  • 浏览: 62917 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

hibernate分页

阅读更多
这里想说的代码主要是泛型DAO层的应用与分页的写法.

分页,采用了hibernate的一些API来分页,这里同时采用了两种分页方式,CriteriaPage分页方式,适用于多表单时查询后分页用的,而第二种方式是采用Hql语句查询后分页的.代码如下:

CriteriaPage.java文件:
package org.mmc.commons; import java.util.ArrayList;
import java.util.List; import org.hibernate.Criteria;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.impl.CriteriaImpl;
import org.hibernate.impl.CriteriaImpl.OrderEntry;
import org.mmc.utils.BeanUtils; /**
* 使用Hql查询的的分页查询类.
* 支持执行Count查询取得总记录条数
* 本类参考了springside项目的分页设计
*/
public class CriteriaPage { /**
* 得到一个PageInstance实例,.
*/
public static Page getPageInstance(Criteria criteria, int pageNo, int pageSize) {

return CriteriaPage.getPageInstanceByCount(criteria, pageNo, pageSize);
} /**
* 以查询Count的形式获取totalCount的函数
*/
protected static Page getPageInstanceByCount(Criteria criteria, int pageNo, int pageSize) {
CriteriaImpl impl = (CriteriaImpl) criteria; //先把Projection和OrderBy条件取出来,清空两者来执行Count操作
Projection projection = impl.getProjection();
List<OrderEntry> orderEntries;
try {
orderEntries = (List) BeanUtils.getPrivateProperty(impl, "orderEntries");
BeanUtils.setPrivateProperty(impl, "orderEntries", new ArrayList());
}
catch (Exception e) {
throw new InternalError(" Runtime Exception impossibility throw ");
} //执行查询
int totalCount = (Integer) criteria.setProjection(Projections.rowCount()).uniqueResult(); //将之前的Projection和OrderBy条件重新设回去
criteria.setProjection(projection);
if (projection == null) {
criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
} try {
BeanUtils.setPrivateProperty(impl, "orderEntries", orderEntries);
} catch (Exception e) {
throw new InternalError(" Runtime Exception impossibility throw ");
} return getPageResult(criteria, totalCount, pageNo, pageSize);
}

/**
* 取得totalCount后,根据pageNo和PageSize, 执行criteria的分页查询,取得Page变量
*/
private static Page getPageResult(Criteria criteria, int totalCount, int pageNo, int pageSize) {
if (totalCount < 1) return new Page(); int startIndex = Page.getStartOfPage(pageNo, pageSize);
List list = criteria.setFirstResult(startIndex).setMaxResults(pageSize).list(); return new Page(startIndex, totalCount, pageSize, list);
} }

HqlPage.java文件的代码
package org.mmc.commons; import java.util.List; import org.hibernate.Query; /**
* 使用Hql查询的的分页查询类.
* 支持执行getCount查询取得总记录条数
* 本类参考了springside项目的分页设计
*
* @author lighter
* @see org.mmc.commons.Page
*/
public class HqlPage { 
public static Page getPageInstanceByCount(Query query, int pageNo, int pageSize, int totalCount) {
return getPageResult(query, totalCount, pageNo, pageSize);
} private static Page getPageResult(Query q, int totalCount, int pageNo, int pageSize) {
if (totalCount < 1) return new Page();
int startIndex = Page.getStartOfPage(pageNo, pageSize);
List list = q.setFirstResult(startIndex).setMaxResults(pageSize).list(); return new Page(startIndex, totalCount, pageSize, list);
}
}

Page.java文件的源代码如下:
package org.mmc.commons; import java.util.ArrayList; /**
* 分页对象. 包含数据及分页信息.
* 
* @author lighter 天马行空
*/
public class Page implements java.io.Serializable {
/**
* 当前页第一条数据的位置,从0开始
*/
private int start; /**
* 每页的记录数
*/
private int pageSize = Constants.DEFAULT_PAGE_SIZE; /**
* 当前页中存放的记录
*/
private Object data; /**
* 总记录数
*/
private int totalCount; /**
* 构造方法,只构造空页
*/
public Page() {
this(0, 0, Constants.DEFAULT_PAGE_SIZE, new ArrayList());
} /**
* 默认构造方法
* 
* @param start
* 本页数据在数据库中的起始位置
* @param totalSize
* 数据库中总记录条数
* @param pageSize
* 本页容量
* @param data
* 本页包含的数据
*/
public Page(int start, int totalSize, int pageSize, Object data) {
this.pageSize = pageSize;
this.start = start;
this.totalCount = totalSize;
this.data = data;
} /**
* 取数据库中包含的总记录数
*/
public int getTotalCount() {
return this.totalCount;
} /**
* 取总页数
*/
public int getTotalPageCount() {
if (totalCount % pageSize == 0)
return totalCount / pageSize;
else
return totalCount / pageSize + 1;
} /**
* 取每页数据容量
*/
public int getPageSize() {
return pageSize;
} /**
* 当前页中的记录
*/
public Object getResult() {
return data;
} /**
* 取当前页码,页码从1开始
*/
public int getCurrentPageNo() {
return (start / pageSize) + 1;
} /**
* 是否有下一页
*/
public boolean hasNextPage() {
return (this.getCurrentPageNo() < this.getTotalPageCount() - 1);
} /**
* 是否有上一页
*/
public boolean hasPreviousPage() {
return (this.getCurrentPageNo() > 1);
} /**
* 获取任一页第一条数据的位置,每页条数使用默认值
* 关键字设为pretected
*/
protected static int getStartOfPage(int pageNo) {
return getStartOfPage(pageNo, Constants.DEFAULT_PAGE_SIZE);
} /**
* 获取任一页第一条数据的位置,startIndex从0开始
* 关键字设为pretected
*/
protected static int getStartOfPage(int pageNo, int pageSize) {
return (pageNo - 1) * pageSize;
}
}


分页的改造已经完成,现在重构一下DAO层的写法,利用了spring对hibernate支持的一些的API.
DAO层:
AbstractHibernateDao.java的源代码
package org.mmc.dao; import org.apache.commons.beanutils.PropertyUtils;
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.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.mmc.utils.GenericsUtils; import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set; /**
* 纯Hibernate Entity DAO基类.
* 通过泛型,子类无需扩展任何函数即拥有完整的CRUD操作.
*
*/
abstract public class AbstractHibernateDao<T> extends HibernateDaoSupport { protected Log logger = LogFactory.getLog(getClass()); /**
* Dao所管理的Entity类型.
*/
protected Class<T> entityClass; /**
* 取得entityClass的函数.
* JDK1.4不支持泛型的子类可以抛开Class<T> entityClass,重新实现此函数达到相同效果。
*/
protected Class getEntityClass() {
return entityClass;
} /**
* 在构造函数中将泛型T.class赋给entityClass
*/
public AbstractHibernateDao() {
entityClass = GenericsUtils.getGenericClass(getClass());
} public T get(Serializable id) {
T o = (T) getHibernateTemplate().get(getEntityClass(), id);
if (o == null)
throw new ObjectRetrievalFailureException(getEntityClass(), id);
return o;
} public List<T> getAll() {
return getHibernateTemplate().loadAll(getEntityClass());
} public void save(Object o) {
getHibernateTemplate().saveOrUpdate(o);
} public void removeById(Serializable id) {
remove(get(id));
} public void remove(Object o) {
getHibernateTemplate().delete(o);
} public List<T> find(String hsql, Object... values) {
if (values.length == 0)
return getHibernateTemplate().find(hsql);
else
return getHibernateTemplate().find(hsql, values);
} /**
* 根据属性名和属性值查询对象.
*
* @return 符合条件的唯一对象
*/
public T findUniqueBy(String name, Object value) {
Criteria criteria = getSession().createCriteria(getEntityClass());
criteria.add(Restrictions.eq(name, value));
return (T) criteria.uniqueResult();
} /**
* 根据属性名和属性值查询对象.
*
* @return 符合条件的对象列表
*/
public List<T> findBy(String name, Object value) {
Assert.hasText(name);
Criteria criteria = getSession().createCriteria(getEntityClass());
criteria.add(Restrictions.eq(name, value));
return criteria.list();
} /**
* 根据属性名和属性值以Like AnyWhere方式查询对象.
*/
public List<T> findByLike(String name, String value) {
Assert.hasText(name);
Criteria criteria = getSession().createCriteria(getEntityClass());
criteria.add(Restrictions.like(name, value, MatchMode.ANYWHERE));
return criteria.list();
} /**
* 根据Map中过滤条件进行查询.
*
* @param filter 过滤条件.
* @param criteriaSetup 将Map中条件转换为criteria的call back类
*/
public List<T> findBy(Map filter, CriteriaSetup criteriaSetup) {
Criteria criteria = getEntityCriteria();
if (!CollectionUtils.isEmpty(filter)) {
criteriaSetup.setup(criteria, filter);
}
return criteria.list();
} /**
* 函数作用同 {@link #findBy(Map,CriteriaSetup)}
* 如果不需要分页,子类可直接重载此函数.
*/
public List<T> findBy(Map filter) {
return findBy(filter, getDefaultCriteriaSetup());
} protected CriteriaSetup getDefaultCriteriaSetup() {
return new CriteriaSetup() {
public void setup(Criteria criteria, Map filter) {
if (filter != null && !filter.isEmpty()) {
Set keys = filter.keySet();
for (Object key : keys) {
String value = (String) filter.get(key);
if (StringUtils.isNotBlank(value))
criteria.add(Restrictions.eq((String) key, value));
}
}
}
};
} /**
* 取得Entity的Criteria.
*/
protected Criteria getEntityCriteria() {
return getSession().createCriteria(getEntityClass());
} /**
* 构造Criteria的排序条件默认函数.可供其他查询函数调用
*
* @param criteria Criteria实例.
* @param sortMap 排序条件.
* @param entity entity对象,用于使用反射来获取某些属性信息
*/
protected void sortCriteria(Criteria criteria, Map sortMap, Object entity) {
if (!sortMap.isEmpty()) {
for (Object o : sortMap.keySet()) {
String fieldName = o.toString();
String orderType = sortMap.get(fieldName).toString(); //处理嵌套属性如category.name,modify_user.id,暂时只处理一级嵌套
if (fieldName.indexOf(.) != -1) {
String alias = StringUtils.substringBefore(fieldName, ".");
String aliasType = alias;
try {
aliasType = PropertyUtils.getProperty(entity, alias).getClass().getSimpleName();
} catch (Exception e) {
logger.error("Get property" + alias + " error");
}
criteria.createAlias(aliasType, alias);
} if ("asc".equalsIgnoreCase(orderType)) {
criteria.addOrder(Order.asc(fieldName));
} else {
criteria.addOrder(Order.desc(fieldName));
}
}
}
} /**
* 判断对象某列的值在数据库中不存在重复
*
* @param names 在POJO里相对应的属性名,列组合时以逗号分割<br>
* 如"name,loginid,password"
*/
public boolean isNotUnique(Object entity, String names) {
Assert.hasText(names);
Criteria criteria = getSession().createCriteria(entity.getClass()).setProjection(Projections.rowCount());
String[] nameList = names.split(",");
try {
for (String name : nameList) {
criteria.add(Restrictions.eq(name, PropertyUtils.getProperty(entity, name)));
} String keyName = getSessionFactory().getClassMetadata(entity.getClass()).getIdentifierPropertyName();
if (keyName != null) {
Object id = PropertyUtils.getProperty(entity, keyName);
//如果是update,排除自身
if (id != null)
criteria.add(Restrictions.not(Restrictions.eq(keyName, id)));
}
}
catch (Exception e) {
logger.error(e.getMessage());
return false;
}
return ((Integer) criteria.uniqueResult()) > 0;
}
}

再建一个文件:
BaseHibernateDao.java
package org.mmc.dao; import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern; import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.CriteriaSpecification;
import org.mmc.commons.CriteriaPage;
import org.mmc.commons.HqlPage;
import org.mmc.commons.Page;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils; /**
* Hibernate Entity Dao基类.
* 扩展的分页函数,具体的分页代码在Page类中.
*
* @see AbstractHibernateDao
* @see HqlPage
* @see CriteriaPage
*/
abstract public class BaseHibernateDao<T> extends AbstractHibernateDao<T> {
/**
* 根据Map中过滤条件和分页参数进行分页查询.
*
* @param filterMap 过滤条件.
* @param pageNo 当前页码
* @param pageSize 每页显示记录数.
*/
public Page findBy(Map filterMap, int pageNo, int pageSize) {
return findBy(filterMap, null, pageNo, pageSize);
} /**
* 根据Map中过滤条件,排序条件和分页参数进行分页查询.
*
* @param filterMap 过滤条件.
* @param orderMap 排序条件.
* @param pageNo 当前页码
* @param pageSize 每页显示记录数.
*/
public Page findBy(Map filterMap, Map orderMap, int pageNo, int pageSize, CriteriaSetup criteriaSetup) {
Criteria criteria = getSession().createCriteria(getEntityClass()); if (!CollectionUtils.isEmpty(filterMap)) {
try {
criteriaSetup.setup(criteria, filterMap);
} catch (Exception e) {
}
} if (!CollectionUtils.isEmpty(orderMap))
sortCriteria(criteria, orderMap, null); criteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY); return pagedQuery(criteria, pageNo, pageSize);
} public Page findBy(Map filterMap, Map orderMap, int pageNo, int pageSize) {
return findBy(filterMap, orderMap, pageNo, pageSize, getDefaultCriteriaSetup());
} /**
* Criteria分页查询,采用了getCount模式
*/
public Page pagedQuery(Criteria criteria, int pageNo, int pageSize) {
return CriteriaPage.getPageInstance(criteria, pageNo, pageSize);
} /**
* HQL分页查询,可以指定具体的模式,
* 采用getCount方式,须在此层完成hsql的转换与查询。
* 注意参数Object...args的应用,可以在查询的设置查询条件用的(JDK5.0语法)
*/
public Page pagedQuery(String hql, int pageNo, int pageSize, Object... args) {
Assert.hasText(hql);
Query query = getSession().createQuery(hql);
for (int i = 0; i < args.length; i++) {
query.setParameter(i, args[i]);
}
String countQueryString = " select count (*) " + removeSelect(removeOrders(hql));
List countlist = getHibernateTemplate().find(countQueryString, args);
int totalCount = (Integer) countlist.get(0);
return HqlPage.getPageInstanceByCount(query, pageNo, pageSize, totalCount);
} /**
* 去除select 子句,未考虑union的情况
*/
private static String removeSelect(String hql) {
Assert.hasText(hql);
int beginPos = hql.toLowerCase().indexOf("from");
Assert.isTrue(beginPos != -1, " hql : " + hql + " must has a keyword from");
return hql.substring(beginPos);
} /**
* 去除orderby 子句
*/
private static String removeOrders(String hql) {
Assert.hasText(hql);
Pattern p = Pattern.compile("order\\s*by[\\w|\\W|\\s|\\S]*", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(hql);
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement(sb, "");
}
m.appendTail(sb);
return sb.toString();
}
}
BaseHibernateDAO负责抽象一个Entity 的CRUD函数。 所有子类只要声明如下,即拥有如下函数:
public class UserDAO extends BaseHibernateDao<User> 
protected final Log logger 
public Object get(Serializable id) 
public List getAll() 
public void save(Object o) 
public void remove(Serializable id) 
public void remove(Object o) 
public List find(String hql) 
public List find(String hql,Object value) 
public List find(String hql,object[]) 
public Object findBy(String name,Object value) 
public List findAllBy(String name,Object value) 
public List findAllByLike(String name,Object value) 
public List findAllBy(Map filter)
分享到:
评论

相关推荐

    Hibernate分页查询小结

    Hibernate分页查询小结

    Hibernate分页查询原理解读

    #### 三、Hibernate分页查询实现原理 ##### 3.1 使用SQL LIMIT实现分页 对于支持LIMIT关键字的数据库(例如MySQL),Hibernate会通过特定的方言(Dialect)来生成包含LIMIT关键字的SQL语句。具体实现如下: ```...

    hibernate分页查询 数据库连接

    此外,优化查询,避免N+1查询问题,合理设计实体关系,都能有效提升Hibernate分页查询的效率。 总结起来,Hibernate的分页查询和数据库连接管理是其强大功能的重要组成部分。正确理解和使用这些特性,能够帮助...

    hibernate分页Hibernate 分页的设计和编码

    标题与描述均提到了“Hibernate分页的设计和编码”,这表明文章主要聚焦于如何在Hibernate框架中实现数据分页功能。下面将详细解析这一主题的关键知识点。 ### Hibernate分页概念 Hibernate是Java环境下一个开放源...

    hibernate分页查询

    让我们深入探讨Hibernate分页查询的相关知识点。 一、Hibernate分页原理 Hibernate分页查询基于SQL的LIMIT和OFFSET子句,通过Session的createQuery或createSQLQuery方法创建查询,并设置FirstResult和MaxResults...

    strut2.0 + hibernate3.0 + jquery.datatables+mysql 5.0实现的 hibernate分页

    hibernate分页(无排序,搜索,仅仅分页显示),服务器端分页在datatables上展现,有关 datatables的知识请关注它的官网http://www.datatables.net/,datatables的功能很 全面。 2,建表的sql--studentinfo和插入...

    hibernate分页代码

    总结起来,"hibernate分页代码"是一个关于如何在Hibernate中进行分页查询的实践示例,适用于在MyEclipse环境下运行。通过Criteria API或HQL,开发者能够方便地实现分页功能,提升应用性能,为用户提供更好的体验。...

    Struts + Hibernate 分页实现

    在"Struts + Hibernate 分页实现"这个项目中,重点在于如何在Web应用中整合这两个框架,并实现数据的分页显示。分页是大型数据集处理时常见的需求,它能够帮助用户更有效地浏览和管理大量信息,避免一次性加载所有...

    struts2+spring+hibernate分页显示完整代码

    本篇文章将详细讲解如何在基于Struts2、Spring和Hibernate的项目中实现分页功能。 首先,我们从DAO层开始。在`MemberDao`接口中,我们定义了两个关键的方法,一个是用于分页查询,另一个是获取所有记录的数量。这两...

    Struts和Hibernate分页及查询

    在"Struts+Hibernate分页及条件查询练习"这个项目中,开发者可能采用了以下步骤: 1. **配置Struts和Hibernate**:首先,需要在项目中引入Struts和Hibernate的相关库,配置Struts的struts-config.xml文件和...

    使用hibernate分页查询

    1. **配置Hibernate分页**: 在Hibernate中,我们通常使用`Criteria`或`Query` API进行分页查询。`Criteria`提供了一种更面向对象的方式来执行SQL查询,而`Query` API则对应于原生的SQL语句。在这些API中,我们可以...

    hibernate分页技巧

    hibernate分页 博文链接:https://iomo.iteye.com/blog/243518

    Hibernate 分页查询效果

    本篇主要围绕"Hibernate分页查询效果"这一主题,深入探讨如何利用Hibernate框架实现高效、便捷的分页功能。 首先,Hibernate是一个优秀的Java持久化框架,它提供了ORM(对象关系映射)解决方案,使得开发者可以使用...

    高效率的dw+spring+hibernate分页演示例子

    这个"高效率的dw+spring+hibernate分页演示例子"提供了一个实用的示例,展示了如何将这三个框架整合起来,以实现高效的数据分页功能。 首先,让我们来逐一了解这三个技术: 1. **DWR (Direct Web Remoting)**:DWR...

    hibernate实现分页

    ### Hibernate分页基础 1. **Criteria API**:Hibernate的Criteria API允许我们创建动态查询,同时也支持分页。通过设置`setFirstResult()`和`setMaxResults()`方法,可以实现分页效果。例如: ```java Criteria ...

    struts+hibernate分页

    综上所述,"struts+hibernate分页"涉及到的主要是如何在Struts的控制层和Hibernate的数据层之间协调处理分页请求,以及在DAO层利用Hibernate的特性实现数据库查询的分页。理解并掌握这两个框架的分页机制,对于开发...

    java 实现的一个简单的hibernate分页类

    java 实现的一个简单的hibernate分页类 可以设置,从某一条开始取、显示的条数 不依赖struts spring

    hibernate分页例子.rar

    本教程将通过一个具体的“hibernate分页例子”来深入理解如何在Hibernate中实现分页功能。 在实际应用中,当数据量大到一定程度时,一次性加载所有数据会导致内存压力过大,影响系统性能。因此,分页查询成为一种...

    关于Hibernate分页类和jdbc的sql分页完美融合

    本主题将探讨如何在Hibernate分页类和JDBC的SQL分页方法之间实现完美的融合,以提高性能并提供更好的用户体验。 首先,让我们了解一下Hibernate的分页功能。Hibernate提供了一种方便的方式来处理分页查询,通过...

Global site tag (gtag.js) - Google Analytics