/* -------------------------------------- * CREATED ON 2007-11-26 10:46:09 * * MSN ardenemily@msn.com * QQ 83058327(太阳里的雪) * MOBILE 13590309275 * BLOG http://www.caojianghua.com * * ALL RIGHTS RESERVED BY ZHENUU CO,.LTD. * -------------------------------------- */ package com.jrails.modules.orm.hibernate; import com.jrails.commons.utils.*; import com.jrails.modules.orm.EntityManager; import com.jrails.modules.orm.model.Entity; import com.jrails.page.TablePage; import java.io.Serializable; import java.sql.SQLException; import java.util.Collection; import java.util.List; import java.lang.InstantiationException; import org.hibernate.*; import org.hibernate.criterion.CriteriaSpecification; import org.hibernate.criterion.DetachedCriteria; import org.hibernate.criterion.Projections; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.support.incrementer.AbstractDataFieldMaxValueIncrementer; import org.springframework.orm.hibernate3.HibernateCallback; import org.springframework.orm.hibernate3.HibernateTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; /** * 泛型实体管理器 * * @author <a href="mailto:arden.emily@gmail.com">arden</a> */ @SuppressWarnings("unchecked") public abstract class GenericEntityManager<T extends Entity> extends HibernateTemplate implements EntityManager<T> { private AbstractDataFieldMaxValueIncrementer sequence; @Override public Serializable save(Object entity) throws DataAccessException { // TODO Auto-generated method stub return super.save(entity); } /** * 批量保存 * * @param entities */ @SuppressWarnings("unchecked") public void batchSave(final Collection entities) { this.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { if (CollectionUtils.isNotEmpty(entities)) { int max = CollectionUtils.size(entities); int i = 0; for (Object t : entities) { session.save(t); if ((i != 0 && i % CoreConstants.DEFAULT_BATCH_SIZE.getValue() == 0) || i == max - 1) { session.flush(); session.clear(); } i++; } } return null; } }); } /** * 批量删除 * * @param entities */ @SuppressWarnings("unchecked") public void batchRemove(final Collection entities) { this.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { if (CollectionUtils.isNotEmpty(entities)) { int max = CollectionUtils.size(entities); int i = 0; for (Object t : entities) { session.refresh(t); session.delete(t); if ((i != 0 && i % CoreConstants.DEFAULT_BATCH_SIZE.getValue() == 0) || i == max - 1) { session.flush(); session.clear(); } i++; } } return null; } }); } /** * 批量更新 * * @param entities */ @SuppressWarnings("unchecked") public void batchUpdate(final Collection entities) { this.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { if (CollectionUtils.isNotEmpty(entities)) { int max = CollectionUtils.size(entities); int i = 0; for (Object t : entities) { session.update(t); if ((i != 0 && i % CoreConstants.DEFAULT_BATCH_SIZE.getValue() == 0) || i == max - 1) { session.flush(); session.clear(); } i++; } } return null; } }); } /** * 执行HQL语句 * * @param hql * @param cacheable * @param values * @return */ public int executeByHql(final String hql, final boolean cacheable, final Object... values) { Integer count = (Integer)this.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { Query query = session.createQuery(hql); prepareQuery(query); if (cacheable) { query.setCacheable(true); //query.setCacheRegion(""); } if (values != null) { for (int i = 0; i < values.length; i++) { query.setParameter(i, values[i]); } } return query.executeUpdate(); } }); return count == null ? 0 : count.intValue(); } /** * 执行SQL语句 * * @param sql * @param cacheable * @param values * @return */ public int executeBySql(final String sql, final boolean cacheable, final Object... values) { Integer count = (Integer)this.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { Query query = session.createSQLQuery(sql); prepareQuery(query); if (cacheable) { query.setCacheable(true); //query.setCacheRegion(""); } if (values != null) { for (int i = 0; i < values.length; i++) { query.setParameter(i, values[i]); } } return query.executeUpdate(); } }); return count == null ? 0 : count.intValue(); } /** * 根据指定的HQ语句查询记录条数 * * @param hql * @param values * @return */ public int countByHql(final String hql, final boolean cacheable, final Object... values) { Long count = (Long) this.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { Query query = session.createQuery(hql); prepareQuery(query); if (cacheable) { query.setCacheable(cacheable); } if (values != null) { for (int i = 0; i < values.length; i++) { query.setParameter(i, values[i]); } } return query.uniqueResult(); } }); return count == null ? 0 : count.intValue(); } /** * 根据指定的SQL语句查询记录条数 * * @param sql * @param values * @return */ public int countBySql(final String sql, final boolean cacheable, final Object... values) { Long count = (Long) this.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException { Query query = session.createSQLQuery(sql).addScalar("count(*)", Hibernate.LONG); prepareQuery(query); if (cacheable) { query.setCacheable(cacheable); } if (values != null) { for (int i = 0; i < values.length; i++) { query.setParameter(i, values[i]); } } return query.uniqueResult(); } }); return count == null ? 0 : count.intValue(); } /** * 根据指定的属性查询 * * @param propertyName * @param value * @param rowStartIdxAndCount * @return */ @SuppressWarnings("unchecked") public List<T> findByProperty(Class entityClass, String propertyName, final Object value, final boolean cacheable, final int... rowStartIdxAndCount) { String className = entityClass.getSimpleName(); try { final String queryString = "from " + className + " where " + propertyName + "= :propertyValue"; return (List<T>) execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { Query query = session.createQuery(queryString); prepareQuery(query); if (cacheable) { query.setCacheable(cacheable); } query.setParameter("propertyValue", value); if (rowStartIdxAndCount != null && rowStartIdxAndCount.length > 0) { int rowStartIdx = Math.max(0, rowStartIdxAndCount[0]); if (rowStartIdx > 0) { query.setFirstResult(rowStartIdx); } if (rowStartIdxAndCount.length > 1) { int rowCount = Math.max(0, rowStartIdxAndCount[1]); if (rowCount > 0) { query.setMaxResults(rowCount); } } } return (List<T>) query.list(); } }); } catch (RuntimeException re) { logger.error("find by property name failed", re); throw re; } } /** * 查询所有 * * @param * @return */ @SuppressWarnings("unchecked") public TablePage<T> findAll(Class entityClass, final TablePage<T> page, final boolean cacheable) { final String className = entityClass.getSimpleName(); logger.info("finding all " + className + " instances"); try { final String queryString = "from " + className; return this.findByHql(queryString, page, cacheable); } catch (RuntimeException re) { logger.error("find all failed", re); throw re; } } /** * 根据指定的HQL查询 * * @param hql * @param page * @param cacheable * @param values * @return */ @SuppressWarnings("unchecked") public TablePage<T> findByHql(final String hql, final TablePage<T> page, final boolean cacheable, final Object... values) { try { return (TablePage<T>) this.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { int startIndex = page.getFirst(); int count = page.getPageSize(); String countHql = SqlStringUtils.getCountString(hql); int totalCount = countByHql(countHql, cacheable, values); Query query = session.createQuery(hql); prepareQuery(query); if (cacheable) { query.setCacheable(cacheable); } if (values != null) { for (int i = 0; i < values.length; i++) { query.setParameter(i, values[i]); } } query.setFirstResult(startIndex); query.setMaxResults(count); page.setResult(query.list()); page.setTotalCount((int) totalCount); return page; } }); } catch (RuntimeException re) { logger.error("find all failed", re); throw re; } } /** * 根据HQL语句查询 * @param hql * @param page * @param cacheable * @param countHql * @param values * @return */ public TablePage<T> findByHql(final String hql, final String countHql, final boolean countBySql, final TablePage<T> page, final boolean cacheable, final Object... values) { try { return (TablePage<T>) this.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { int startIndex = page.getFirst(); int count = page.getPageSize(); String theCountHql = countHql; if (StringUtils.isEmpty(countHql)) { theCountHql = SqlStringUtils.getCountString(hql); } int totalCount = 0; if (countBySql) { totalCount = countBySql(theCountHql, cacheable, values); } else { totalCount = countByHql(theCountHql, cacheable, values); } Query query = session.createQuery(hql); prepareQuery(query); if (cacheable) { query.setCacheable(cacheable); } if (values != null) { for (int i = 0; i < values.length; i++) { query.setParameter(i, values[i]); } } query.setFirstResult(startIndex); query.setMaxResults(count); page.setResult(query.list()); page.setTotalCount((int) totalCount); return page; } }); } catch (RuntimeException re) { logger.error("find all failed", re); throw re; } } /** * 根据指定的SQL分页查询 * * @param sql * @param page * @param cacheable * @param values * @return */ @SuppressWarnings("unchecked") public TablePage<T> findBySql(final String sql, final TablePage<T> page, final boolean cacheable, final Object... values) { try { return (TablePage<T>) this.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { int startIndex = page.getFirst(); int count = page.getPageSize(); String countHql = SqlStringUtils.getCountString(sql); int totalCount = countBySql(countHql, cacheable, values); Query query = session.createSQLQuery(sql); prepareQuery(query); if (cacheable) { query.setCacheable(cacheable); } if (values != null) { for (int i = 0; i < values.length; i++) { query.setParameter(i, values[i]); } } query.setFirstResult(startIndex); query.setMaxResults(count); page.setResult(query.list()); page.setTotalCount((int) totalCount); return page; } }); } catch (RuntimeException re) { logger.error("find all failed", re); throw re; } } /** * 根据Criteria查找 * * @param detachedCriteria * @param page * @param cacheable * @return */ @SuppressWarnings("unchecked") public TablePage<T> findByCriteria(final DetachedCriteria detachedCriteria, final TablePage<T> page, final boolean cacheable) { try { return (TablePage<T>) this.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { int startIndex = page.getFirst(); int count = page.getPageSize(); Criteria criteria = detachedCriteria.getExecutableCriteria(session); if (cacheable) { criteria.setCacheable(cacheable); } int totalCount = ((Integer) criteria.setProjection(Projections.rowCount()).uniqueResult()).intValue(); page.setTotalCount(totalCount); criteria.setProjection(null); detachedCriteria.setResultTransformer(CriteriaSpecification.ROOT_ENTITY); List records = criteria.setFirstResult(startIndex).setMaxResults(count).list(); page.setResult(records); return page; } }); } catch (RuntimeException re) { logger.error("find all failed", re); throw re; } } /** * 设置序列号生成器 */ public void setSequence(AbstractDataFieldMaxValueIncrementer sequence) { this.sequence = sequence; } /** * 根据HQL语句查找第一个元素 * * @param hql * @param cacheable * @param values * @return */ @SuppressWarnings("unchecked") public T findFirstByHql(String hql, boolean cacheable, Object... values) { List<T> records = this.findByHql(hql, cacheable, values); return this.first(records); } /** * 根据SQL语句查找第一个元素 * * @param sql * @param cacheable * @param values * @return */ @SuppressWarnings("unchecked") public T findFirstBySql(final String sql, final boolean cacheable, final Object... values) { List<T> records = this.findBySql(sql, cacheable, values); return this.first(records); } /** * 获得列表里的第一个元素 * * @param list * @return */ @SuppressWarnings("unchecked") protected T first(List<T> list) { if (list == null || list.isEmpty()) { return null; } return (T) list.get(0); } /** * 根据指定的模型生成ID * * @param * @return */ @SuppressWarnings("unchecked") public Long generateId() { T model = null; Class<T> entityClass = GenericsUtils.getSuperClassGenricType(this.getClass()); try { if (model == null) { model = entityClass.newInstance(); } } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } String sequenceName = model.getSequenceName(); this.sequence.setIncrementerName(sequenceName); long id = this.sequence.nextLongValue(); return id; } public List<T> findByHql(final String hql, final boolean cacheable, final Object... values) { try { return (List<T>) this.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { Query query = session.createQuery(hql); prepareQuery(query); if (cacheable) { query.setCacheable(cacheable); } if (values != null) { for (int i = 0; i < values.length; i++) { query.setParameter(i, values[i]); } } return query.list(); } }); } catch (RuntimeException re) { logger.error("find all failed", re); throw re; } } public List<T> findBySql(final String sql, final boolean cacheable, final Object... values) { try { return (List<T>) this.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { Query query = session.createSQLQuery(sql); prepareQuery(query); if (cacheable) { query.setCacheable(cacheable); } if (values != null) { for (int i = 0; i < values.length; i++) { query.setParameter(i, values[i]); } } return query.list(); } }); } catch (RuntimeException re) { re.printStackTrace(); logger.error("find all failed", re); throw re; } } public List<T> findAll(Class entityClass, final boolean cacheable) { final String className = entityClass.getSimpleName(); logger.info("finding all " + className + " instances"); try { final String queryString = "from " + className; return this.findByHql(queryString, cacheable); } catch (RuntimeException re) { logger.error("find all failed", re); throw re; } } /** * 获得指定多少条记录 * @param hql * @param limit * @param cacheable * @param values * @return */ public List<T> findLimitByHql(final String hql, final int limit, final boolean cacheable, final Object... values) { try { return (List<T>) this.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { Query query = session.createQuery(hql); prepareQuery(query); if (cacheable) { query.setCacheable(cacheable); } if (values != null) { for (int i = 0; i < values.length; i++) { query.setParameter(i, values[i]); } } query.setFirstResult(0); query.setMaxResults(limit); return query.list(); } }); } catch (RuntimeException re) { logger.error("find all failed", re); throw re; } } /** * 获得指定多少条记录 * @param sql * @param limit * @param cacheable * @param values * @return */ public List<T> findLimitBySql(final String sql, final int limit, final boolean cacheable, final Object... values) { try { return (List<T>) this.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { Query query = session.createSQLQuery(sql); prepareQuery(query); if (cacheable) { query.setCacheable(cacheable); } if (values != null) { for (int i = 0; i < values.length; i++) { query.setParameter(i, values[i]); } } query.setFirstResult(0); query.setMaxResults(limit); return query.list(); } }); } catch (RuntimeException re) { logger.error("find all failed", re); throw re; } } }