[分享][Hibernate]公用DAO

通过Hibernate的元信息处理组件等等,利用spring封装的jdbc bean rowmapper自动映射为bean
又见hibernate的dao封装,不要拍砖了,只是记录而已,个人总结的最佳实践。
代码主要内容:
  • Hibernate 泛型DAO
  • 分页:
    • 基于实体Example的分页
    • 基于HQL的分页
    • 基于实体类的分页
  • 工具方法:
    • hibernate的处理——获取hibernate元数据样例
    • jdbc的处理
  • 通用Hibernate非泛型Dao
先上类图,给个大概印象:


 
通用实体Dao,可以操作所有hibernate实体:
/**
 * 基于Hibernate的实现.<br>
 * <ol>
 * 	<li>支持Autowired自动装载{@link SessionFactory}</li>
 * </ol>
 * @author <a href="mailto:[email protected]">skzr.org</a>
 * @version 1.0.0
 * @since JDK1.6
 */
public class BaseDaoHibernateImpl extends HibernateDaoSupport implements IBaseDao { // NOPMD by skzrorg on 11-4-30 下午2:35
	protected final transient ILocalLogger logger = LocalLoggerFactory.getLogger(getClass());
	@Autowired
	protected JdbcTemplate jdbcTemplate;
	@Autowired
	public final void setSuperSessionFactory(SessionFactory sessionFactory) {
		setSessionFactory(sessionFactory);
	}
	
	/**
	 * 查询结果映射到对象<br>
	 * 具体实现见:{@link BeanPropertyRowMapper}
	 * @param <Bean> 对象类型
	 * @param elementType 必须
	 * @param sql
	 * @param paramters 参数
	 * @return
	 */
	protected final <Bean> List<Bean> query(Class<Bean> elementType, String sql, Object... paramters) {
		if (logger.isDebugEnabled()) logger.debug(I10NDao.jdbcTemplateQueryBean, elementType, sql, UtilObject.toString(paramters));
		return UtilJdbcTemplate.query(jdbcTemplate, elementType, sql, paramters);
	}
	
	/**
	 * 执行sql update 
	 * @param sql
	 * @param paramters 参数
	 * @return {@link JdbcTemplate#update(String, Object...)}
	 */
	protected final int update(String sql, Object... paramters) {
		if (logger.isDebugEnabled()) logger.debug(I10NDao.jdbcTemplateUpdate, sql, UtilObject.toString(paramters));
		return jdbcTemplate.update(sql, paramters);
	}
	
	@SuppressWarnings("unchecked")
	public <T> List<T> find(String hql, Object... values) {
		return getHibernateTemplate().find(hql, values);
	}
	
	public <T> T findSingle(String hql, Object... values) {
		List<T> entities = find(hql, values);
		return DataAccessUtils.requiredSingleResult(entities);
	}
	
	@Override
	public void delete(Object entity) {
		getHibernateTemplate().delete(entity);
	}
	
	@Override
	public <T> int deleteById(Class<T> entityClass, Serializable id) {
		return getHibernateTemplate().execute(new DeleteByIdHibernateCallback(entityClass, id));
	}
	
	@Override
	public final <T, PK extends Serializable> int deleteByIds(Class<T> entityClass, Collection<PK> ids) {
		return getHibernateTemplate().execute(new DeleteByIdHibernateCallback(entityClass, ids));
	}

	@Override
	public <T> T get(Class<T> entityClass, Serializable id) {
		return getHibernateTemplate().get(entityClass, id);
	}

	@Override
	public <T> List<T> loadAll(Class<T> entityClass) {
		return getHibernateTemplate().loadAll(entityClass);
	}

	@Override
	public void saveOrUpdate(Object entity) {
		getHibernateTemplate().saveOrUpdate(entity);
	}

	@Override
	public void saveOrUpdateAll(Collection<?> entities) {
		getHibernateTemplate().saveOrUpdateAll(entities);
	}
	
	@SuppressWarnings("unchecked")
	public <T> List<T> findByExample(T exampleEntity) {
		return getHibernateTemplate().findByExample(exampleEntity);
	}
	
	@Override
	public <PAGE extends PageByHQL<?>> PAGE findByPage(PAGE page) {
		return getHibernateTemplate().execute(new PageByHQLHibernateCallback<PAGE>(page));
	}

	@Override
	public <PAGE extends PageByExample<?>> PAGE findByPageWithExample(PAGE page) {
		return UtilHibernate.findByPageWithExample(getHibernateTemplate(), page);
	}
	
}
 
