`

hibernate 通用泛型DAO

    博客分类:
  • ssh
阅读更多
package org.lzpeng.dao;

import java.io.Serializable;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.criterion.Criterion;
import org.springside.modules.orm.hibernate.Page;


/**
 * 
 * @version 2009-1-10
 * @author lzpeng
 * 
 */
public interface IGenericDAO<T, PK extends Serializable> {

	public void save(T entity);

	public void delete(T entity);

	public void delete(PK id);

	public List<T> findAll();

	public Page<T> findAll(Page<T> page);

	/**
	 * 按id获取对象.
	 */
	public T get(final PK id);

	/**
	 * 按HQL查询对象列表.
	 * 
	 * @param hql
	 *            hql语句
	 * @param values
	 *            数量可变的参数
	 */
	public List find(String hql, Object... values);

	/**
	 * 按HQL分页查询. 暂不支持自动获取总结果数,需用户另行执行查询.
	 * 
	 * @param page
	 *            分页参数.包括pageSize 和firstResult.
	 * @param hql
	 *            hql语句.
	 * @param values
	 *            数量可变的参数.
	 * 
	 * @return 分页查询结果,附带结果列表及所有查询时的参数.
	 */
	public Page<T> find(Page<T> page, String hql, Object... values);

	/**
	 * 按HQL查询唯一对象.
	 */
	public Object findUnique(String hql, Object... values);

	/**
	 * 按HQL查询Intger类形结果.
	 */
	public Integer findInt(String hql, Object... values);

	/**
	 * 按HQL查询Long类型结果.
	 */
	public Long findLong(String hql, Object... values);

	/**
	 * 按Criterion查询对象列表.
	 * 
	 * @param criterion
	 *            数量可变的Criterion.
	 */
	public List<T> findByCriteria(Criterion... criterion);

	/**
	 * 按Criterion分页查询.
	 * 
	 * @param page
	 *            分页参数.包括pageSize、firstResult、orderBy、asc、autoCount.
	 *            其中firstResult可直接指定,也可以指定pageNo. autoCount指定是否动态获取总结果数.
	 * 
	 * @param criterion
	 *            数量可变的Criterion.
	 * @return 分页查询结果.附带结果列表及所有查询时的参数.
	 */
	public Page<T> findByCriteria(Page page, Criterion... criterion);

	/**
	 * 按属性查找对象列表.
	 */
	public List<T> findByProperty(String propertyName, Object value);

	/**
	 * 按属性查找唯一对象.
	 */
	public T findUniqueByProperty(String propertyName, Object value);

	/**
	 * 根据查询函数与参数列表创建Query对象,后续可进行更多处理,辅助函数.
	 */
	public Query createQuery(String queryString, Object... values);

	/**
	 * 根据Criterion条件创建Criteria,后续可进行更多处理,辅助函数.
	 */
	public Criteria createCriteria(Criterion... criterions);

	/**
	 * 判断对象的属性值在数据库内是否唯一.
	 * 
	 */
	public boolean isPropertyUnique(String propertyName, Object newValue,
			Object orgValue);

	/**
	 * 通过count查询获得本次查询所能获得的对象总数.
	 * 
	 * @return page对象中的totalCount属性将赋值.
	 */
	public int countQueryResult(Page<T> page, Criteria c);
}

 

package org.lzpeng.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;

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.Order;
import org.hibernate.criterion.Projection;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.impl.CriteriaImpl;
import org.hibernate.transform.ResultTransformer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.util.Assert;
import org.lzpeng.dao.IGenericDAO;
import org.springside.modules.utils.BeanUtils;
import org.springside.modules.orm.hibernate.Page;
import org.springside.modules.orm.hibernate.QueryParameter;

/**
 * Hibernate的范型基类.
 * <p>
 * 可以在service类中直接创建使用.也可以继承出DAO子类
 * </p>
 * 修改自Springside SimpleHibernateTemplate
 * 
 * @param <T>
 *            DAO操作的对象类型
 * @param <PK>
 *            主键类型
 * 
 * 
 */
@SuppressWarnings("unchecked")
public class GenericDAOImpl<T, PK extends Serializable> extends
		HibernateDaoSupport implements IGenericDAO<T, PK> {

	protected Logger logger = LoggerFactory.getLogger(getClass());

	protected SessionFactory sessionFactory;

	protected Session session;

	protected Class<?> entityClass;
		
	public GenericDAOImpl() {
		this.entityClass = (Class<?>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
	}

	public GenericDAOImpl(SessionFactory sessionFactory, Class<T> entityClass) {		
		super.setSessionFactory(sessionFactory);
		this.entityClass = entityClass;
	}

	public void save(T entity) {
		Assert.notNull(entity);
		super.getHibernateTemplate().saveOrUpdate(entity);
		logger.info("save entity: {}", entity);
	}

	public void delete(T entity) {
		Assert.notNull(entity);
		super.getHibernateTemplate().delete(entity);
		logger.info("delete entity: {}", entity);
	}

	public void delete(PK id) {
		Assert.notNull(id);
		delete(get(id));
	}

	public List<T> findAll() {
		return findByCriteria();
	}

	public Page<T> findAll(Page<T> page) {
		return findByCriteria(page);
	}

	public T get(final PK id) {
		if(super.getHibernateTemplate() == null){
			System.out.println("asdfasdf");
		}
		return (T) super.getHibernateTemplate().get(entityClass, id);
	}

	public List find(String hql, Object... values) {
		return createQuery(hql, values).list();
	}

	public Page<T> find(Page<T> page, String hql, Object... values) {
		Assert.notNull(page);

		if (page.isAutoCount()) {
			logger.warn("HQL查询暂不支持自动获取总结果数,hql为{}", hql);
		}
		Query q = createQuery(hql, values);
		if (page.isFirstSetted()) {
			q.setFirstResult(page.getFirst());
		}
		if (page.isPageSizeSetted()) {
			q.setMaxResults(page.getPageSize());
		}
		page.setResult(q.list());
		return page;
	}

	/**
	 * 按HQL查询唯一对象.
	 */
	public Object findUnique(String hql, Object... values) {
		return createQuery(hql, values).uniqueResult();
	}

	public Integer findInt(String hql, Object... values) {
		return (Integer) findUnique(hql, values);
	}

	public Long findLong(String hql, Object... values) {
		return (Long) findUnique(hql, values);
	}

	public List<T> findByCriteria(Criterion... criterion) {
		return createCriteria(criterion).list();
	}

	public Page<T> findByCriteria(Page page, Criterion... criterion) {
		Assert.notNull(page);

		Criteria c = createCriteria(criterion);

		if (page.isAutoCount()) {
			page.setTotalCount(countQueryResult(page, c));
		}
		if (page.isFirstSetted()) {
			c.setFirstResult(page.getFirst());
		}
		if (page.isPageSizeSetted()) {
			c.setMaxResults(page.getPageSize());
		}

		if (page.isOrderBySetted()) {
			if (page.getOrder().endsWith(QueryParameter.ASC)) {
				c.addOrder(Order.asc(page.getOrderBy()));
			} else {
				c.addOrder(Order.desc(page.getOrderBy()));
			}
		}
		page.setResult(c.list());
		return page;
	}

	/**
	 * 按属性查找对象列表.
	 */
	public List<T> findByProperty(String propertyName, Object value) {
		Assert.hasText(propertyName);
		return createCriteria(Restrictions.eq(propertyName, value)).list();
	}

	public T findUniqueByProperty(String propertyName, Object value) {
		Assert.hasText(propertyName);
		return (T) createCriteria(Restrictions.eq(propertyName, value))
				.uniqueResult();
	}

	public Query createQuery(String queryString, Object... values) {
		 Assert.hasText(queryString);
		 super.getSession().createQuery(queryString);
		Query queryObject = super.getSession().createQuery(queryString);
		if (values != null) {
			for (int i = 0; i < values.length; i++) {
				queryObject.setParameter(i, values[i]);
			}
		}
		return queryObject;
	}

	
	public Criteria createCriteria(Criterion... criterions) {
		Criteria criteria = super.getSession().createCriteria(entityClass);
		for (Criterion c : criterions) {
			criteria.add(c);
		}
		return criteria;
	}

	
	public boolean isPropertyUnique(String propertyName, Object newValue,
			Object orgValue) {
		if (newValue == null || newValue.equals(orgValue))
			return true;

		Object object = findUniqueByProperty(propertyName, newValue);
		return (object == null);
	}

	public int countQueryResult(Page<T> page, 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) BeanUtils.getFieldValue(impl, "orderEntries");
			BeanUtils.setFieldValue(impl, "orderEntries", new ArrayList());
		} catch (Exception e) {
			logger.error("不可能抛出的异常:{}", e.getMessage());
		}

		// 执行Count查询
		int totalCount = (Integer) c.setProjection(Projections.rowCount())
				.uniqueResult();
		if (totalCount < 1)
			return -1;

		// 将之前的Projection和OrderBy条件重新设回去
		c.setProjection(projection);

		if (projection == null) {
			c.setResultTransformer(CriteriaSpecification.ROOT_ENTITY);
		}
		if (transformer != null) {
			c.setResultTransformer(transformer);
		}

		try {
			BeanUtils.setFieldValue(impl, "orderEntries", orderEntries);
		} catch (Exception e) {
			logger.error("不可能抛出的异常:{}", e.getMessage());
		}

		return totalCount;
	}

}

 

1.service中直接使用
GenericDAOImpl<User, Integer> userDAO = new GenericDAOImpl<User, Integer>(sessionFactory, User.class);

2.继承出子DAO
interface IUserDAO extends IGenericDAO<User, Integer>

class UserDAOImpl extends GenericDAOImpl<User, Integer> implements IUserDAO

 

分享到:
评论
3 楼 waterenjoy 2012-03-01  
/**
* 获取泛型
* @param type 类型
* @param index 第几个泛型
* @return 泛型类型
*/
public static Class getGenericClass(Class type, int index) {
Type genType = type.getGenericSuperclass();

if (genType instanceof ParameterizedType) {
Type[] params = ((ParameterizedType) genType).getActualTypeArguments();

if ((params != null) && (params.length >= index - 1)) {
return (Class) params[index];
}
}
return null;
}
2 楼 29163077 2011-08-17  
spring在UserServiceImpl 注入genericDao的时候,能够找到声明了@Repository("genericDao") 的泛型实现类,但是调用构造方法的时候报错:
nested exception is java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType 
1 楼 29163077 2011-08-17  
错误是在这里,但是我能力有限,不知道该怎么解决。
Java代码  收藏代码

   1. public GenericDAOImpl() {    
   2.             this.entityClass = (Class<?>) ((ParameterizedType) getClass()    
   3.                     .getGenericSuperclass()).getActualTypeArguments()[0];    
   4.      }  

public GenericDAOImpl() {  
        this.entityClass = (Class<?>) ((ParameterizedType) getClass()  
                .getGenericSuperclass()).getActualTypeArguments()[0];  
}



这个构造方法不能找到泛型声明的entityClass,也就是User。
有没有哪位有类似的实现或者更好的方式?

相关推荐

    Hibernate泛型Dao

    【标题】"Hibernate泛型Dao"是针对Java开发中的数据持久化框架Hibernate的一个高级应用,主要目的是为了提高代码的复用性和简洁性。在传统的Hibernate使用中,针对每个实体类,我们都需要创建一个对应的Dao(Data ...

    基于hibernate的泛型Dao框架

    标题中的“基于Hibernate的泛型Dao框架”是指在Java开发中使用Hibernate ORM工具,并结合泛型设计模式构建的数据库访问对象(DAO)框架。这样的框架旨在提高代码复用性,减少重复工作,使得数据访问层的实现更加简洁...

    泛型dao 泛型dao 泛型dao

    Struts2、Hibernate、Spring整合的泛型DAO (本人评价: 代码开发效率提高30% 代码出错率减少70%) 对于大多数开发人员,系统中的每个 DAO 编写几乎相同的代码到目前为止已经成为一种习惯。虽然所有人都将这种重复...

    Hibernate泛型DAO(结合spring模板支持)

    泛型DAO是一种设计模式,它通过定义一个通用的DAO接口或抽象类,可以适用于不同的实体类,减少了重复的代码。这种模式的核心在于利用Java的泛型特性,使得DAO方法可以处理任何类型的实体对象,而无需为每个实体类...

    一个很好的通用泛型dao(含源码)

    而泛型DAO是一个类型安全的,代码精简的设计模式(相对于传统DAO),尤其在DAO组件数量庞大的时候,代码量的减少更加明显。 泛型DAO的核心是定义一个GenericDao接口,声明基本的CRUD操作: 用hibernate作为持久化...

    Hibernate泛型DAO接口,大部分通用都已包括

    本篇将详细介绍"Hibernate泛型DAO接口,大部分通用都已包括"这一主题。 首先,让我们看看DAO的概念。DAO是软件设计模式中的一种,它的主要职责是封装对数据源的访问,以提供业务逻辑层与数据存储层之间的解耦。通过...

    基于泛型的通用Dao接口和hibernate的实现

    Hibernate 对泛型Dao接口的实现主要通过继承泛型Dao接口,使用 Hibernate 的 Session 对象来实现数据访问。 Hibernate 对泛型Dao接口的实现的优点: 1. 简化数据访问:Hibernate 对泛型Dao接口的实现可以简化数据...

    hibernate不是泛型的通用DAo1

    例如,一个泛型DAO接口可能定义如下: ```java public interface GenericDao&lt;T&gt; { void save(T entity); T get(Long id); void update(T entity); void delete(T entity); } ``` 然后,对于一个名为`User`的实体...

    ssh通用泛型DAO

    在这个主题中,我们将深入探讨"ssh通用泛型DAO"的相关知识点。 首先,我们来了解"BaseHibernateDAO"。BaseHibernateDAO是基于Hibernate框架的一个基类,它封装了常见的数据库操作,如增删查改(CRUD)。通过继承这...

    spring hibernate 泛型DAO

    本文将深入探讨“Spring Hibernate 泛型DAO”这一主题,以及如何通过泛型DAO实现更加高效、可复用的代码。 首先,让我们理解什么是DAO(Data Access Object)模式。DAO是一种设计模式,它的主要作用是隔离业务逻辑...

    Hibernate泛型DAO及使用方法.doc

    而泛型DAO(Data Access Object)则是基于Hibernate进一步抽象出来的一个设计模式,用于提供更通用的数据操作方法。本文档主要探讨了如何在Spring+Hibernate环境中创建和使用泛型DAO。 首先,我们来看一下泛型DAO...

    ssh整合下的通用泛型DAO+分页

    在这个特定的讨论中,我们聚焦于SSH1中的一个关键概念:通用泛型DAO(Data Access Object)以及分页功能的实现。DAO层是模型层和数据访问层之间的桥梁,它的主要职责是处理数据库操作,为业务层提供无状态的数据访问...

    大家看看我设计的泛型DAO(使用Spring的Anotation和Hibernate)

    本篇文章将深入探讨一个使用Spring注解和Hibernate实现的泛型DAO设计,以提高代码的复用性和可维护性。 首先,`HibernateBaseDao.java`是基础的Hibernate DAO类,它提供了对Hibernate操作的基本封装。这个类通常会...

    泛型dao

    【泛型DAO】是一种在Java开发中常见的设计模式,它利用了Java泛型特性来提高代码的可重用性和类型安全性。在Java中,DAO(Data Access Object)模式是用来封装对数据库的操作,将业务逻辑与数据访问逻辑分离,使得...

    Struts2+hibernate+spring整合泛型DAO

    总结来说,"Struts2+hibernate+spring整合泛型DAO"是一种常见的Java Web开发模式,它利用三大框架的优势,结合泛型设计,提高了代码复用,降低了维护成本,使得开发者能更专注于业务逻辑,而不是基础架构。

    S2SH整合例子 注解配置 JSON 泛型Dao

    6. **泛型Dao**:在Java开发中,泛型Dao(Generic Dao)是一种设计模式,用于减少重复的数据库操作代码。通过定义一个通用的Dao接口,可以实现对不同类型的实体对象进行CRUD操作,提高了代码的复用性和可维护性。...

    一个简单的Hibernate泛型Dao的实现 ---- 20160624

    本文将深入探讨如何实现一个简单的Hibernate泛型DAO(数据访问对象),以提高代码的可重用性和可维护性。 首先,我们来看`AbstractHibernateGenericDao`类,这是一个抽象类,它通常会包含一些基本的CRUD(创建、...

    Struts2 Spring3 Hibernate 注解功能 DAO 泛型 通用分页

    总的来说,"SSHWithAnnotationDemo"项目展示了如何利用现代Java技术栈的高级特性,包括Struts2、Spring3和Hibernate的注解功能,DAO层的泛型设计以及通用的分页实现,来构建一个高效、可维护的Web应用。这样的实践...

    泛型DAO,注释详细

    在泛型DAO中,我们定义一个通用的DAO接口,该接口使用类型参数T表示所操作的数据实体类。例如: ```java public interface GenericDAO, ID&gt; { T save(T entity); void delete(ID id); T findById(ID id); List...

Global site tag (gtag.js) - Google Analytics