<script></script>
代码:
IBase.java
HibernateEntityDao.java
IEntityDao.java
HibernateGenericDao.java
com.hibernate.dao.support下的3个类和如下的一致:
引用地址:http://blog.youkuaiyun.com/tom_221x/archive/2008/12/26/3611535.aspx
另提供IBM 社区基于Hibernate编写的GenericDao参考文章地址
中文版:http://www.ibm.com/developerworks/cn/java/j-genericdao.html
英文版:http://www.ibm.com/developerworks/java/library/j-genericdao.html
结构看图:

HinernateEntityDao和HibernateGenericDao都继承在spring的HibernateDaoSupport
一个提供和实体相关的操作,一个提供和实体类无关的操作。
然后以组合的方式在BaseDao中使用,这样程序中全部使用IBaseDao接口来操作数据,便于修改和维护.
xml配置实用如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
- <!-这个是和实体相关的dao,所以scope是prototype的每个实体对应一个对象->
- <bean id="hedao"
- class="com.hibernate.dao.extend.HibernateEntityDao" scope="prototype" lazy-init="true">
- <property name="sessionFactory">
- <ref bean="sessionFactory" />
- </property>
- </bean>
- <!-这个和具体实体无关,所有dao共享->
- <bean id="hgdao"
- class="com.hibernate.dao.generic.HibernateGenericDao">
- <property name="sessionFactory">
- <ref bean="sessionFactory" />
- </property>
- </bean>
- <!--使用泛型DAO作为抽象基类-->
- <bean id="baseDao" class="com.hibernate.dao.base.BaseDao"
- abstract="true" depends-on="hedao,hgdao">
- <property name="hedao">
- <ref bean="hedao" />
- </property>
- <property name="hgdao">
- <ref bean="hgdao" />
- </property>
- </bean>
- <!-- 配置实体Demodata的DAO -->
- <bean id="demoDao" parent="baseDao">
- <constructor-arg>
- <value>com.hibernate.entityclass.Demodata</value>
- </constructor-arg>
- </bean>
- </beans>
BaseDao.java
- package com.hibernate.dao.base;
- import java.io.Serializable;
- import java.util.List;
- import org.hibernate.Criteria;
- import org.hibernate.Query;
- import org.hibernate.criterion.Criterion;
- import org.springframework.orm.hibernate3.HibernateTemplate;
- import com.hibernate.dao.extend.HibernateEntityDao;
- import com.hibernate.dao.generic.HibernateGenericDao;
- import com.hibernate.dao.support.Page;
- /**
- * 提供hibernate dao的所有操作,<br>
- * 实现类由spring注入HibernateEntityDao和HibernateGenericDao来实现
- *
- */
- public class BaseDao<T,PK extends Serializable> implements IBaseDao<T,PK> {
- protected Class<T> entityClass;// DAO所管理的Entity类型.
- private HibernateEntityDao<T,PK> hedao;
- private HibernateGenericDao hgdao;
- public void setHedao(HibernateEntityDao<T, PK> hedao) {
- hedao.setEntityClass(entityClass);
- this.hedao = hedao;
- }
- public void setHgdao(HibernateGenericDao hgdao) {
- this.hgdao = hgdao;
- }
- /**
- *让spring提供构造函数注入
- */
- public BaseDao(Class<T> type) {
- this.entityClass = type;
- }
- public BaseDao(){}
- /**
- * 清除所有对象缓存
- */
- public void clear() {
- hgdao.clear();
- }
- /**
- * 创建Criteria对象.
- * @param criterions 可变的Restrictions条件列表
- */
- public Criteria createCriteria(Criterion... criterions) {
- return hedao.createCriteria(criterions);
- }
- /**
- * 创建Criteria对象,带排序字段与升降序字段.
- */
- public Criteria createCriteria(String orderBy, boolean isAsc,
- Criterion... criterions) {
- return hedao.createCriteria(orderBy, isAsc, criterions);
- }
- /**
- * 创建Query对象. 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
- * 留意可以连续设置,如下:
- * <pre>
- * dao.getQuery(hql).setMaxResult(100).setCacheable(true).list();
- * </pre>
- * 调用方式如下:
- * <pre>
- * dao.createQuery(hql)
- * dao.createQuery(hql,arg0);
- * dao.createQuery(hql,arg0,arg1);
- * dao.createQuery(hql,new Object[arg0,arg1,arg2])
- * </pre>
- *
- * @param values 可变参数.
- */
- public Query createQuery(String hql, Object... values) {
- return hgdao.createQuery(hql, values);
- }
- /**
- * @param hql 查询sql
- * @param start 分页从哪一条数据开始
- * @param pageSize 每一个页面的大小
- * @param values 查询条件
- * @return page对象
- */
- public Page dataQuery(String hql, int start, int pageSize, Object... values) {
- return hgdao.dataQuery(hql, start, pageSize, values);
- }
- /**
- * 消除与 Hibernate Session 的关联
- * @param entity
- */
- public void evit(T entity) {
- hedao.evict(entity);
- }
- /**
- * 执行本地sql语句获得标量数值列表
- */
- @SuppressWarnings("unchecked")
- public List executeNativeSql(String sql) {
- return hgdao.executeNativeSql(sql);
- }
- /**
- * 根据hql查询,直接使用HibernateTemplate的find函数.
- * @param values 可变参数
- */
- @SuppressWarnings("unchecked")
- public List find(String hql, Object... values) {
- return hgdao.find(hql, values);
- }
- /**
- * 根据属性名和属性值查询对象.
- * @return 符合条件的对象列表
- */
- public List<T> findBy(String propertyName, Object value) {
- return hedao.findBy(propertyName, value);
- }
- /**
- * 根据属性名和属性值查询对象,带排序参数.
- */
- public List<T> findBy(String propertyName, Object value, String orderBy,
- boolean isAsc) {
- return hedao.findBy(propertyName, value, orderBy, isAsc);
- }
- /**
- * 根据属性名和属性值查询唯一对象.
- * @return 符合条件的唯一对象 or null if not found.
- */
- public T findUniqueBy(String propertyName, Object value) {
- return hedao.findUniqueBy(propertyName, value);
- }
- /**
- * 执行一些必须的sql语句把内存中的对象同步到jdbc的链接中
- */
- public void flush() {
- hgdao.flush();
- }
- /**
- * 根据Serializable类型的id获取实体对象<p/>
- * 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常.
- * @param id
- */
- public T get(PK id) {
- return hedao.get(id);
- }
- /**
- * 获取实体类型的全部对象
- */
- public List<T> getAll() {
- return hedao.getAll();
- }
- /**
- * 获取全部对象,带排序字段与升降序参数.
- */
- public List<T> getAll(String orderBy, boolean isAsc) {
- return hedao.getAll(orderBy, isAsc);
- }
- /**
- * 直接使用spring提供的HibernateTemplate
- */
- public HibernateTemplate getHibernateTemplate() {
- return hgdao.getHibernateTemplate();
- }
- /**
- * 判断对象某些属性的值在数据库中是否唯一.
- *
- * @param uniquePropertyNames 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
- */
- public boolean isUnique(T entity, String uniquePropertyNames) {
- return hedao.isUnique(entity, uniquePropertyNames);
- }
- /**
- * 分页查询函数,使用hql.
- *
- * @param pageNo 页号,从1开始.
- */
- public Page pagedQuery(String hql, int pageNo, int pageSize,
- Object... values) {
- return hgdao.pagedQuery(hql, pageNo, pageSize, values);
- }
- /**
- * 分页查询函数,使用已设好查询条件与排序的<code>Criteria</code>.
- *
- * @param pageNo 页号,从1开始.
- * @return 含总记录数和当前页数据的Page对象.
- */
- public Page pagedQuery(Criteria criteria, int pageNo, int pageSize) {
- return hedao.pagedQuery(criteria, pageNo, pageSize);
- }
- /**
- * 分页查询函数,根据entityClass和查询条件参数创建默认的<code>Criteria</code>.
- *
- * @param pageNo 页号,从1开始.
- * @return 含总记录数和当前页数据的Page对象.
- */
- public Page pagedQuery(int pageNo, int pageSize, Criterion... criterions) {
- return hedao.pagedQuery(pageNo, pageSize, criterions);
- }
- /**
- * 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的<code>Criteria</code>.
- *
- * @param pageNo 页号,从1开始.
- * @return 含总记录数和当前页数据的Page对象.
- */
- public Page pagedQuery(int pageNo, int pageSize, String orderBy,
- boolean isAsc, Criterion... criterions) {
- return hedao.pagedQuery(pageNo, pageSize, orderBy, isAsc, criterions);
- }
- /**
- * 删除对象.
- */
- public void remove(T entity) {
- hedao.remove(entity);
- }
- /**
- * 根据ID删除对象.
- */
- public void removeById(PK id) {
- hedao.removeById(id);
- }
- /**
- * 保存对象.<br>
- * 如果对象已在本session中持久化了,不做任何事。<br>
- * 如果另一个seesion拥有相同的持久化标识,抛出异常。<br>
- * 如果没有持久化标识属性,调用save()。<br>
- * 如果持久化标识表明是一个新的实例化对象,调用save()。<br>
- * 如果是附带版本信息的(<version>或<timestamp>)且版本属性表明为新的实例化对象就save()。<br>
- * 否则调用update()重新关联托管对象
- */
- public void save(T entity) {
- hedao.save(entity);
- }
- /**
- * 在不同的session中关联修改过的托管对象
- */
- public void update(T entity){
- hedao.update(entity);
- }
- }
- /**
- *
- */
- package com.hibernate.dao.base;
- import java.io.Serializable;
- import java.util.List;
- import org.hibernate.Criteria;
- import org.hibernate.Query;
- import org.hibernate.criterion.Criterion;
- import org.springframework.orm.hibernate3.HibernateTemplate;
- import com.hibernate.dao.generic.HibernateGenericDao;
- import com.hibernate.dao.support.Page;
- /**
- * 提供hibernate dao的所有操作,<br>
- * 实现类由spring注入HibernateEntityDao和HibernateGenericDao来实现
- *
- */
- public interface IBaseDao<T,PK extends Serializable> {
- /**
- * 获取全部对象
- *
- * @see HibernateGenericDao#getAll(Class)
- */
- public List<T> getAll();
- /**
- * 获取全部对象,带排序参数.
- */
- public List<T> getAll(String orderBy, boolean isAsc);
- /**
- * 根据ID移除对象.
- */
- public void removeById(PK id);
- /**
- * 取得Entity的Criteria.
- */
- public Criteria createCriteria(Criterion... criterions);
- /**
- * 取得Entity的Criteria,带排序参数.
- */
- public Criteria createCriteria(String orderBy, boolean isAsc,
- Criterion... criterions);
- /**
- * 根据属性名和属性值查询对象.
- *
- * @return 符合条件的对象列表
- */
- public List<T> findBy(String propertyName, Object value);
- /**
- * 根据属性名和属性值查询对象,带排序参数.
- *
- * @return 符合条件的对象列表
- */
- public List<T> findBy(String propertyName, Object value, String orderBy,
- boolean isAsc);
- /**
- * 根据属性名和属性值查询单个对象.
- *
- * @return 符合条件的唯一对象 or null
- */
- public T findUniqueBy(String propertyName, Object value);
- /**
- * 判断对象某些属性的值在数据库中唯一.
- *
- * @param uniquePropertyNames
- * 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
- * @see HibernateGenericDao#isUnique(Class,Object,String)
- */
- public boolean isUnique(T entity, String uniquePropertyNames);
- /**
- * 消除与 Hibernate Session 的关联
- *
- */
- public void evit(T entity);
- /**
- * 根据ID获取对象. 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常.
- */
- public T get(PK id);
- /**
- * 保存对象.
- */
- public void save(T o);
- /**
- * 删除对象.
- */
- public void remove(T o);
- public void flush();
- public void clear();
- /**
- * 创建Query对象. 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
- * 留意可以连续设置,如下:
- * <pre>
- * dao.getQuery(hql).setMaxResult(100).setCacheable(true).list();
- * </pre>
- * 调用方式如下:
- * <pre>
- * dao.createQuery(hql)
- * dao.createQuery(hql,arg0);
- * dao.createQuery(hql,arg0,arg1);
- * dao.createQuery(hql,new Object[arg0,arg1,arg2])
- * </pre>
- *
- * @param values 可变参数.
- */
- public Query createQuery(String hql, Object... values);
- /**
- * 根据hql查询,直接使用HibernateTemplate的find函数.
- */
- @SuppressWarnings("unchecked")
- public List find(String hql, Object... values);
- /**
- * 分页查询函数,使用hql.
- *
- * @param pageNo 页号,从1开始.
- */
- public Page pagedQuery(String hql, int pageNo, int pageSize, Object... values);
- /**
- * @param hql 查询sql
- * @param start 分页从哪一条数据开始
- * @param pageSize 每一个页面的大小
- * @param values 查询条件
- * @return page对象
- */
- public Page dataQuery(String hql, int start, int pageSize, Object... values);
- /**
- * 分页查询函数,使用已设好查询条件与排序的<code>Criteria</code>.
- *
- * @param pageNo 页号,从1开始.
- * @return 含总记录数和当前页数据的Page对象.
- */
- public Page pagedQuery(Criteria criteria, int pageNo, int pageSize);
- /**
- * 分页查询函数,根据entityClass和查询条件参数创建默认的<code>Criteria</code>.
- *
- * @param pageNo 页号,从1开始.
- * @return 含总记录数和当前页数据的Page对象.
- */
- public Page pagedQuery(int pageNo, int pageSize, Criterion... criterions);
- /**
- * 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的<code>Criteria</code>.
- *
- * @param pageNo 页号,从1开始.
- * @return 含总记录数和当前页数据的Page对象.
- */
- public Page pagedQuery(int pageNo, int pageSize, String orderBy, boolean isAsc,
- Criterion... criterions);
- @SuppressWarnings("unchecked")
- public List executeNativeSql(String sql);
- public HibernateTemplate getHibernateTemplate();
- /**
- * 在不同的session中关联修改过的托管对象
- */
- public void update(T entity);
- }
- /**
- *
- */
- package com.hibernate.dao.extend;
- import java.io.Serializable;
- import java.lang.reflect.InvocationTargetException;
- import java.util.ArrayList;
- import java.util.List;
- import org.apache.commons.beanutils.PropertyUtils;
- import org.hibernate.Criteria;
- import org.hibernate.criterion.CriteriaSpecification;
- import org.hibernate.criterion.Criterion;
- import org.hibernate.criterion.DetachedCriteria;
- import org.hibernate.criterion.Order;
- import org.hibernate.criterion.Projection;
- import org.hibernate.criterion.Projections;
- import org.hibernate.criterion.Restrictions;
- import org.hibernate.impl.CriteriaImpl;
- import org.hibernate.metadata.ClassMetadata;
- import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
- import org.springframework.util.Assert;
- import org.springframework.util.ReflectionUtils;
- import com.hibernate.dao.support.BeanUtils;
- import com.hibernate.dao.support.Page;
- /**
- * 负责为单个Entity对象提供CRUD操作的Hibernate DAO基类. <p/>
- * 子类只要在类定义时指定所管理Entity的Class,
- * 即拥有对单个Entity对象的CRUD操作.
- *
- * @see 继承自spring的HibernateDaoSupport
- */
- public class HibernateEntityDao<T,PK extends Serializable> extends HibernateDaoSupport implements IEntityDao<T, PK> {
- protected Class<T> entityClass;// DAO所管理的Entity类型.
- public void setEntityClass(Class<T> type){
- this.entityClass=type;
- }
- /**
- * 在构造函数中将泛型T.class赋给entityClass.
- */
- public HibernateEntityDao() {
- //entityClass = GenericsUtils.getSuperClassGenricType(getClass());
- }
- /**
- * 取得entityClass.JDK1.4不支持泛型的子类可以抛开Class<T> entityClass,重载此函数达到相同效果。
- */
- protected Class<T> getEntityClass() {
- return entityClass;
- }
- /**
- * 根据Serializable类型的id获取实体对象<p/>
- * 实际调用Hibernate的session.load()方法返回实体或其proxy对象. 如果对象不存在,抛出异常.
- * @param id
- */
- @SuppressWarnings("unchecked")
- public T get(PK id) {
- return (T) getHibernateTemplate().load(getEntityClass(), id);
- }
- /**
- * 获取实体类型的全部对象
- */
- @SuppressWarnings("unchecked")
- public List<T> getAll() {
- return (List<T>)(getHibernateTemplate().loadAll(getEntityClass()));
- }
- /**
- * 获取全部对象,带排序字段与升降序参数.
- */
- @SuppressWarnings("unchecked")
- public List<T> getAll(String orderBy, boolean isAsc) {
- Assert.hasText(orderBy);
- if (isAsc)
- return getHibernateTemplate().findByCriteria(
- DetachedCriteria.forClass(getEntityClass()).addOrder(Order.asc(orderBy)));
- else
- return getHibernateTemplate().findByCriteria(
- DetachedCriteria.forClass(getEntityClass()).addOrder(Order.desc(orderBy)));
- }
- /**
- * 删除对象.
- */
- public void remove(T entity) {
- getHibernateTemplate().delete(entity);
- }
- /**
- * 根据ID删除对象.
- */
- public void removeById(PK id) {
- remove(get(id));
- }
- /**
- * 保存对象.<br>
- * 如果对象已在本session中持久化了,不做任何事。<br>
- * 如果另一个seesion拥有相同的持久化标识,抛出异常。<br>
- * 如果没有持久化标识属性,调用save()。<br>
- * 如果持久化标识表明是一个新的实例化对象,调用save()。<br>
- * 如果是附带版本信息的(<version>或<timestamp>)且版本属性表明为新的实例化对象就save()。<br>
- * 否则调用update()重新关联托管对象
- */
- public void save(T entity) {
- getHibernateTemplate().saveOrUpdate(entity);
- }
- /**
- * 在不同的session中关联修改过的托管对象
- */
- public void update(T entity) {
- getHibernateTemplate().update(entity);
- }
- /**
- * 消除与 Hibernate Session 的关联
- * @param entity
- */
- public void evict(T entity) {
- getHibernateTemplate().evict(entity);
- }
- /**
- * 创建Criteria对象.
- * @param criterions 可变的Restrictions条件列表
- */
- public Criteria createCriteria(Criterion... criterions) {
- Criteria criteria = getSession().createCriteria(getEntityClass());
- for (Criterion c : criterions) {
- criteria.add(c);
- }
- return criteria;
- }
- /**
- * 创建Criteria对象,带排序字段与升降序字段.
- */
- public Criteria createCriteria(String orderBy, boolean isAsc, Criterion... criterions) {
- Assert.hasText(orderBy);
- Criteria criteria = createCriteria(criterions);
- if (isAsc)
- criteria.addOrder(Order.asc(orderBy));
- else
- criteria.addOrder(Order.desc(orderBy));
- return criteria;
- }
- /**
- * 根据属性名和属性值查询对象.
- * @return 符合条件的对象列表
- */
- @SuppressWarnings("unchecked")
- public List<T> findBy(String propertyName, Object value) {
- Assert.hasText(propertyName);
- return createCriteria(Restrictions.eq(propertyName, value)).list();
- }
- /**
- * 根据属性名和属性值查询对象,带排序参数.
- */
- @SuppressWarnings("unchecked")
- public List<T> findBy(String propertyName, Object value, String orderBy, boolean isAsc) {
- Assert.hasText(propertyName);
- Assert.hasText(orderBy);
- return createCriteria(orderBy, isAsc, Restrictions.eq(propertyName, value)).list();
- }
- /**
- * 根据属性名和属性值查询唯一对象.
- * @return 符合条件的唯一对象 or null if not found.
- */
- @SuppressWarnings("unchecked")
- public T findUniqueBy(String propertyName, Object value) {
- Assert.hasText(propertyName);
- return (T) createCriteria(Restrictions.eq(propertyName, value)).uniqueResult();
- }
- /**
- * 分页查询函数,使用已设好查询条件与排序的<code>Criteria</code>.
- *
- * @param pageNo 页号,从1开始.
- * @return 含总记录数和当前页数据的Page对象.
- */
- @SuppressWarnings("unchecked")
- public Page pagedQuery(Criteria criteria, int pageNo, int pageSize) {
- Assert.notNull(criteria);
- Assert.isTrue(pageNo >= 1, "pageNo should start from 1");
- CriteriaImpl impl = (CriteriaImpl) criteria;
- // 先把Projection和OrderBy条件取出来,清空两者来执行Count操作
- Projection projection = impl.getProjection();
- List<CriteriaImpl.OrderEntry> orderEntries;
- try {
- orderEntries = (List) BeanUtils.forceGetProperty(impl, "orderEntries");
- BeanUtils.forceSetProperty(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.forceSetProperty(impl, "orderEntries", orderEntries);
- } catch (Exception e) {
- throw new InternalError(" Runtime Exception impossibility throw ");
- }
- // 返回分页对象
- 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);
- }
- /**
- * 分页查询函数,根据entityClass和查询条件参数创建默认的<code>Criteria</code>.
- *
- * @param pageNo 页号,从1开始.
- * @return 含总记录数和当前页数据的Page对象.
- */
- public Page pagedQuery(int pageNo, int pageSize, Criterion... criterions) {
- Criteria criteria = createCriteria(criterions);
- return pagedQuery(criteria, pageNo, pageSize);
- }
- /**
- * 分页查询函数,根据entityClass和查询条件参数,排序参数创建默认的<code>Criteria</code>.
- *
- * @param pageNo 页号,从1开始.
- * @return 含总记录数和当前页数据的Page对象.
- */
- public Page pagedQuery(int pageNo, int pageSize, String orderBy, boolean isAsc,
- Criterion... criterions) {
- Criteria criteria = createCriteria(orderBy, isAsc, criterions);
- return pagedQuery(criteria, pageNo, pageSize);
- }
- /**
- * 判断对象某些属性的值在数据库中是否唯一.
- *
- * @param uniquePropertyNames 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password"
- */
- public boolean isUnique(T entity, String uniquePropertyNames) {
- Assert.hasText(uniquePropertyNames);
- Criteria criteria = createCriteria().setProjection(Projections.rowCount());
- String[] nameList = uniquePropertyNames.split(",");
- try {
- // 循环加入唯一列
- for (String name : nameList) {
- criteria.add(Restrictions.eq(name, PropertyUtils.getProperty(entity, name)));
- }
- // 以下代码为了如果是update的情况,排除entity自身.
- String idName = getIdName(getEntityClass());
- // 取得entity的主键值
- PK id = getId(getEntityClass(), entity);
- // 如果id!=null,说明对象已存在,该操作为update,加入排除自身的判断
- if (id != null)
- criteria.add(Restrictions.not(Restrictions.eq(idName, id)));
- } catch (Exception e) {
- ReflectionUtils.handleReflectionException(e);
- }
- return (Integer) criteria.uniqueResult() == 0;
- }
- /**
- * 取得对象的主键值,辅助函数.
- */
- @SuppressWarnings("unchecked")
- public PK getId(Class<T> entityClass, T entity) throws NoSuchMethodException, IllegalAccessException,
- InvocationTargetException {
- Assert.notNull(entity);
- Assert.notNull(entityClass);
- return (PK) PropertyUtils.getProperty(entity, getIdName(entityClass));
- }
- /**
- * 取得对象的主键名,辅助函数.
- */
- public String getIdName(Class<T> clazz) {
- Assert.notNull(clazz);
- ClassMetadata meta = getSessionFactory().getClassMetadata(clazz);
- Assert.notNull(meta, "Class " + clazz + " not define in hibernate session factory.");
- String idName = meta.getIdentifierPropertyName();
- Assert.hasText(idName, clazz.getSimpleName() + " has no identifier property define.");
- return idName;
- }
- }
- package com.hibernate.dao.extend;
- import java.io.Serializable;
- import java.util.List;
- /**
- * 针对单个Entity对象的CRUD操作定义.
- */
- public interface IEntityDao<T,PK extends Serializable> {
- T get(PK id);
- List<T> getAll();
- void save(T entity);
- void remove(T entity);
- void removeById(PK id);
- void update(T entity);
- /**
- * 获取Entity对象的主键名.
- */
- String getIdName(Class<T> clazz);
- }
- /**
- *
- */
- package com.hibernate.dao.generic;
- import java.util.List;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import org.hibernate.Query;
- import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
- import org.springframework.util.Assert;
- import com.hibernate.dao.support.Page;
- /**
- * 继承自spring的HibernateDaoSupport<br>
- * 提供了和具体实体类无关的数据库操作,如分页函数和若干便捷查询方法
- * @see HibernateDaoSupport
- */
- public class HibernateGenericDao extends HibernateDaoSupport {
- /**
- * 分页查询函数,使用hql.
- *
- * @param pageNo 页号,从1开始.
- */
- @SuppressWarnings("unchecked")
- public Page pagedQuery(String hql, int pageNo, int pageSize, Object... values) {
- Assert.hasText(hql);
- Assert.isTrue(pageNo >= 1, "pageNo should start from 1");
- // Count查询
- String countQueryString = " select count (*) " + removeSelect(removeOrders(hql));
- List countlist = getHibernateTemplate().find(countQueryString, values);
- long totalCount = (Long) countlist.get(0);
- if (totalCount < 1)
- return new Page();
- // 实际查询返回分页对象
- int startIndex = Page.getStartOfPage(pageNo, pageSize);
- Query query = createQuery(hql, values);
- List list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();
- return new Page(startIndex, totalCount, pageSize, list);
- }
- /**
- * @param hql 查询sql
- * @param start 分页从哪一条数据开始
- * @param pageSize 每一个页面的大小
- * @param values 查询条件
- * @return page对象
- */
- @SuppressWarnings("unchecked")
- public Page dataQuery(String hql, int start, int pageSize, Object... values){
- Assert.hasText(hql);
- // Count查询
- String countQueryString = " select count (*) " + removeSelect(removeOrders(hql));
- List countlist = getHibernateTemplate().find(countQueryString, values);
- long totalCount = (Long) countlist.get(0);
- if (totalCount < 1)
- return new Page();
- // 实际查询返回分页对象
- int startIndex = start;
- Query query = createQuery(hql, values);
- List list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();
- return new Page(startIndex, totalCount, pageSize, list);
- }
- /**
- * 创建Query对象. 对于需要first,max,fetchsize,cache,cacheRegion等诸多设置的函数,可以在返回Query后自行设置.
- * 留意可以连续设置,如下:
- * <pre>
- * dao.getQuery(hql).setMaxResult(100).setCacheable(true).list();
- * </pre>
- * 调用方式如下:
- * <pre>
- * dao.createQuery(hql)
- * dao.createQuery(hql,arg0);
- * dao.createQuery(hql,arg0,arg1);
- * dao.createQuery(hql,new Object[arg0,arg1,arg2])
- * </pre>
- *
- * @param values 可变参数.
- */
- public Query createQuery(String hql, Object... values) {
- Assert.hasText(hql);
- Query query = getSession().createQuery(hql);
- for (int i = 0; i < values.length; i++) {
- query.setParameter(i, values[i]);
- }
- return query;
- }
- /**
- * 根据hql查询,直接使用HibernateTemplate的find函数.
- * @param values 可变参数
- */
- @SuppressWarnings("unchecked")
- public List find(String hql, Object... values) {
- Assert.hasText(hql);
- return getHibernateTemplate().find(hql, values);
- }
- /**
- * 执行一些必须的sql语句把内存中的对象同步到jdbc的链接中
- */
- public void flush() {
- getHibernateTemplate().flush();
- }
- /**
- * 清除所有对象缓存
- */
- public void clear() {
- getHibernateTemplate().clear();
- }
- /**
- * 执行本地sql语句获得标量数值列表
- */
- @SuppressWarnings("unchecked")
- public List executeNativeSql(String sql){
- return getSession().createSQLQuery(sql).list();
- }
- /**
- * 去除hql的select 子句,未考虑union的情况,用于pagedQuery.
- */
- 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);
- }
- /**
- * 去除hql的orderby 子句,用于pagedQuery.
- */
- 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();
- }
- }