泛型Dao
package org.skzr.framework.dao.impl;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;

import org.hibernate.SessionFactory;
import org.skzr.framework.dao.IEntityDao;
import org.skzr.framework.dao.page.PageByEntity;
import org.skzr.framework.dao.page.PageByExample;
import org.skzr.framework.dao.page.PageByHQLHibernateCallback;
import org.skzr.framework.i10n.I10NDao;
import org.skzr.framework.util.UtilAssert;
import org.skzr.framework.util.UtilHibernate;
import org.skzr.framework.util.UtilJdbcTemplate;
import org.skzr.framework.util.UtilObject;
import org.skzr.logging.ILocalLogger;
import org.skzr.logging.LocalLoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

/**
 * 实例化配置时使用:
 * <ol>
 * 	<li>支持Autowired自动装载{@link SessionFactory}</li>
 * </ol>
 * @param <T> 实体类型
 * @param <PK> 实体的主键标识类型
 * @author <a href="mailto:[email protected]">skzr.org</a>
 * @version 1.0.0
 * @since JDK1.6
 */
public class EntityDaoHibernateImpl<T, PK extends Serializable> extends HibernateDaoSupport implements IEntityDao<T, PK> {
	protected final transient ILocalLogger logger = LocalLoggerFactory.getLogger(getClass());
	@Autowired
	protected JdbcTemplate jdbcTemplate;
	private final Class<T> entityClass;
	
	public EntityDaoHibernateImpl(Class<T> entityClass) {
		UtilAssert.notNull(entityClass, logger.getText(I10NDao.entityClassNeed, "new EntityDaoHibernateImpl()"));
		this.entityClass = entityClass;
	}
	
	/**
	 * 查询结果映射到对象<br>
	 * 具体实现见:{@link BeanPropertyRowMapper}
	 * @param <Bean> 对象类型
	 * @param elementType 必须
	 * @param sql
	 * @param paramters 参数
	 * @return
	 */
	protected final <Bean> List<Bean> query(Class<Bean> elementType, String sql, Object... paramters) {
		if (logger.isDebugEnabled()) logger.debug(I10NDao.jdbcTemplateQueryBean, elementType, sql, UtilObject.toString(paramters));
		return UtilJdbcTemplate.query(jdbcTemplate, elementType, sql, paramters);
	}
	
	/**
	 * 执行sql update 
	 * @param sql
	 * @param paramters 参数
	 * @return {@link JdbcTemplate#update(String, Object...)}
	 */
	protected final int update(String sql, Object... paramters) {
		if (logger.isDebugEnabled()) logger.debug(I10NDao.jdbcTemplateUpdate, sql, UtilObject.toString(paramters));
		return jdbcTemplate.update(sql, paramters);
	}
	
	@Autowired
	public final void setSuperSessionFactory(SessionFactory sessionFactory) {
		setSessionFactory(sessionFactory);
	}
	
	@Override
	public void delete(T entity) {
		getHibernateTemplate().delete(entity);
	}

	@Override
	public int deleteById(final PK id) {
		return getHibernateTemplate().execute(new DeleteByIdHibernateCallback(entityClass, id));
	}

	@Override
	public int deleteByIds(final Collection<PK> ids) {
		return getHibernateTemplate().execute(new DeleteByIdHibernateCallback(entityClass, ids));
	}

	@Override
	public T get(PK id) {
		return getHibernateTemplate().get(entityClass, id);
	}

	@Override
	public List<T> loadAll() {
		return getHibernateTemplate().loadAll(entityClass);
	}

	@Override
	public void saveOrUpdate(T entity) {
		getHibernateTemplate().saveOrUpdate(entity);
	}

	@Override
	public void saveOrUpdateAll(Collection<T> entities) {
		getHibernateTemplate().saveOrUpdateAll(entities);
	}
	
	@Override
	@SuppressWarnings("unchecked")
	public List<T> findByExample(T exampleEntity) {
		return getHibernateTemplate().findByExample(exampleEntity);
	}

	@Override
	public <PAGE extends PageByEntity<T>> PAGE findByPage(PAGE page) {
		return getHibernateTemplate().execute(new PageByHQLHibernateCallback<PAGE>(page));
	}

	@Override
	public <PAGE extends PageByExample<T>> PAGE findByPageWithExample(PAGE page) {
		return UtilHibernate.findByPageWithExample(getHibernateTemplate(), page);
	}
}

