package common.base; import static cn.org.rapid_framework.util.SqlRemoveUtils.removeFetchKeyword; import static cn.org.rapid_framework.util.SqlRemoveUtils.removeOrders; import static cn.org.rapid_framework.util.SqlRemoveUtils.removeSelect; import java.io.Serializable; import java.sql.SQLException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.Criteria; import org.hibernate.HibernateException; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.criterion.Expression; import org.hibernate.criterion.Projections; import org.hibernate.criterion.Restrictions; import org.springframework.dao.support.DataAccessUtils; import org.springframework.orm.ObjectRetrievalFailureException; import org.springframework.orm.hibernate3.HibernateCallback; import org.springframework.orm.hibernate3.HibernateTemplate; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; import org.springframework.util.Assert; import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; import cn.org.rapid_framework.page.Page; import cn.org.rapid_framework.page.PageRequest; /** * @author badqiu */ public abstract class BaseHibernateDao<E, PK extends Serializable> extends HibernateDaoSupport implements EntityDao<E, PK> { /** * Logger for subclass */ protected Log log = LogFactory.getLog(getClass()); public long queryForLong(final String queryString) { return queryForLong(queryString, new Object[]{}); } public long queryForLong(final String queryString, Object value) { return queryForLong(queryString, new Object[]{value}); } public long queryForLong(final String queryString, Object[] values) { return DataAccessUtils.longResult(getHibernateTemplate().find( queryString, values)); } /** * 得到全部数据,但执行分页 * * @param pageRequest * @return */ public Page findAll(final PageRequest pageRequest) { return (Page) getHibernateTemplate().executeFind( new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { StringBuffer queryString = new StringBuffer(" FROM ") .append(getEntityClass().getSimpleName()); String countQueryString = "SELECT count(*) " + queryString.toString(); if (StringUtils.hasText(pageRequest.getSortColumns())) { queryString.append(" ORDER BY " + pageRequest.getSortColumns()); } Query query = session.createQuery(queryString .toString()); Query countQuery = session .createQuery(countQueryString); return PageQueryUtils.executeQueryForPage(pageRequest, query, countQuery); } }); } public Page pageQuery(final String sql, final PageRequest pageRequest) { final String countQuery = "select count(*) " + removeSelect(removeFetchKeyword((sql))); return pageQuery(sql, countQuery, pageRequest); } public Page pageQuery(final String sql, String countQuerySql, final PageRequest pageRequest) { Map otherFilters = new HashMap(1); otherFilters.put("sortColumns", pageRequest.getSortColumns()); return PageQueryUtils.pageQuery(getHibernateTemplate(), pageRequest, sql, countQuerySql); } static class PageQueryUtils { @SuppressWarnings(value = "all") private static Page pageQuery(HibernateTemplate template, final PageRequest pageRequest, final String sql, final String countQuerySql) { return (Page) template.execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { Query query = setQueryParameters(session.createQuery(sql), pageRequest); Query countQuery = setQueryParameters(session .createQuery(removeOrders(countQuerySql)), pageRequest); return executeQueryForPage(pageRequest, query, countQuery); } }); } private static Object executeQueryForPage( final PageRequest pageRequest, Query query, Query countQuery) { Page page = new Page(pageRequest, ((Number) countQuery .uniqueResult()).intValue()); if (page.getTotalCount() <= 0) { page.setResult(new ArrayList(0)); } else { page.setResult(query.setFirstResult(page.getFirstResult()) .setMaxResults(page.getPageSize()).list()); } return page; } public static Query setQueryParameters(Query q, Object params) { q.setProperties(params); return q; } public static Query setQueryParameters(Query q, Map params) { q.setProperties(params); return q; } } public void save(E entity) { getHibernateTemplate().save(entity); } public List<E> findAll() { return getHibernateTemplate().loadAll(getEntityClass()); } public E getById(PK id) { return (E) getHibernateTemplate().get(getEntityClass(), id); } public void delete(Object entity) { getHibernateTemplate().delete(entity); } public void delete(Serializable entity) { getHibernateTemplate().delete(entity); } public void deleteById(PK id) { Object entity = getById(id); if (entity == null) { throw new ObjectRetrievalFailureException(getEntityClass(), id); } getHibernateTemplate().delete(entity); } public void update(E entity) { getHibernateTemplate().update(entity); } public void saveOrUpdate(E entity) { getHibernateTemplate().saveOrUpdate(entity); } public void refresh(Object entity) { getHibernateTemplate().refresh(entity); } public void flush() { getHibernateTemplate().flush(); } public void evict(Object entity) { getHibernateTemplate().evict(entity); } public void saveAll(Collection<E> entities) { for (Iterator<E> it = entities.iterator(); it.hasNext();) { save(it.next()); } } public void deleteAll(Collection entities) { getHibernateTemplate().deleteAll(entities); } public E findByProperty(final String propertyName, final Object value) { return (E) getHibernateTemplate().execute(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { return session.createCriteria(getEntityClass()).add( Expression.eq(propertyName, value)).uniqueResult(); } }); } public List<E> findAllBy(final String propertyName, final Object value) { return getHibernateTemplate().executeFind(new HibernateCallback() { public Object doInHibernate(Session session) throws HibernateException, SQLException { return session.createCriteria(getEntityClass()).add( Expression.eq(propertyName, value)).list(); } }); } /** * 判断对象某些属性的值在数据库中是否唯一. * * @param uniquePropertyNames * 在POJO里不能重复的属性列表,以逗号分割 如"name,loginid,password" */ public boolean isUnique(E entity, String uniquePropertyNames) { Assert.hasText(uniquePropertyNames); Criteria criteria = getSession().createCriteria(getEntityClass()) .setProjection(Projections.rowCount()); String[] nameList = uniquePropertyNames.split(","); try { // 循环加入唯一列 for (int i = 0; i < nameList.length; i++) { criteria.add(Restrictions.eq(nameList[i], PropertyUtils .getProperty(entity, nameList[i]))); } // 以下代码为了如果是update的情况,排除entity自身. String idName = getSessionFactory().getClassMetadata( entity.getClass()).getIdentifierPropertyName(); if (idName != null) { // 取得entity的主键值 Serializable id = (Serializable) PropertyUtils.getProperty( entity, idName); // 如果id!=null,说明对象已存在,该操作为update,加入排除自身的判断 if (id != null) criteria.add(Restrictions.not(Restrictions.eq(idName, id))); } } catch (Exception e) { ReflectionUtils.handleReflectionException(e); } return ((Number) criteria.uniqueResult()).intValue() == 0; } public abstract Class getEntityClass(); }