如何在数据源动态变化时设计DAO

时间:2009-02-05 18:53:03

标签: java spring dao

通常在定义DAO时,您将拥有DAO对象上数据源的setter。 我的问题是我们的数据源根据对服务器的请求动态变化。即每个请求都可以访问不同的数据库实例。

请求包含逻辑属性,稍后可用于检索与请求的DB的连接。

因此,当依赖项将DAO注入业务逻辑对象时,我需要一种在运行时(而不是配置时)在DAO上设置属性的方法。

一种解决方案是将数据源存储在本地线程上,但我真的不喜欢弄乱线程局部变量。

另一种选择是在业务逻辑对象上使用initialize方法,该方法使用请求属性调用DAO上的初始化。

我想这是一个常见的问题,你能提出一个共同的解决方案吗?

5 个答案:

答案 0 :(得分:8)

你的问题有点令人困惑。让一个DAO访问多个不同的数据源似乎是一个维护噩梦。因此,您应该定义一个DAO接口,其中包含您要调用的所有方法。对于您要连接的每个数据库,我将构建一个实现DAO接口的新类。这允许您有多个实现。然后我将这些实现(每个都有自己的数据源)存储在Map(java.util.Map)中,使用“逻辑属性”作为映射的关键。由于您的所有DAO实现都实现了您的界面,您将能够将它们转换为界面并交替使用它们。在您的业务对象上,您将注入DAO实现的Map。我希望这有助于你的设计。

答案 1 :(得分:6)

您可能需要查看此课程:

http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/jdbc/datasource/lookup/AbstractRoutingDataSource.html

这将使您的服务对象和数据访问对象更容易忽略动态数据源的任何概念。

通常,您需要实现servlet过滤器并使用ThreadLocal,以便AbstractRoutingDataSource使用的DataSourceLookup实现可以轻松访问指示返回哪个DataSource的请求参数。如果你真的想避免这种情况,你可以实现一个servlet过滤器,它在请求范围的bean上设置属性,并将该bean注入你编写的DataSourceLookup实现中。请求范围的bean在它们的实现中仍然使用ThreadLocal,但至少这是Spring的impl,而不是你的,你不需要担心它。 :)

Spring团队的博客文章详细介绍了类似的方法:

http://blog.springsource.com/2007/01/23/dynamic-datasource-routing/

答案 2 :(得分:5)

听起来你的问题是你正在为你的应用程序创建一个DAO实例。您需要为每个数据源创建一个单独的实例(可能需要某种dao控制器来为您管理它)或者可能允许您的dao中的方法是静态的,并传递有关如何连接到数据源的所有信息以及你坚持使用每种方法的数据。

答案 3 :(得分:5)

我在客户端/服务器项目上遇到了这样的问题。客户端和服务器项目共享Dao接口。当我以前做数据库操作时,我不得不选择合适的Dao实现。我的解决方案是这样的:

IVehicleDao vehicleDao =daoFactory.Get<IVehicleDao>(parameters);
vehicleDao.doSomething();

通过传递参数从工厂获取dao.Inside Dao工厂决定返回哪个Dao实现..

答案 4 :(得分:2)

我已经这样做了。您需要为每个类创建一个DAO,并且在DAO的范围内,您需要传递DATASOURCE,最后传递一个类CONTROLLER,您可以在其中动态调用DAO。