分页代码:

/**
 * @param <T> 实体类型
 * @author <a href="mailto:[email protected]">skzr.org</a>
 * @version 1.0.0
 * @since JDK1.6
 */
public class Page<T> {
	/** &lt;结果&gt; */
	private List<T> datas;
	/** 每页记录数 */
	private int pageSize = getDefaultPageSize();
	/** 当前页号从1开始 */
	private int pageNumber = 1;
	/** 总记录数 */
	private int totalCount;
	
	public static int getDefaultPageSize() {
		return 20;
	}
	
	public void setDatas(List<T> datas) {
		this.datas = datas;
	}
	/**
	 * 返回结果集,如果{@link #datas}空返回{@link Collections#EMPTY_LIST}
	 * @return &lt;T&gt;
	 */
	@SuppressWarnings("unchecked")
	public List<T> getDatas() {
		return datas == null ? Collections.EMPTY_LIST : datas;
	}
	public void setTotalCount(int totalCount) {
		this.totalCount = totalCount;
	}
	public int getTotalCount() {
		return totalCount;
	}
	/**
	 * 设置每页记录数
	 * @param pageSize 页大小
	 */
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize < 1 ? getDefaultPageSize() : pageSize;
	}
	public int getPageSize() {
		return pageSize;
	}
	/**
	 * 设置查询第几页数据
	 * @param pageNumber 页码
	 */
	public void setPageNumber(int pageNumber) {
		this.pageNumber = pageNumber < 1 ? 1 : pageNumber;
	}
	
	/**
	 * 第一条记录索引位置
	 * @return
	 */
	public int getFirstResult() {
		return (pageNumber - 1) * pageSize;
	}
	
	/**
	 * 是否需要查询.
	 * <ol>
	 * 	<li>根据已知的总记录数{@link #totalCount}判断:如果总记录数超过{@link #getFirstResult()}需要查询,不需要查询</li>
	 * </ol>
	 * @return {@link #totalCount}&gt;{@link #getFirstResult()}
	 */
	public boolean needQuery() {
		return totalCount > getFirstResult();
	}
}

基于实体查询的分页:

/**
 * 实体分页
 * @param <T> 实体类型
 * @author <a href="mailto:[email protected]">skzr.org</a>
 * @version 1.0.0
 * @since JDK1.6
 */
public class PageByExample<T> extends Page<T> {
	protected final transient ILocalLogger logger = LocalLoggerFactory.getLogger(getClass());
	private final T exampleEntity;
	
	public T getExampleEntity() {
		return exampleEntity;
	}
	
	public PageByExample(T exampleEntity) {
		UtilAssert.notNull(exampleEntity, logger.getText(I10NDao.entityNeed, "PageByExample"));
		this.exampleEntity = exampleEntity;
	}
	
	@SuppressWarnings("unchecked")
	public Class<T> getEntityClass() {
		return (Class<T>) exampleEntity.getClass();
	}
}
 

基于HQL分页:

/**
 * @param <T> 实体类型
 * @author <a href="mailto:[email protected]">skzr.org</a>
 * @version 1.0.0
 * @since JDK1.6
 */
public class PageByHQL<T> extends Page<T> {
	protected final transient ILocalLogger logger = LocalLoggerFactory.getLogger(getClass());
	private final String hql;
	
	public String getHql() {
		return hql;
	}
	
	public PageByHQL(String hql) {
		UtilAssert.notEmptyStr(hql, logger.getText(I10NDao.hqlNeed, "PageByHQL"));
		this.hql = hql;
	}
	
	public List<?> getParameters() {
		return null;
	}
}

 基于实体分页:

/**
 * 实体分页
 * @param <T> 实体类型
 * @author <a href="mailto:[email protected]">skzr.org</a>
 * @version 1.0.0
 * @since JDK1.6
 */
public class PageByEntity<T> extends PageByHQL<T> {
	
	public PageByEntity(Class<T> entityClass) {
		super("from " + entityClass.getName());
	}
	
}
 

工具方法:

/**
 * 这里是所有Hibernate相关的帮助方法
 * @author <a href="mailto:[email protected]">skzr.org</a>
 * @version 1.0.0
 * @since JDK1.6
 */
public final class UtilHibernate {
	private static transient ILocalLogger logger = LocalLoggerFactory.getLogger(UtilHibernate.class);
	
