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

Posted

技术标签:

【中文标题】数据源动态变化时如何设计DAO【英文标题】:How to design DAOs when the datasource varies dynamically 【发布时间】:2010-10-05 18:21:48 【问题描述】:

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

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

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

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

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

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

【问题讨论】:

【参考方案1】:

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

【讨论】:

【参考方案2】:

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

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

通过传递参数从Factory中获取dao。在Dao工厂内部决定返回哪个Dao实现..

【讨论】:

【参考方案3】:

你可能想看看这个类:

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/

【讨论】:

【参考方案4】:

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

【讨论】:

【参考方案5】:

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

【讨论】:

以上是关于数据源动态变化时如何设计DAO的主要内容,如果未能解决你的问题,请参考以下文章

Entity Framework Core 中的动态变化模式

如何使此JPanel中的像素动态变化?

线程池动态自适应变化

QT如何获得当前时间的秒,要是动态变化的,能用指针接收

如果数据动态变化,如何修复 HTML 中表格行的背景颜色(静态)?

GridLayout 动态变化以填充 Gone 视图