Java tutorial
/** * Copyright (c) 2005-2010 springside.org.cn * * Licensed under the Apache License, Version 2.0 (the "License"); * * $Id: HibernateDao.java 1205 2010-09-09 15:12:17Z xiaoxiu $ */ package com.macrosoft.core.orm.hibernate; import java.io.Serializable; import java.lang.reflect.InvocationTargetException; import java.sql.ResultSet; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import java.util.Map; 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.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.criterion.CriteriaSpecification; import org.hibernate.criterion.Criterion; import org.hibernate.criterion.Disjunction; import org.hibernate.criterion.MatchMode; import org.hibernate.criterion.Order; import org.hibernate.criterion.Projection; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.hibernate.internal.CriteriaImpl; import org.hibernate.metadata.ClassMetadata; import org.hibernate.transform.ResultTransformer; import org.springframework.util.Assert; import com.macrosoft.common.collection.CollectionUtils; import com.macrosoft.common.constant.CommonConst; import com.macrosoft.common.reflection.ReflectionUtils; import com.macrosoft.core.BaseForm; import com.macrosoft.core.EntityDao; import com.macrosoft.core.HqlCondition; import com.macrosoft.core.PropertyFilter; import com.macrosoft.core.PropertyFilter.MatchType; import com.macrosoft.core.orm.Page; /** * ?SpringSideHibernat DAO. * * ,?. ?Service,?DAO?,?. * * @param <T> * DAO? * @param <PK> * * * @author xiao */ public class HibernateDao<T, PK extends Serializable> extends SimpleHibernateDao<T, PK> implements EntityDao<T> { private static Long ZERO_LONG = new Long(0); private static Integer ZERO_INT = new Integer(0); private static String ZERO_STRING = new String(""); protected Log log = LogFactory.getLog(getClass()); private Boolean isCache = true; /** * Dao?. ??Class. eg. public class UserDao extends * HibernateDao<User, Long>{ } */ public HibernateDao() { super(); } /** * ?Dao, ServiceHibernateDao. Class. eg. * HibernateDao<User, Long> userDao = new HibernateDao<User, * Long>(sessionFactory, User.class); */ public HibernateDao(final SessionFactory sessionFactory, final Class<T> entityClass) { super(sessionFactory, entityClass); } // -- --// /** * ?. */ public Page<T> getAll(final Page<T> page) { return findPage(page); } /** * HQL. * * @param page * ?. ???orderBy?. * @param hql * hql?. * @param values * ????,?. * * @return , ??. */ @SuppressWarnings("unchecked") public Page<T> findPage(final Page<T> page, final String hql) { Assert.notNull(page, "page?"); Query q = createQuery(hql); if (page.isAutoCount()) { long totalCount = countHqlResult(hql); page.setTotalCount(totalCount); } setPageParameterToQuery(q, page); List result = q.list(); page.setData(result); return page; } /** * HQL. * * @param page * ?. ???orderBy?. * @param hql * hql?. * @param values * ????,?. * * @return , ??. */ @SuppressWarnings("unchecked") public Page<T> findPage(final Page<T> page, final String hql, final Object... values) { Assert.notNull(page, "page?"); Query q = createQuery(hql, values); if (page.isAutoCount()) { long totalCount = countHqlResult(hql, values); page.setTotalCount(totalCount); } setPageParameterToQuery(q, page); List result = q.list(); page.setData(result); return page; } /** * HQL. * * @param page * ?. ???orderBy?. * @param hql * hql?. * @param values * ???,??. * * @return , ??. */ @SuppressWarnings("unchecked") public Page<T> findPage(final Page<T> page, final String hql, final Map<String, ?> values) { Assert.notNull(page, "page?"); Query q = createQuery(hql, values); if (page.isAutoCount()) { long totalCount = countHqlResult(hql, values); page.setTotalCount(totalCount); } setPageParameterToQuery(q, page); List result = q.list(); page.setData(result); return page; } /** * Criteria. * * @param page * ?. * @param criterions * ???Criterion. * * @return .??. */ @SuppressWarnings("unchecked") public Page<T> findPage(final Page<T> page, final Criterion... criterions) { Assert.notNull(page, "page?"); Criteria c = createCriteria(criterions); if (page.isAutoCount()) { long totalCount = countCriteriaResult(c); page.setTotalCount(totalCount); } setPageParameterToCriteria(c, page); List result = c.list(); page.setData(result); return page; } /** * ?Query,. */ protected Query setPageParameterToQuery(final Query q, final Page<T> page) { Assert.isTrue(page.getPageSize() > 0, "Page Size must larger than zero"); // hibernatefirstResult??0 q.setFirstResult(page.getFirst() - 1); q.setMaxResults(page.getPageSize()); return q; } /** * ?Criteria,. */ protected Criteria setPageParameterToCriteria(final Criteria c, final Page<T> page) { Assert.isTrue(page.getPageSize() > 0, "Page Size must larger than zero"); // hibernatefirstResult??0 c.setFirstResult(page.getFirst() - 1); c.setMaxResults(page.getPageSize()); if (page.isOrderBySetted()) { String[] orderByArray = StringUtils.split(page.getOrderBy(), ','); String[] orderArray = StringUtils.split(page.getOrder(), ','); Assert.isTrue(orderByArray.length == orderArray.length, "???,????"); for (int i = 0; i < orderByArray.length; i++) { if (Page.ASC.equals(orderArray[i])) { c.addOrder(Order.asc(orderByArray[i])); } else { c.addOrder(Order.desc(orderByArray[i])); } } } return c; } /** * countHql. * * ???hql?,??hql?count?. */ protected long countHqlResult(final String hql) { String countHql = prepareCountHql(hql); try { Long count = findUnique(countHql); return count; } catch (Exception e) { throw new RuntimeException("hql can't be auto count, hql is:" + countHql, e); } } /** * countHql. * * ???hql?,??hql?count?. */ protected long countHqlResult(final String hql, final Object... values) { String countHql = prepareCountHql(hql); try { Long count = findUnique(countHql, values); return count; } catch (Exception e) { throw new RuntimeException("hql can't be auto count, hql is:" + countHql, e); } } /** * countHql. * * ???hql?,??hql?count?. */ protected long countHqlResult(final String hql, final Map<String, ?> values) { String countHql = prepareCountHql(hql); try { Long count = findUnique(countHql, values); return count; } catch (Exception e) { throw new RuntimeException("hql can't be auto count, hql is:" + countHql, e); } } private String prepareCountHql(String orgHql) { String fromHql = orgHql; // select??order by???count,?. fromHql = "from " + StringUtils.substringAfter(fromHql, "from"); fromHql = StringUtils.substringBefore(fromHql, "order by"); String countHql = "select count(*) " + fromHql; return countHql; } /** * countCriteria. */ @SuppressWarnings("unchecked") protected long countCriteriaResult(final Criteria c) { CriteriaImpl impl = (CriteriaImpl) c; // Projection?ResultTransformer?OrderBy??,??Count? Projection projection = impl.getProjection(); ResultTransformer transformer = impl.getResultTransformer(); List<CriteriaImpl.OrderEntry> orderEntries = null; try { orderEntries = (List) ReflectionUtils.getFieldValue(impl, "orderEntries"); ReflectionUtils.setFieldValue(impl, "orderEntries", new ArrayList()); } catch (Exception e) { logger.error("??:{}", e.getMessage()); } // Count Long totalCountObject = (Long) c.setProjection(Projections.rowCount()).uniqueResult(); long totalCount = (totalCountObject != null) ? totalCountObject : 0; // ?Projection,ResultTransformerOrderBy?? c.setProjection(projection); if (projection == null) { c.setResultTransformer(CriteriaSpecification.ROOT_ENTITY); } if (transformer != null) { c.setResultTransformer(transformer); } try { ReflectionUtils.setFieldValue(impl, "orderEntries", orderEntries); } catch (Exception e) { logger.error("??:{}", e.getMessage()); } return totalCount; } // -- ?(PropertyFilter) --// /** * ,????. * * @param matchType * ??,????PropertyFilterMatcheType enum. */ public List<T> findBy(final String propertyName, final Object value, final MatchType matchType) { Criterion criterion = buildCriterion(propertyName, value, matchType); return find(criterion); } /** * ?. */ public List<T> find(List<PropertyFilter> filters) { Criterion[] criterions = buildCriterionByPropertyFilter(filters); return find(criterions); } /** * ?. */ public Page<T> findPage(final Page<T> page, final List<PropertyFilter> filters) { Criterion[] criterions = buildCriterionByPropertyFilter(filters); return findPage(page, criterions); } /** * ??Criterion,. */ protected Criterion buildCriterion(final String propertyName, final Object propertyValue, final MatchType matchType) { Assert.hasText(propertyName, "propertyName?"); Criterion criterion = null; // ?MatchTypecriterion switch (matchType) { case EQ: criterion = Restrictions.eq(propertyName, propertyValue); break; case LIKE: criterion = Restrictions.like(propertyName, (String) propertyValue, MatchMode.ANYWHERE); break; case LE: criterion = Restrictions.le(propertyName, propertyValue); break; case LT: criterion = Restrictions.lt(propertyName, propertyValue); break; case GE: criterion = Restrictions.ge(propertyName, propertyValue); break; case GT: criterion = Restrictions.gt(propertyName, propertyValue); } return criterion; } /** * ?Criterion,. */ protected Criterion[] buildCriterionByPropertyFilter(final List<PropertyFilter> filters) { List<Criterion> criterionList = new ArrayList<Criterion>(); for (PropertyFilter filter : filters) { if (!filter.hasMultiProperties()) { // ??. Criterion criterion = buildCriterion(filter.getPropertyName(), filter.getMatchValue(), filter.getMatchType()); criterionList.add(criterion); } else {// ??,or?. Disjunction disjunction = Restrictions.disjunction(); for (String param : filter.getPropertyNames()) { Criterion criterion = buildCriterion(param, filter.getMatchValue(), filter.getMatchType()); disjunction.add(criterion); } criterionList.add(disjunction); } } return criterionList.toArray(new Criterion[criterionList.size()]); } /** * ,?? * * @param father_id * @return */ public T getById(Object id) { T result = null; Class idClass = null; try { if (id != null) { // ??entity try { String idName = getIdName(entityClass); idClass = ReflectionUtils.getPropertyType(entityClass, idName); } catch (Exception e) { log.error(e, e); } if (idClass.isInstance(ZERO_STRING) == true) { String key = (String) id; if (StringUtils.isEmpty(key) == false) { result = findUniqueBy("id", id); } } else { if (idClass.isInstance(ZERO_LONG) == true) { if (((Long) id).longValue() > 0) { result = findUniqueBy("id", id); } } else { if (idClass.isInstance(ZERO_INT) == true) { if (((Integer) id).intValue() > 0) { result = findUniqueBy("id", id); } } else { result = findUniqueBy("id", id); } } } } } catch (Exception ex) { log.error(ex, ex); } return result; } /** * * @param code * @return * @throws Exception */ public T getByCode(String code) throws Exception { T result = null; try { if (StringUtils.isEmpty(code) == false) { result = findUniqueBy("code", code); } } catch (Exception ex) { log.error(ex); } return result; } /** * ? * * @param temp * @return 0? */ public BaseForm create(final T entity) throws Exception { BaseForm result = new BaseForm(); int temp = -1; try { result.setSuccess(false); save(entity); result.setSuccess(true); temp = 1; result.setResultInt(temp); } catch (Exception ex) { temp = -1; result.setSuccess(false); result.setResultInt(temp); log.error(ex); throw ex; } return result; } /** * ? * * @param temp * @return 0? */ public BaseForm update(final T entity) throws Exception { BaseForm result = new BaseForm(); int temp = -1; try { result.setSuccess(false); save(entity); result.setSuccess(true); temp = 1; result.setResultInt(temp); } catch (Exception ex) { temp = -1; result.setSuccess(false); result.setResultInt(temp); log.error(ex); throw ex; } return result; } /** * . * * @param entity * session?idtransient. */ public void delete(final T entity) { super.delete(entity); } /** * ? * * @param ids * ??id, ":" * @param temp * @return */ public BaseForm delete(Object ids, final T temp) throws Exception { BaseForm result = new BaseForm(); List dataList = null; String[] idArr = null; try { result.setSuccess(false); if (ids != null) { if (ids instanceof String) { String key = (String) ids; if (StringUtils.isEmpty(key) == false) { idArr = com.macrosoft.common.string.StringUtils.strToArray(key, CommonConst.SYS_SPLIT_COLON); if (idArr != null && idArr.length > 0) { dataList = getList(key, temp); if (dataList != null && dataList.size() > 0) { // ? ? int size = dataList.size(); size = dataList.size(); for (int i = 0; i < size; i++) { delete((T) dataList.get(i)); } result.setSuccess(true); } } } } } } catch (Exception ex) { result.setSuccess(false); log.error(ex); } finally { idArr = null; CollectionUtils.clearList(dataList); dataList = null; } return result; } /** * ? * * @param form * @param pageNo * @param pageSize * @return */ public Page listPage(T form, int pageNo, int pageSize) throws Exception { Page result = null; Page page = null; HqlCondition condition = null; List param = null; try { page = new Page(); page.setPageNo(pageNo); page.setPageSize(pageSize); condition = new HqlCondition(); condition.setSelStr(" select table_entity"); condition.setFromStr(" from " + form.getClass()); condition.setWhereStr(" where 1=1 "); if (form != null) { param = new ArrayList(); } result = findPage(page, condition.toString(), param); } catch (Exception ex) { log.error(ex); } finally { condition = null; CollectionUtils.clearList(param); param = null; } return result; } /** * * @param module_id * ??id,:'1','2','3' :??id,:1:2:3 * @return */ public List getList(String module_id, final T temp) throws Exception { HqlCondition condition = null; Object[] paramValueArr = null; List result = null; String[] ids = null; Class idClass = null; String idName = null; try { // ???,??? if (StringUtils.isEmpty(module_id) == false) { condition = new HqlCondition(); condition.setSelStr(" select table_entity "); condition.setFromStr(" from " + temp.getClass().getName() + " as table_entity "); if (module_id.indexOf(",") > 0) { condition.setWhereStr(" where id in (" + module_id + ")"); } else { ids = com.macrosoft.common.string.StringUtils.strToArray(module_id, CommonConst.SYS_SPLIT_COLON); if (ids != null && ids.length > 0) { // ??entity try { idName = getIdName(entityClass); idClass = ReflectionUtils.getPropertyType(entityClass, idName); } catch (Exception e) { idName = "id"; } paramValueArr = new Object[ids.length]; condition.setWhereStr(" where "); for (int i = 0; i < ids.length; i++) { if (i > 0) { condition.setWhereStr(" or "); } condition.setWhereStr(idName + "=?"); if (idClass.isInstance(ZERO_INT) == true) { paramValueArr[i] = Integer.parseInt(ids[i]); } else { if (idClass.isInstance(ZERO_LONG) == true) { paramValueArr[i] = Long.parseLong(ids[i]); } else { paramValueArr[i] = ids[i]; } } } } } result = this.find(condition.toString(), paramValueArr); } } catch (Exception ex) { log.error(ex); throw ex; } finally { condition = null; paramValueArr = null; ids = null; } return result; } /** * ??,. */ public int getNextSeqNo(String entityName) { Assert.notNull(entityName); int retval = 1; // Count String countQueryString = "select max(seqNo) from " + entityName; Query q = createQuery(countQueryString); if (q.uniqueResult() != null) { retval = ((Integer) q.uniqueResult()).intValue() + 1; } return retval; } /** * ??,. */ public int getNextSeqNo(String entityName, String parentCode) { Assert.notNull(entityName); int retval = 1; // Count String countQueryString = "select max(seqNo) from " + entityName + " where parentCode = '" + parentCode + "'"; Query q = createQuery(countQueryString); if (q.uniqueResult() != null) { retval = ((Integer) q.uniqueResult()).intValue() + 1; } return retval; } /** * Criteria. * * @param criterions * ??Restrictions?,?{@link #createQuery(String,Object...)} */ public <T> Criteria createCriteria(Class<T> entityClass, Criterion... criterions) { Criteria criteria = getSession().createCriteria(entityClass); for (Criterion c : criterions) { criteria.add(c); } return criteria.setCacheable(isCache); } /** * ???. * * @param uniquePropertyNames * POJO???,? "name,loginid,password" */ public <T> boolean isUnique(Class<T> entityClass, Object entity, String uniquePropertyNames) { Assert.hasText(uniquePropertyNames); Criteria criteria = createCriteria(entityClass).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(entityClass); // ?entity Serializable id = getId(entityClass, entity); // id!=null,,?update, if (id != null) criteria.add(Restrictions.not(Restrictions.eq(idName, id))); } catch (Exception e) { e.printStackTrace(); } return (Integer) criteria.uniqueResult() == 0; } /** * ??. * * @param uniquePropertyNames * POJO???,? "name,loginid,password" * @see HibernateGenericDao#isUnique(Class,Object,String) */ public boolean isUnique(Object entity, String uniquePropertyNames) { return isUnique(getEntityClass(), entity, uniquePropertyNames); } /** * ?entityClass.JDK1.4????Class<T> entityClass,?? */ protected Class<T> getEntityClass() { return entityClass; } /** * ?,. */ public Serializable getId(Class entityClass, Object entity) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { Assert.notNull(entity); Assert.notNull(entityClass); return (Serializable) PropertyUtils.getProperty(entity, getIdName(entityClass)); } /** * ???,. */ public String getIdName(Class 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; } public Boolean getIsCache() { return isCache; } public void setIsCache(Boolean isCache) { this.isCache = isCache; } /** * ?hql?:select max("+idClassName+") from "+entity+" where * "+idClassName+">0 " * * @param idClassName * id??,id * @param entity * @return */ public Integer getMax(String idClassName, final T entity) { Integer result = null; List list = null; String[] paramArr = null; try { String hql = "select max(" + idClassName + ") from " + entity.getClass().getName() + " where " + idClassName + ">0 "; list = this.find(hql, paramArr); if (list != null && list.size() > 0) { if (list.get(0) instanceof Integer) { result = (Integer) list.get(0) + 1; } else { if (list.get(0) instanceof Long) { Long temp = (Long) list.get(0); result = new Integer(temp.intValue() + 1); } else { result = new Integer(1); } } } } catch (RuntimeException ex) { log.error(ex); } finally { CollectionUtils.clearList(list); list = null; } return result; } /** * ?hql?:select max("+idClassName+") from "+entity+" where * "+idClassName+">0 " * * @param idClassName * id??,id * @param entity * @return */ public Long getMaxLong(String idClassName, final T entity) { Long result = null; List list = null; String[] paramArr = null; try { String hql = "select max(" + idClassName + ") from " + entity.getClass().getName() + " where " + idClassName + ">0 "; list = this.find(hql, paramArr); if (list != null && list.size() > 0) { if (list.get(0) instanceof Integer) { Integer temp = (Integer) list.get(0); result = new Long(temp.intValue() + 1); } else { if (list.get(0) instanceof Long) { result = (Long) list.get(0) + 1; } else { result = new Long(1); } } } } catch (RuntimeException ex) { log.error(ex, ex); } finally { CollectionUtils.clearList(list); list = null; } return result; } /** * ?? by rhine */ protected void doClose(Session session, Statement stmt, ResultSet rs) { if (rs != null) { try { rs.close(); rs = null; } catch (Exception ex) { rs = null; log.error(ex, ex); ex.printStackTrace(); } } // Statement,?ResultSet if (stmt != null) { try { stmt.close(); stmt = null; } catch (Exception ex) { stmt = null; log.error(ex, ex); ex.printStackTrace(); } } // HibernateSpring,sessionSpring?.? // if(session != null){ // session.close(); // } } }