	private UtilHibernate() {
		throw new IllegalArgumentException(logger.getText(I10NFramework.utilClassInstance));
	}
	
	/**
	 * 获取主键属性名
	 * @param session
	 * @param entityClass 实体类
	 * @return 主键名
	 * @see #getIdentifierPropertyName(SessionFactory, Class)
	 */
	public static String getIdentifierPropertyName(Session session, Class<?> entityClass) {
		return session.getSessionFactory().getClassMetadata(entityClass).getIdentifierPropertyName();
	}
	
	/**
	 * 获取主键属性名
	 * @param sessionFactory 
	 * @param entityClass 实体类
	 * @return 主键名
	 */
	public static String getIdentifierPropertyName(SessionFactory sessionFactory, Class<?> entityClass) {
		return sessionFactory.getClassMetadata(entityClass).getIdentifierPropertyName();
	}
	
	/**
	 * 输入的Hql转化为求数据个数的hql
	 * @param hql 
	 * @return hql的count hql
	 */
	public static String getCountHql(String hql) {
		StringBuilder buf = new StringBuilder(hql.length());
		
		//find order by and delete
		String tmp = hql.toLowerCase(Locale.ENGLISH);
		int from0 = tmp.indexOf("from");
		int order0 = tmp.lastIndexOf("order ");
		if (order0 > 0) { //find order by
			int order1 = tmp.indexOf("by", order0 + "order ".length()); //find by
			if (order1 > 0 && tmp.substring(order0 + "order ".length(), order1).isEmpty()) {
				order1 = order1 + "by".length();
				if (tmp.indexOf('\'', order1) == -1 && tmp.indexOf(')', order1) == -1) { // NOPMD by skzrorg on 11-4-30 下午2:33
					buf.append("select count(*) ").append(hql.substring(from0, order0));
				}
			}
		}
		if (buf.length() == 0) buf.append("select count(*) ").append(hql.substring(from0));
		logger.debug(I10NDao.hqlCount, hql, buf);
		return buf.toString();
	}
	
	/** Query设置条件值 */
	public static void setParameters(Query query, List<?> parameters) {
		if (parameters == null || parameters.isEmpty()) return;
		for (int i = 0, len = parameters.size(); i < len; i++) {
			query.setParameter(i, parameters.get(i));
		}
	}
	
	/** 创建Hibernate Query */
	public static Query createQuery(Session session, String hql, List<?> parameters) {
		Query query = session.createQuery(hql);
		setParameters(query, parameters);
		return query;
	}
	
	@SuppressWarnings("unchecked")
	public static <PAGE extends PageByExample<?>> PAGE findByPageWithExample(HibernateTemplate hibernateTemplate, PAGE page) {
		final Class<?> entityClass = page.getEntityClass();
		page.setTotalCount(hibernateTemplate.execute(new HibernateCallback<Integer>() {
			@Override
			public Integer doInHibernate(Session session) throws SQLException {
				Query countQuery = session.createQuery("select count(" + getIdentifierPropertyName(session, entityClass) + ") from " + entityClass.getName());
				return ((Number) countQuery.uniqueResult()).intValue();
			}
		}));
		page.setDatas(hibernateTemplate.findByExample(page.getExampleEntity()));
		return page;
	}
}
 

jdbc的:

/**
 * 提供{@link JdbcTemplate}的工具方法
 * @author <a href="mailto:[email protected]">skzr.org</a>
 * @version 1.0.0
 * @since JDK1.6
 */
public final class UtilJdbcTemplate {
	private static final ILocalLogger logger = LocalLoggerFactory.getLogger(UtilJdbcTemplate.class);
	
	private UtilJdbcTemplate() {
		throw new IllegalArgumentException(logger.getText(I10NFramework.utilClassInstance));
	}
	/**
	 * 查询结果映射到对象<br>
	 * 具体实现见:{@link BeanPropertyRowMapper}
	 * @param <T> 对象类型
	 * @param jdbcTemplate 必须
	 * @param elementType 必须
	 * @param sql
	 * @param paramters 参数
	 * @return
	 * @see BeanPropertyRowMapper
	 */
	public static <T> List<T> query(JdbcTemplate jdbcTemplate, Class<T> elementType, String sql, Object... paramters) {
		return jdbcTemplate.query(sql, paramters, new BeanPropertyRowMapper<T>(elementType));
	}
	
}
 

猜你喜欢

转载自skzr-org.iteye.com/blog/1044937