`
pasu
  • 浏览: 22539 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

泛型Dao-减少重复的Dao代码,用Hibernate实现

阅读更多
     Data Access Object (DAO) 是一般的J2EE项目中的一个常见的模块,在我们用一般的方法去实现DAO的过程中会发现在为每个pojo实现DAO的的时候会不断地区重复的写一些常用的方法,如update(),delete(),find()等。
    
    为了解决以上所述的缺点,可以采用DAO用泛型实现的方法,把通用的方法抽出来放到基类中,以后为pojo实现DAO的时候只要继承DAO基类就可以复用这些通用方法。这样的做法即保证了代码的复用,又保证了类型的安全。

下面例子为以前一个项目中的代码片段:
代码说明:
IBaseDao          是DAO基类的接口
BaseHibernateDao  是DAO的Hibernate实现基类(实现了接口IBaseDao)
IUserDao          是具体的DAO接口,用于持久化用户数据(继承了接口IBaseDao)
UserHibernateDao  是具体的DAO的Hibernate实现,持久化用户数据(继承了BaseHibernate 并实现了接口 IUserDao)

UserHibernateDao 继承了BaseHibernateDao的所有功能,在新建一个DAO时
只要用 XxxxxHibernateDao extends BaseHibernate就可以继承BaseHibernate的所有功能。


1.DAO基类接口

package com.rc.video.common.base;

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

import com.rc.video.pojo.TVideo;

/**
 * DAO 基类接口
 * @param <T> T pojo类型
 * @param <ID> ID类型
 */
public interface IBaseDao<T,ID extends Serializable>
{
	

	public abstract List<T> findAll();
	
	/**
	 * 查找所有,并分页
	 * @param page     要返回的页数
	 * @param pageSize 没有记录数
	 * @return
	 */
	public abstract List<T> findAll(int page, int pageSize);
	
	public abstract void save(T entity);
	
	public abstract void delete(T entity);
	
	/**
	 * 与findByProperty相似,当properyName == value 时把相应的记录删除
	 */
	public abstract void deleteByProperty(String propertyName, Object value);
	
	public abstract List<T> findByExample(T example);
	
	/**
	 * 通过属性查找
	 * @param 	propertyName	属性名称
	 * @param 	value			属性的值
	 * @return
	 */
	public abstract List<T> findByProperty(String propertyName, Object value);
	

	
	/**
	 * 通过多个属性查找
	 * @param 	propertyNames	属性名称数组
	 * @param 	values			属性值数组
	 * @return
	 */
	public abstract List<T> findByPropertys(String[] propertyNames,Object[] values);
	
	/**
	 * 通过多个属性查找,并分页,
	 * 属性名称数组和属性值数组的序列要对应
	 * 
	 * @param	propertyNames	属性名称数组
	 * @param 	values			属性值数组
	 * @param 	page			页码
	 * @param 	pageSize		每页内容条数
	 * @return
	 */
	public List<T> findByPropertys(String[] propertyNames,Object[] values,int page,int pageSize);
	
	/**
	 * 通过属性查找,并分页,
	 * 属性名称数组和属性值数组的序列要对应
	 * 
	 * @param	propertyNames	属性名称
	 * @param 	values			属性值
	 * @param 	page			页码
	 * @param 	pageSize		每页内容条数
	 * @return
	 */
	public List<T> findByProperty(String propertyName,Object value,int page,int pageSize);
	
	/**
	 * 统计所有记录的总数
	 * @return 总数
	 */
	public int countAll();
	/**
	 * 统计数据库中当propertyName=value时的记录总数
	 * @param propertyName
	 * @param value
	 * @return
	 */
	public int countByProperty(String propertyName, Object value);
	/**
	 *  统计数据库中当多个propertyName=value时的记录总数
	 * @param propertyNames	
	 * @param values
	 * @return
	 */ 
	public int countByPropertys(String[] propertyNames, Object[] values);
	
	public abstract void saveOrUpdate(T entity);
	
	public abstract T findById(ID id);
	
	public abstract void update(T entity);
	
	
	/**
	 * 获得持久化对象的类型
	 * @return
	 */
	public abstract Class<T> getPersistentClass();
	
	/**
	 * 查找并通过某一属性排序
	 * @param property 排序依据的顺序
	 * @param isSequence	是否顺序排序
	 */
	public List<T> findAndOrderByProperty(int firstResult, int fetchSize, String propertyName, boolean isSequence);
	
	
	/**
	 * 查找并通过某一属性排序
	 * @param property 排序依据的顺序
	 * @param isSequence	是否顺序排序
	 */
	public List<T> findAllAndOrderByProperty(String propertyName, boolean isSequence);
	
	
}


2.DAO的Hibernate基类
package com.rc.video.common.base;

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

import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

/**
 * DAO的Hibernate基类
 * @author pasu
 * @param <T>
 *            pojo的类型
 * @para <ID> id的类型
 * 
 */
public abstract class BaseHibernateDao<T, ID extends Serializable> extends
		HibernateDaoSupport implements IBaseDao<T, ID>
{
	private Class<T> persistentClass;

	@SuppressWarnings("unchecked")
	public BaseHibernateDao()
	{
		// 获取持久化对象的类型
		this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
	}

	public Class<T> getPersistentClass()
	{
		return persistentClass;
	}

	/**
	 * 通过id查找
	 * 
	 * @param id
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public T findById(ID id)
	{
		return (T) this.getHibernateTemplate().get(getPersistentClass(), id);
	}

	public void save(T entity)
	{
		this.getHibernateTemplate().save(entity);
	}

	/**
	 * 删除
	 */
	public void delete(T entity)
	{
		this.getHibernateTemplate().delete(entity);
	}

	/**
	 * 通过属性删除
	 */
	public void deleteByProperty(String propertyName, Object value)
	{
		String queryString = "delete from " + getPersistentClass().getName()
				+ " as model where model." + propertyName + "= ?";
		Query query = this.getSession().createQuery(queryString);
		query.setParameter(0, value);
		query.executeUpdate();
	}

	/**
	 * saveOrUpdate
	 */
	public void saveOrUpdate(T entity)
	{
		this.getHibernateTemplate().saveOrUpdate(entity);
	}

	/**
	 * 更新
	 */
	public void update(T entity)
	{
		this.getHibernateTemplate().update(entity);
	}

	/**
	 * 分页查找所有的记录
	 * 
	 * @param page
	 *            要返回的页数
	 * @param pageSize
	 *            没有记录数
	 * @return
	 */
	public List<T> findAll(int page, int pageSize)
	{
		String queryString = "from " + getPersistentClass().getName();
		Query query = this.getSession().createQuery(queryString);
		int firstResult = (page - 1) * pageSize;
		query.setFirstResult(firstResult);
		query.setMaxResults(pageSize);
		return query.list();
	}

	/**
	 * 统计所有记录的总数
	 * 
	 * @return 总数
	 */
	public int countAll()
	{
		String queryString = "select count(*) from "
				+ getPersistentClass().getName();
		Query query = this.getSession().createQuery(queryString);
		List list = query.list();
		Long result = (Long) list.get(0);
		return result.intValue();
	}

	/**
	 * find By Example
	 * 
	 * @param entity
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<T> findByExample(T entity)
	{
		return this.getHibernateTemplate().findByExample(entity);
	}

	@SuppressWarnings("unchecked")
	public List<T> findAll()
	{
		return this.getHibernateTemplate().find(
				"from " + getPersistentClass().getName());
	}

	/**
	 * 通过属性查找
	 * 
	 * @param propertyName
	 *            属性名称
	 * @param value
	 *            属性的值
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<T> findByProperty(String propertyName, Object value)
	{
		String queryString = "from " + getPersistentClass().getName()
				+ " as model where model." + propertyName + "= ?";
		return this.getHibernateTemplate().find(queryString, value);

	}

	/**
	 * 通过多个属性组合查询
	 * 
	 * @param propertyNames
	 *            属性名称数组
	 * @param values
	 *            对应于propertyNames的值 return 匹配的结果
	 */
	public List<T> findByPropertys(String[] propertyNames, Object[] values)
	{
		StringBuffer strBuffer = new StringBuffer();
		strBuffer.append("from " + getPersistentClass().getName());
		strBuffer.append(" as model where ");
		for (int i = 0; i < propertyNames.length; i++)
		{
			if (i != 0)
				strBuffer.append(" and");
			strBuffer.append(" model.");
			strBuffer.append(propertyNames[i]);
			strBuffer.append("=");
			strBuffer.append("? ");
		}
		String queryString = strBuffer.toString();
		return this.getHibernateTemplate().find(queryString, values);
	}

	/**
	 * 通过属性查找并分页
	 * 
	 * @param propertyName
	 *            属性名称
	 * @param value
	 *            属性值
	 * @param page
	 *            页数
	 * @param pageSize
	 *            每页显示条数
	 */
	public List<T> findByProperty(String propertyName, Object value, int page,
			int pageSize)
	{
		return this.findByPropertys(new String[]
		{
			propertyName
		}, new Object[]
		{
			value
		}, page, pageSize);
	}

	/**
	 * 通过多个属性组合查询
	 * 
	 * @param propertyNames
	 *            属性名称数组
	 * @param values
	 *            对应于propertyNames的值
	 * @param page
	 *            页数
	 * @param pageSize
	 *            每页显示数 return 匹配的结果 return 匹配的结果
	 */
	public List<T> findByPropertys(String[] propertyNames, Object[] values,
			int page, int pageSize)
	{

		StringBuffer strBuffer = new StringBuffer();
		strBuffer.append("from " + getPersistentClass().getName());
		strBuffer.append(" as model where ");
		for (int i = 0; i < propertyNames.length; i++)
		{
			if (i != 0)
				strBuffer.append(" and");
			strBuffer.append(" model.");
			strBuffer.append(propertyNames[i]);
			strBuffer.append("=");
			strBuffer.append("? ");
		}
		String queryString = strBuffer.toString();

		int firstResult = (page - 1) * pageSize;

		Query query = this.getSession().createQuery(queryString);
		query.setFirstResult(firstResult);
		query.setMaxResults(pageSize);
		for (int i = 0; i < values.length; i++)
		{
			query.setParameter(i, values[i]);
		}

		return query.list();
	}

	/**
	 * 通过属性统计数量
	 * 
	 * @param propertyName
	 *            属性名称
	 * @param value
	 *            属性值
	 */
	public int countByProperty(String propertyName, Object value)
	{
		String[] propertyNames = new String[]
		{
			propertyName
		};
		Object[] values = new Object[]
		{
			value
		};
		return this.countByPropertys(propertyNames, values);
	}

	/**
	 * 通过多个属性统计数量
	 * 
	 * @param propertyNames
	 *            属性名称数组
	 * @param values
	 *            对应的属性值数组 return
	 */
	public int countByPropertys(String[] propertyNames, Object[] values)
	{
		StringBuffer strBuffer = new StringBuffer();
		strBuffer.append("select count(*) from "
				+ getPersistentClass().getName());
		strBuffer.append(" as model where ");
		for (int i = 0; i < propertyNames.length; i++)
		{
			if (i != 0)
				strBuffer.append(" and");
			strBuffer.append(" model.");
			strBuffer.append(propertyNames[i]);
			strBuffer.append("=");
			strBuffer.append("? ");
		}

		String queryString = strBuffer.toString();
		Query query = this.getSession().createQuery(queryString);
		for (int i = 0; i < values.length; i++)
		{
			query.setParameter(i, values[i]);
		}

		List list = query.list();
		Long result = (Long) list.get(0);
		return result.intValue();
	}

	/**
	 * 查找T并通过某一属性排序
	 * 
	 * @param property
	 *            排序依据的顺序
	 * @param isSequence
	 *            是否顺序排序,false为倒序
	 */
	public List<T> findAndOrderByProperty(int firstResult, int fetchSize,
			String propertyName, boolean isSequence)
	{
		String queryString = "from " + getPersistentClass().getName()
				+ " as model order by model." + propertyName;
		if (isSequence == false)
		{
			queryString = queryString + " DESC";
		}

		Query queryObject = getSession().createQuery(queryString);
		queryObject.setFirstResult(firstResult);
		queryObject.setMaxResults(fetchSize);
		return queryObject.list();

	}

	/**
	 * 查找所有并通过某个属性排序
	 * 
	 * @param propertyName
	 *            排序依据的属性名称
	 * @param isSequence
	 *            是否顺序排列
	 */
	public List<T> findAllAndOrderByProperty(String propertyName,
			boolean isSequence)
	{
		String queryString = "from " + getPersistentClass().getName()
				+ " as model order by model." + propertyName;
		if (isSequence == false)
		{
			queryString = queryString + " DESC";
		}

		Query queryObject = getSession().createQuery(queryString);
		return queryObject.list();
	}

}


3.具体的DAO接口(继承IBaseDao):
package com.rc.video.dao;

import com.rc.video.common.base.IBaseDao;
import com.rc.video.pojo.TUser;

/**
 * 用户Dao
 * 
 * @author pasu
 * @see com.rc.video.common.base.IBaseDao
 *  @vesion 1.0, 2008-3-2
 */
public interface IUserDao extends IBaseDao<TUser,String>
{
	/**
	 * 通过用户名查找用户
	 * 
	 * @param 	userName 	用户名
	 * @return 	TUser 		用户对象,如果用户名不存在返回null
	 */
	public  TUser findByUserName(String userName);  
}


4.具体的Dao实现(Hibernate)

package com.rc.video.dao.hibernate;

import java.util.List;

import com.rc.video.common.base.BaseHibernateDao;
import com.rc.video.dao.IUserDao;
import com.rc.video.pojo.TUser;

/**
 * 用户Dao
 * @author pasu
 * @vesion 1.0, 2008-3-2
 *
 */
public class UserHibernateDao extends BaseHibernateDao<TUser,String> implements IUserDao
{
	// property constants
	public static final String USER_NAME = "userName";
	
	/**
	 * 通过名称查找用户
	 * @return TUser 
	 */
	public TUser findByUserName(String userName)
	{
		List<TUser> userList = super.findByProperty(USER_NAME, userName);
		if(userList.size() != 0)
		{
			return userList.get(0);
		}
		else
		{
			return null;
		}
	}
}

4
0
分享到:
评论
3 楼 pipal 2013-09-12  
真是知我者谓我何忧,不知我者谓我何求,你不了解其中的精妙就别乱说

xman 写道
看不出这种方式比原来写一个BaseDaoImpl好在哪里。
没事干还要写一个空的Dao实现类?就是为了把getEntity(Class class, Integer id)变成getEntity(Integer id)这样一点代码量?
那多出来的这一陀代码呢?
public interface IUserDao extends IBaseGenericDao<User, Integer> {

}
public class UserDaoImpl extends BaseGenericDaoImpl<User, Integer> implements IUserDao {

}
再加上spring配置文件加上
<bean id="userDao" class="com.....UserDaoImpl" >
  <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

不可理喻啊。


2 楼 hongshenghome 2010-10-14  
直接写成一个类就行了,没必要写成接口,写成了反而增加spring配置代码
1 楼 xman 2009-07-10  
看不出这种方式比原来写一个BaseDaoImpl好在哪里。
没事干还要写一个空的Dao实现类?就是为了把getEntity(Class class, Integer id)变成getEntity(Integer id)这样一点代码量?
那多出来的这一陀代码呢?
public interface IUserDao extends IBaseGenericDao<User, Integer> {

}
public class UserDaoImpl extends BaseGenericDaoImpl<User, Integer> implements IUserDao {

}
再加上spring配置文件加上
<bean id="userDao" class="com.....UserDaoImpl" >
  <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

不可理喻啊。

相关推荐

Global site tag (gtag.js) - Google Analytics