泛型/类型安全DAO编写

由于要求在项目中使用泛型的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);
}

GenericDaoHibernateImplGenericDao 接口的泛型实现 :


/***/ /**
*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)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值