由于要求在项目中使用泛型的DAO,所以上网Google了一下,找到了IBM的一篇文章。文章讲得不错,但是有些地方不清楚,如果完全按照那篇文章可能还会遇到一些困难。所以写了这篇文章,解释如何在项目中加入泛型的DAO实现。
首先是总的类关系的UML图:

然后是在配置文件中的关系图:

其中,IStaffDao是我们自己定义的接口,这个接口类似:

public interface IStaffDAO extends GenericDao < Staff,Integer >
{

public ListlistAll();

public StaffgetByLogonAndId(Stringlogon,Integerid);

// more

}

GenericDao<T , PK extends Serilizable> 是泛型的 Dao 接口:

/***/ /**
*2006-11-22
*范型DAO接口
* @author ZouAng
*Contact<ahref="mailto:richardeee@gmail.com">ZouAng</a>
*/

public interface GenericDao < T,PK extends Serializable >
{


/***/ /**
*保存一个对象到数据库
* @param newInstance需要保存的对象
* @return
*/
PKcreate(TnewInstance);

/***/ /**
*从数据库读取一个对象
* @param id主键
* @return
*/
Tread(PKid);


/***/ /**
*更新一个对象
* @param transientObject被更新的对象
*/
void update(TtransientObject);


/***/ /**
*删除一个对象
* @param transientObject被删除的对象
*/
void delete(TtransientObject);
}
GenericDaoHibernateImpl 是 GenericDao 接口的泛型实现 :


/***/ /**
*2006-11-22
*范型DAO实现
* @author ZouAng
*Contact<ahref="mailto:richardeee@gmail.com">ZouAng</a>
*/
public class GenericDaoHibernateImpl < T,PK extends Serializable >
extends HibernateDaoSupport

implements GenericDao < T,PK > ,FinderExecutor
{

private Class < T > type;
private FinderNamingStrategynamingStrategy = new SimpleFinderNamingStrategy(); // Default.Canoverrideinconfig
private FinderArgumentTypeFactoryargumentTypeFactory = new SimpleFinderArgumentTypeFactory(); // Default.Canoverrideinconfig


public GenericDaoHibernateImpl(Class < T > type)
{
this .type = type;
}


/**/ /* (non-Javadoc)
*@seecom.gdnfha.atcs.common.service.dao.GenericDao#create(java.lang.Object)
*/

public PKcreate(TnewInstance)
{
return (PK)getHibernateTemplate().save(newInstance);
}


/**/ /* (non-Javadoc)
*@seecom.gdnfha.atcs.common.service.dao.GenericDao#delete(java.lang.Object)
*/

public void delete(TtransientObject)
{
getHibernateTemplate().delete(transientObject);
}


/**/ /* (non-Javadoc)
*@seecom.gdnfha.atcs.common.service.dao.GenericDao#read(java.io.Serializable)
*/

public Tread(PKid)
{
return (T)getHibernateTemplate().get(type,id);
}


/**/ /* (non-Javadoc)
*@seecom.gdnfha.atcs.common.service.dao.GenericDao#update(java.lang.Object)
*/

public void update(TtransientObject)
{
getHibernateTemplate().update(transientObject);
}

public List < T > executeFinder(Methodmethod, final Object[]queryArgs)

{
final QuerynamedQuery = prepareQuery(method,queryArgs);
return (List < T > )namedQuery.list();
}

public Iterator < T > iterateFinder(Methodmethod, final Object[]queryArgs)

{
final QuerynamedQuery = prepareQuery(method,queryArgs);
return (Iterator < T > )namedQuery.iterate();
}

private QueryprepareQuery(Methodmethod,Object[]queryArgs)

{
final StringqueryName = getNamingStrategy().queryNameFromMethod(type,method);
final QuerynamedQuery = getSession().getNamedQuery(queryName);
String[]namedParameters = namedQuery.getNamedParameters();
if (namedParameters.length == 0 )

{
setPositionalParams(queryArgs,namedQuery);

} else
{
setNamedParams(namedParameters,queryArgs,namedQuery);
}
return namedQuery;
}

private void setPositionalParams(Object[]queryArgs,QuerynamedQuery)

{
// Setparameter.UsecustomHibernateTypeifnecessary
if (queryArgs != null )

{
for ( int i = 0 ;i < queryArgs.length;i ++ )

{
Objectarg = queryArgs[i];
TypeargType = getArgumentTypeFactory().getArgumentType(arg);
if (argType != null )

{
namedQuery.setParameter(i,arg,argType);
}
else

{
namedQuery.setParameter(i,arg);
}
}
}
}

private void setNamedParams(String[]namedParameters,Object[]queryArgs,QuerynamedQuery)

{
// Setparameter.UsecustomHibernateTypeifnecessary
if (queryArgs != null )

{
for ( int i = 0 ;i < queryArgs.length;i ++ )

{
Objectarg = queryArgs[i];
TypeargType = getArgumentTypeFactory().getArgumentType(arg);
if (argType != null )

{
namedQuery.setParameter(namedParameters[i],arg,argType);
}
else

{

if (arg instanceof Collection)
{
namedQuery.setParameterList(namedParameters[i],(Collection)arg);
}
else

{
namedQuery.setParameter(namedParameters[i],arg);
}
}
}
}
}

public FinderNamingStrategygetNamingStrategy()

{
return namingStrategy;
}

public void setNamingStrategy(FinderNamingStrategynamingStrategy)

{
this .namingStrategy = namingStrategy;
}

public FinderArgumentTypeFactorygetArgumentTypeFactory()

{
return argumentTypeFactory;
}

public void setArgumentTypeFactory(FinderArgumentTypeFactoryargumentTypeFactory)

{
this .argumentTypeFactory = argumentTypeFactory;
}

}
FinderNamingStrategy 是查找方法的命名规范:
public interface FinderNamingStrategy

{
public StringqueryNameFromMethod(ClassfindTargetType,MethodfinderMethod);
}
目前有两个命名查找策略,使用的是
Simple 的,也就是直接是
< 类型名
>.< 方法名
> 的形式。
public class SimpleFinderNamingStrategy implements FinderNamingStrategy

{
public StringqueryNameFromMethod(ClassfindTargetType,MethodfinderMethod)
