请教DAO和DAOFactory的实现

03-05-11 anonymous
         

在我当前的工程种使用的是抽象工厂方法来实现,在消费者中只关心抽象层的调用,但在增加新的DAO时不得不更改所有的DAOFactory及其子类,这对扩展新功能有太多的不利,

而如果用工厂模式则需要创建很多的工厂类和产品类,但在切换数据库时又很麻烦

我现在的想法是申明一个DAO的抽象类,在其中定义所有的抽象存取方法,

而在DAOFactory中则工具给定的DAO名字或什么的创建并返回具体DAO子类

参看下面这篇文章:

JDBC对象的持续性:一种更好的方法

正在考虑其实现中

还有,在ChinaXP上说使用DAO池来保存DAO实例以提高重用率和效率,当消费者调用工厂方法取该DAO时都从池中取,有点类似Struts的Actions,但有个问题是此时只有一个DAO实例,那对该DAO中的方法是否该考虑同步?比如同时更新同一条记录时?

有点头晕了,呵呵,不知道各位大虾有何好的主意?

望指教,谢了先:)

         

banq
2003-05-12 15:33

我好像在之前帖子看过DAOFactory的思路。

其实EJB模型实际上实现你目前的困境,又通用性又方便,但是性能有所降低。

anonymous
2003-05-16 10:15

新系统中对DAO做了新的设计,基本思想为:

因为所有的数据存取操作只有四种:

新增(insert)

更新(update)

删除(delete)

查询(query)

而前三种可以再次抽象成一种操作:更新(update)

故而本系统DAO采用如下机制:

一个DAO抽象基类,高度抽象,仅提供有限的几个公有方法,所有DAO子类

将都继承自此类并实现两个抽象方法:

public abstract int update(opType);

public abstract Collection query(opType);

update涵盖了所有的更新操作,不同的操作由opType指定并由相应子类实现

query涵盖了所有的查询操作,以返回Collection结果

比如,新增加记录可用update(DAO.INSERT)来完成,而具体如何完成则是

实现类的职责,调用者只关心结果...

又入:final DAO accountDAO = DAOFactory.findDAO(AccountDAO.KEY);

accountDAO.addParam("id","1");

final Collection accounts = accountDAO.query(AccountDAO.SELECT_ACCOUNT_BYID);

...

在Action中,使用DAOFactory.findDAO(name)取具体实现DAO类,在工厂

实现中采用了缓存,即将使用过的DAO实例保存在一个dao pool中以提高

重用率,而所有的DAO都使用类似ActionMapping的机制由配置文件指定

具体使用的数据源和实现类:

<dao_mappings>

<dao name="UserDAO" currentType="mysql">

<dao_impl type="mysql"

implClass="org.skyinn.quasar.webapp.example.UserDAOMysqlImpl"/>

<dao_impl type="oracle"

implClass="org.skyinn.quasar.webapp.example.UserDAOOracleImpl"/>

</dao>

</dao_mappings>

因此在切换数据库或新增、修改、移除功能模块时将不影响原有系统,解决了抽象工

厂模式在增加新产品方面的困难

问题:

1,DAO高度抽象了所有的操作,可能因为太灵活而带来一些问题,

2,本系统只使用一个singleton的DAOFactory,不知道在处理大量请求时是否会有问题,有待测试,

3,dao pool中的DAO实例是否需要对某些方法同步?

4,因为使用了配置文件来指定DAO映射,因而可能出现重名DAO,如何从系统角度来保证

命名的唯一性?(当前的解决办法时子类需实现一个DAO接口,其中定义了标识该DAO的常量)

请高手指点,谢了先:)

Popo
2003-05-19 08:24

我打算这样写

public interface DataAccessObject {

public void insert(ValueObject insertRecord);

public void update(ValueObject updateRecord);

public void delete(ValueObject deleteRecord);

}

ValueObject为一抽象类,其他BEAN 继承这个抽象类