package com.mossle.core.hibernate; import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.util.List; import java.util.Map; import com.mossle.core.util.BeanUtils; import com.mossle.core.util.ReflectUtils; import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.SessionFactory; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.Order; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** * 提供基础功能方法的hibernate基类. * * @author Lingo */ public class HibernateGenericDao extends HibernateBasicDao { /** default constructor. */ public HibernateGenericDao() { } /** * constructor. * * @param sessionFactory * SessionFactory */ public HibernateGenericDao(SessionFactory sessionFactory) { super(sessionFactory); } // ============================================================================================ // createQuery // ============================================================================================ /** * 生成一个Query. * * @param hql * HQL语句 * @param values * 参数 * @return Query */ public Query createQuery(String hql, Object... values) { Assert.hasText(hql, "hql cannot be null"); Query query = this.getSession().createQuery(hql); for (int i = 0; i < values.length; i++) { query.setParameter(i, values[i]); } return query; } /** * create query by hql and map. * * @param hql * String * @param map * Map * @return Query */ public Query createQuery(String hql, Map<String, Object> map) { Assert.hasText(hql, "hql cannot be null"); Query query = this.getSession().createQuery(hql); if (map != null) { query.setProperties(map); } return query; } // ============================================================================================ // createCriteria // ============================================================================================ /** * 根据entityClass生成对应类型的Criteria. * * @param entityClass * 实体类型 * @param criterions * 条件 * @return Criteria */ public Criteria createCriteria(Class entityClass, Criterion... criterions) { Criteria criteria = this.getSession().createCriteria(entityClass); for (Criterion c : criterions) { criteria.add(c); } return criteria; } /** * 根据entityClass,生成带排序的Criteria. * * @param <T> * 实体类型 * @param entityClass * 类型 * @param orderBy * 排序字段名 * @param isAsc * 是否正序 * @param criterions * 条件 * @return Criteria */ public <T> Criteria createCriteria(Class<T> entityClass, String orderBy, boolean isAsc, Criterion... criterions) { if (StringUtils.hasText(orderBy)) { Criteria criteria = createCriteria(entityClass, criterions); if (isAsc) { criteria.addOrder(Order.asc(orderBy)); } else { criteria.addOrder(Order.desc(orderBy)); } return criteria; } else { return createCriteria(entityClass, criterions); } } // ============================================================================================ // find Criteria // ============================================================================================ /** * find by critrions. * * @param entityClass * Class * @param criterions * Criterion... * @param <T> * generic * @return List */ @Transactional(readOnly = true) public <T> List<T> find(Class<T> entityClass, Criterion... criterions) { return this.createCriteria(entityClass, criterions).list(); } /** * find unique by critrions. * * @param entityClass * Class * @param criterions * Criterion... * @param <T> * generic * @return T */ @Transactional(readOnly = true) public <T> T findUnique(Class<T> entityClass, Criterion... criterions) { return (T) createCriteria(entityClass, criterions).uniqueResult(); } // ============================================================================================ // find Query // ============================================================================================ /** * find by hql and values. * * @param hql * String * @param values * Object * @return List */ @Transactional(readOnly = true) public List find(String hql, Object... values) { return this.createQuery(hql, values).list(); } /** * find by hql and map. * * @param hql * String * @param map * Map * @return List */ @Transactional(readOnly = true) public List find(String hql, Map<String, Object> map) { return this.createQuery(hql, map).list(); } /** * 查询唯一记录. * * @param <T> * 实体类型 * @param hql * HQL字符串 * @param values * 参数 * @return 实例 */ @Transactional(readOnly = true) public <T> T findUnique(String hql, Object... values) { return (T) this.createQuery(hql, values).setMaxResults(1) .uniqueResult(); } /** * 查询唯一记录. * * @param <T> * 实体类型 * @param hql * HQL字符串 * @param map * Map * @return 实例 */ @Transactional(readOnly = true) public <T> T findUnique(String hql, Map<String, Object> map) { return (T) this.createQuery(hql, map).setMaxResults(1).uniqueResult(); } // ============================================================================================ // findBy // ============================================================================================ /** * 根据name,value进行查询. * * @param <T> * 实体类型 * @param entityClass * 实体类型 * @param name * 字段名 * @param value * 参数值 * @return 查询结果 */ @Transactional(readOnly = true) public <T> List<T> findBy(Class<T> entityClass, String name, Object value) { Assert.hasText(name, "property name cannot be null"); return this.createCriteria(entityClass, Restrictions.eq(name, value)) .list(); } /** * 根据name,value进行模糊查询. * * @param <T> * 实体类型 * @param entityClass * 实体类型 * @param name * 字段名 * @param value * 用来做模糊查询的字段值 * @return 查询结果 */ @Transactional(readOnly = true) public <T> List<T> findByLike(Class<T> entityClass, String name, Object value) { Assert.hasText(name, "property name cannot be null"); return this.createCriteria(entityClass, Restrictions.like(name, value)) .list(); } /** * find by ids. * * @param entityClass * Class * @param ids * List * @param <T> * generic * @return List */ @Transactional(readOnly = true) public <T> List<T> findByIds(Class<T> entityClass, List ids) { Assert.notEmpty(ids); String idName = this.getIdName(entityClass); Criterion criterion = Restrictions.in(idName, ids); return this.find(entityClass, criterion); } /** * 查询唯一记录. * * @param <T> * 实体类型 * @param entityClass * 实体类型 * @param name * 字段名 * @param value * 字段值 * @return 实例 */ @Transactional(readOnly = true) public <T> T findUniqueBy(Class<T> entityClass, String name, Object value) { return (T) this .createCriteria(entityClass, Restrictions.eq(name, value)) .setMaxResults(1).uniqueResult(); } // ============================================================================================ // isUnique // ============================================================================================ /** * 判断对象某些属性的值在数据库中是否唯一. * * @param entityClass * 实体类型 * @param entity * 实体对象 * @param uniquePropertyNames * 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password" * @param <T> * 实体类泛型 * @return 如果唯一返回true,否则返回false */ @Transactional(readOnly = true) public <T> boolean isUnique(Class<T> entityClass, T entity, String uniquePropertyNames) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { Assert.hasText(uniquePropertyNames); Criteria criteria = createCriteria(entityClass).setProjection( Projections.rowCount()); String[] nameList = uniquePropertyNames.split(","); // 循环加入唯一列 for (String name : nameList) { String getterMethodName = ReflectUtils.getGetterMethodName(entity, name); criteria.add(Restrictions.eq(name, BeanUtils.invokeMethod(entity, getterMethodName))); } // 以下代码为了如果是update的情况,排除entity自身. String idName = getIdName(entityClass); // 取得entity的主键值 Serializable id = getId(entityClass, entity); // 如果id!=null,说明对象已存在,该操作为update,加入排除自身的判断 if (id != null) { criteria.add(Restrictions.not(Restrictions.eq(idName, id))); } Object result = criteria.uniqueResult(); return HibernateUtils.getNumber(result) == 0; } // ============================================================================================ // getCount // ============================================================================================ /** * 获得总记录数. * * @param <T> * 实体类型 * @param entityClass * 实体类型 * @return 总数 */ @Transactional(readOnly = true) public <T> Integer getCount(Class<T> entityClass) { return this.getCount(this.createCriteria(entityClass)); } /** * 获得总记录数. * * @param criteria * 条件 * @return 总数 */ @Transactional(readOnly = true) public Integer getCount(Criteria criteria) { Object result = criteria.setProjection(Projections.rowCount()) .uniqueResult(); return HibernateUtils.getNumber(result); } /** * 获得总记录数. * * @param hql * HQL字符串 * @param values * 参数 * @return 总数 */ @Transactional(readOnly = true) public Integer getCount(String hql, Object... values) { Object result = createQuery(hql, values).uniqueResult(); return HibernateUtils.getNumber(result); } /** * 获得总记录数. * * @param hql * HQL字符串 * @param map * Map * @return 总数 */ @Transactional(readOnly = true) public Integer getCount(String hql, Map<String, Object> map) { Object result = createQuery(hql, map).uniqueResult(); return HibernateUtils.getNumber(result); } // ============================================================================================ // batchUpdate // ============================================================================================ /** * batch update by hql and objects. * * @param hql * String * @param values * Object * @return int */ @Transactional public int batchUpdate(String hql, Object... values) { return this.createQuery(hql, values).executeUpdate(); } /** * batch update by hql and map. * * @param hql * String * @param map * Map * @return int */ @Transactional public int batchUpdate(String hql, Map<String, Object> map) { return this.createQuery(hql, map).executeUpdate(); } }