Hibernate 通用底层Dao代码

jopen 7年前

Hibernate 是一个非常 优秀的ORM框架,能以面向对象的方式操作数据库,使得对数据库的操作变得更加简单。以下和大家分享一个通用的Hibernate 编写的底层Dao (涉及到反射)

1.反射工具类 部分代码:

import java.lang.reflect.ParameterizedType;  import java.lang.reflect.Type;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory;  /**   * 反射的 Utils 函数集合 提供访问私有变量, 获取泛型类型 Class, 提取集合中元素属性等 Utils 函数   *    * @author Administrator   *    */  public class ReflectionUtils {           private static Logger logger = LoggerFactory.getLogger(ReflectionUtils.class);   /**    * 通过反射, 获得定义 Class 时声明的父类的泛型参数的类型 如: public EmployeeDao extends    * BaseDao<Employee, String>    *     * @param clazz    * @param index    * @return    */   @SuppressWarnings("unchecked")   public static Class getSuperClassGenricType(Class clazz, int index) {    Type genType = clazz.getGenericSuperclass();      if (!(genType instanceof ParameterizedType)) {     logger.warn(clazz.getSimpleName()       + "'s superclass not ParameterizedType");     return Object.class;    }      Type[] params = ((ParameterizedType) genType).getActualTypeArguments();      if (index >= params.length || index < 0) {     logger.warn("Index: " + index + ", Size of "       + clazz.getSimpleName() + "'s Parameterized Type: "       + params.length);     return Object.class;    }      if (!(params[index] instanceof Class)) {     logger.warn(clazz.getSimpleName()       + " not set the actual class on superclass generic parameter");     return Object.class;    }      return (Class) params[index];   }     /**    * 通过反射, 获得 Class 定义中声明的父类的泛型参数类型 如: public EmployeeDao extends    * BaseDao<Employee, String>    *     * @param <T>    * @param clazz    * @return    */   @SuppressWarnings("unchecked")   public static <T> Class<T> getSuperGenericType(Class clazz) {    return getSuperClassGenricType(clazz, 0);   }  }

2.底层Dao

