`
skzr.org
  • 浏览: 367116 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

[分享][Hibernate]公用DAO

    博客分类:
  • J2EE
阅读更多
通过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:skzr.org@gmail.com">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:skzr.org@gmail.com">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:skzr.org@gmail.com">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:skzr.org@gmail.com">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:skzr.org@gmail.com">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:skzr.org@gmail.com">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:skzr.org@gmail.com">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:skzr.org@gmail.com">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));
	}
	
}
 

 

  • 大小: 264.8 KB
分享到:
评论
2 楼 skzr.org 2011-07-16  
何枫abc 写道
我觉得用JPA实在些!!!

JPA是Hibernate的更通用,我做的是一个现实的系统,必将是有所矛盾的,关键在于寻找平衡点。

一个系统从框架演化为实际的系统往往是特例、个性化的过程,只有成为一个具有完整感情才是有意识的系统、是世界上独一无二的,我们不应当集中在背后的理论和通用,还是应考虑下实际需要。
1 楼 何枫abc 2011-07-16  
我觉得用JPA实在些!!!

相关推荐

    Spring+Hibernate实现)Hibernate公用类

    在标题和描述中提到的"Spring+Hibernate实现)Hibernate公用类",实际上是指创建一个泛化的DAO接口(EntityDao)和它的实现类(EntityDaoImpl)。这样的设计模式可以避免为每个数据模型(如User、News、Company)都...

    SSH 项目框架搭建总结

    cn.itcast.elec.dao:项目的dao层,负责连接数据库的操作 cn.itcast.elec.daomain:封装实体对象(PO对象),对应连接数据库表的映射文件 cn.itcast.elec.service:项目service层,负责操作各个功能模块的业务逻辑 ...

    人事管理系统设计报告

    2. 系统公用代码设计 2.1 DAOFACTORY类 DAO(Data Access Object)工厂类用于创建不同类型的DAO对象,实现数据库操作的抽象,提高代码的可维护性和复用性。 2.1.1 功能描述 DAOFACTORY类提供了一个接口,使得在...

    Spring考试试卷(有答案).docx

    5. Spring与Hibernate集成:Spring提供HibernateDaoSupport类简化Hibernate使用,通过LocalSessionFactoryBean获取SessionFactory,Spring管理依赖关系,将SessionFactory注入到DAO层,而不是DataSource。...

    毕业设计-----企业人事管理系统

    "Dao层封装的很好,dao层的公用代码通用性很强"意味着该系统对数据库操作进行了良好的抽象和封装,使得数据库操作模块化,降低了耦合度。通用性强的Dao层代码可以复用,减少了重复工作,提升了开发效率。 Struts2是...

    SSH三大框架应用实例

    // 可以在这里定义所有Action类公用的方法和属性 // 例如:初始化方法、错误处理等 } ``` #### 四、具体实现 接下来,我们将详细介绍如何使用Struts2进行前端交互,使用Spring进行业务逻辑处理以及使用...

    struts2.1宝典

    15.自定义标签中访问Dao 获取dao 6 16.标签获取参数 6 17.Action之间传递错误验证信息 6 18第一个Ajax例子 Ajax+struts2 6 8.标签 7 8.Select标签 7 9.Checkbox 10 10.checkboxlist 12 11.combobox 14 12....

    java框架-Spring2复习题.pdf

    - Spring提供了`HibernateDaoSupport`类,简化了Hibernate的使用,使得业务层代码无需直接实例化DAO类。 - `LocalSessionFactoryBean`是Spring配置中用来创建`SessionFactory`实例的。 - Spring管理依赖关系,...

    java框架Spring2复习题.pdf

    4. **AOP在Spring中的应用**:Spring的AOP主要用于解决公用问题,比如事务管理。AOP的目标是将交叉关注点(如日志、事务等)从主业务逻辑中分离出来,而不是实现无刷新的界面效果,那是Ajax等前端技术的作用。 5. *...

    Spring考试试卷 (2).docx

    5. Spring与Hibernate集成时,Spring提供HibernateDaoSupport类简化DAO层的使用,并通过LocalSessionFactoryBean获取SessionFactory实例。错误的说法是C,SessionFactory不应该注入到DataSource中,而是被注入到需要...

    Struts2.1.6实战课件精解_02

    这涉及到使用JXL库读取Excel文件、创建序列和表、配置JNDI、创建工程和公用组件、DAO层、Service层、以及控制层的Action代码。 #### 总结 《Struts2.1.6实战课件精解_02》不仅提供了Struts2框架的理论知识,更重要...

    Java界面开发规范[归类].pdf

    文档推荐使用Struts1.2+Spring作为开发框架,而排除了Hibernate。所有数据库访问需通过自定义服务实现,而不是直接依赖ORM工具。在界面控件方面,规定了使用特定的JS控件,如HTC的Treegrid和Tab,以及Ext的Ajax访问...

    ZStar总体描述

    7. **综合性的服务支持体系**:ZStar通过软件集成平台、平台构件、公用应用服务和技术构件等多个方面为开发者提供全方位的服务和支持。 #### 三、ZStar的技术架构 ZStar的技术栈主要包括: - **操作系统**:支持...

    cms后台管理

    Jeecms是基于Spring注解,在自定义标签时对于实体类和dao service等注意注解的问题。 五 自定义标签及使用自己创建的表的实现过程 下面是我自己定义的标签mycontent_list 首先,在数据库里创建了一个jc_...

Global site tag (gtag.js) - Google Analytics