import java.io.Serializable;  import java.util.ArrayList;  import java.util.LinkedHashSet;  import java.util.List;  import java.util.Map;  import java.util.Set;  import javax.annotation.Resource;  import org.hibernate.Criteria;  import org.hibernate.Hibernate;  import org.hibernate.Query;  import org.hibernate.Session;  import org.hibernate.SessionFactory;  import org.hibernate.criterion.CriteriaSpecification;  import org.hibernate.criterion.Criterion;  import org.hibernate.criterion.Restrictions;  import org.hibernate.metadata.ClassMetadata;  import org.slf4j.Logger;  import org.slf4j.LoggerFactory;  import org.springframework.util.Assert;    /**   * 在 Service 层直接使用, 也可以扩展泛型 DAO 子类使用 T: Dao 操作的对象类型 PK: 主键类型   *    * @author Administrator   *    */  public class SimpleHibernateDao<T, PK extends Serializable> {      protected Logger logger = LoggerFactory.getLogger(getClass());     protected SessionFactory sessionFactory;     protected Class<T> entityClass;     /**    * 用于 Dao 层子类使用的构造函数 通过子类的泛型定义取得对象类型 Class    *     * 例如: public class UserDao extends SimpleHibernateDao<User, String>    */   public SimpleHibernateDao() {    this.entityClass = ReflectionUtils.getSuperGenericType(getClass());   }      /**    * 用于省略 Dao 层, 在 Service 层直接使用通用 SimpleHibernateDao 的构造函数 在构造函数中定义对象类型 Class    *     * @param sessionFactory    * @param entityClass    */   public SimpleHibernateDao(SessionFactory sessionFactory,     Class<T> entityClass) {    this.sessionFactory = sessionFactory;    this.entityClass = entityClass;   }     public SessionFactory getSessionFactory() {    return sessionFactory;   }     @Resource   public void setSessionFactory(SessionFactory sessionFactory) {    this.sessionFactory = sessionFactory;   }     /**    * 获取当前 Session    * @return    */   public Session getSession() {    Session session = sessionFactory.getCurrentSession();    return session;      //  return sessionFactory.openSession();   }     /**    * 保存新增或修改的对象    *     * @param entity    */   public void save(T entity) {      Assert.notNull(entity, "entity 不能为空");    getSession().saveOrUpdate(entity);    logger.debug("save entity: {}", entity);   }     /**    * 按 id 获取对象    *     * @param id    * @return    */   @SuppressWarnings("unchecked")   public T get(PK id) {    Assert.notNull(id, "id不能为空");    return (T) getSession().get(entityClass, id);   }     /**    * 删除对象    *     * @param entity: 持久化对象或"瞬态"对象    */   public void delete(T entity) {    Assert.notNull(entity, "entity 不能为空");    getSession().delete(entity);    logger.debug("delete entity: {}", entity);   }     public void delete(PK id) {    Assert.notNull(id, "id 不能为空");    delete(get(id));    logger.debug("delete entity {},id is {}", entityClass.getSimpleName(),      id);   }     /**    * 获取对象的主键名.    *     * @return    */   public String getIdName() {    ClassMetadata meta = getSessionFactory().getClassMetadata(entityClass);    return meta.getIdentifierPropertyName();   }     /**    * 通过 Set 将不唯一的对象列表唯一化 主要用于 HQL/Criteria 预加载关联集合形成重复记录, 又不方便使用 distinct    * 查询语句时: 例如: 迫切左外连接    *     * @param <X>    * @param list    * @return    */   @SuppressWarnings("unchecked")   public <X> List<X> distinct(List list) {    Set<X> set = new LinkedHashSet<X>(list);    return new ArrayList<X>(set);   }     /**    * 为 Criteria 添加 distinct transformer    *     * @param criteria    * @return    */   public Criteria distinct(Criteria criteria) {    criteria.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);    return criteria;   }     /**    * 为 Query 添加 distinct transformer    *     * @param query    * @return    */   public Query distinct(Query query) {    query.setResultTransformer(CriteriaSpecification.DISTINCT_ROOT_ENTITY);    return query;   }     /**    * 初始化对象. 使用 load() 方法得到的仅是对象的代理, 在传到视图层前需要进行初始化    *     * 只初始化 entity 的直接属性, 但不会初始化延迟加载的关联集合和属性 如需初始化关联属性, 可执行:    * Hibernate.initialize(user.getRoles());    *     * @param entity    */   public void initEntity(T entity) {    Hibernate.initialize(entity);   }     public void initEntity(List<T> entityList) {    for (T entity : entityList) {     Hibernate.initialize(entity);    }   }     /**    * 根据 Criterion 条件创建 Criteria    *     * @param criterions    * @return    */   public Criteria createCriteria(Criterion... criterions) {    Criteria criteria = getSession().createCriteria(entityClass);      for (Criterion c : criterions) {     criteria.add(c);    }      return criteria;   }     /**    * 按 Criteria 查询唯一对象    *     * @param criterions: 数量可变的 Criterion    * @return    */   public T findUnique(Criterion... criterions) {    return (T) createCriteria(criterions).uniqueResult();   }     /**    * 按 Criteria 查询对象列表    *     * @param criterions    *            : 数量可变的 Criterion    * @return    */   @SuppressWarnings("unchecked")   public List<T> find(Criterion... criterions) {    return createCriteria(criterions).list();   }     /**    * 根据查询 HQL 与参数列表创建 Query 对象    *     * @param queryString    * @param values    * @return    */   public Query createQuery(String queryString, Map<String, Object> values) {    // String hql = "FROM Employee e where e.loginname = :loginname";    Assert.hasText(queryString, "queryString不能为空");    Query query = getSession().createQuery(queryString);      if (values != null) {     query.setProperties(values);    }      return query;   }     /**    * 根据查询 HQL 与参数列表创建 Query 对象    *     * @param queryString    * @param values    *            : 数来那个可变的参数, 按顺序绑定    * @return    */   public Query createQuery(String queryString, Object... values) {    Assert.hasText(queryString, "queryString不能为空");    Query query = getSession().createQuery(queryString);      if (values != null) {     for (int i = 0; i < values.length; i++) {      query.setParameter(i, values[i]);     }    }      return query;   }     /**    * 执行 hql 进行批量修改/删除操作    *     * @param hql    * @param values    * @return    */   public int batchExecute(String hql, Map<String, Object> values) {    return createQuery(hql, values).executeUpdate();   }     /**    * 执行 hql 进行批量修改/删除操作    *     * @param hql    * @param values    * @return    */   public int batchExecute(String hql, Object... values) {    return createQuery(hql, values).executeUpdate();   }     /**    * 按 HQL 查询唯一对象    *     * @param <X>    * @param hql    * @param values    * @return    */   @SuppressWarnings("unchecked")   public <X> X findUnique(String hql, Map<String, Object> values) {    return (X) createQuery(hql, values).uniqueResult();   }     /**    * 按 HQL 查询唯一对象    *     * @param <X>    * @param hql    * @param values    * @return    */   @SuppressWarnings("unchecked")   public <X> X findUnique(String hql, Object... values) {    return (X) createQuery(hql, values).uniqueResult();   }     /**    * 按 HQL 查询对象列表    *     * @param <X>    * @param hql    * @param values    * @return    */   @SuppressWarnings("unchecked")   public <X> List<X> find(String hql, Map<String, Object> values) {    return createQuery(hql, values).list();   }     /**    * 按 HQL 查询对象列表    *     * @param <X>    * @param hql    * @param values    * @return    */   @SuppressWarnings("unchecked")   public <X> List<X> find(String hql, Object... values) {    return createQuery(hql, values).list();   }     /**    * 按 id 列表获取对象列表    *     * @param ids    * @return    */   public List<T> findByIds(List<?> ids) {    return find(Restrictions.in(getIdName(), ids));   }     /**    * 按属性查找唯一对象, 匹配方式为相等    *     * @param propertyName    * @param value    * @return    */   @SuppressWarnings("unchecked")   public T findUniqueBy(String propertyName, Object value) {    Assert.hasText(propertyName, "propertyName不能为空");    Criterion criterion = Restrictions.eq(propertyName, value);    return (T) createCriteria(criterion).uniqueResult();   }     /**    * 按属性查找对象列表, 匹配方式为相等    *     * @param propertyName    * @param value    * @return    */   public List<T> findBy(String propertyName, Object value) {    Assert.hasText(propertyName, "propertyName不能为空");      Criterion criterion = Restrictions.eq(propertyName, value);    return find(criterion);   }     /**    * 获取全部对象    *     * @return    */   public List<T> getAll() {    return find();   }  }

 来自:http://my.oschina.net/u/1453975/blog/335645