多个数据库的 Dao 接口?
Dao interface for multiple databases?
在DAO implementation
之前有一个DAO interface
的模式。我用谷歌搜索了这种模式的优点,一个引人注目的地方是支持多个数据库。
现在,我能理解的是,这里的多个数据库是指不同的数据库引擎,而不是多个数据源。显然,多个数据源不应该影响 DAO 实现如何由 DAO 接口构成。
我的问题是在什么情况下我们可能需要支持多个数据库引擎来处理相同的数据?另外,如果出现这种需要,将如何管理 REST endpoints
以支持不同的数据库?
他们会喜欢吗? /db1/courses/
, /db2/courses
?如果我在这个问题上有任何错误的假设或陈述,请纠正我。
我遇到过这种情况,我必须检查两个数据库并获取数据。另一个数据库是备份数据库。
这就是流程。
RestController --> Service --> DBService
--> DB1Repository --> Connect to DB1
--> DB2Repository --> Connect to DB2
我们可以随心所欲地设计,最后重要的是我们遵循 SOLID 原则。
基本上,高级组件不应该依赖于低级组件,但两者都应该依赖于抽象。
我只是想补充一下关于开始 Spring 开发的答案。这是一开始没有意义的事情之一。你最终会问自己:
- 只有 1 个数据库,所以这没有意义为什么要这样做?
- 当只有 1 个实现时我为什么要定义一个接口?
但实际上这些都不是您这样做的真正原因。但这是惯例和模式,这种风格正是人们所习惯的,随着时间的推移你会更喜欢它。还有其他一些原因:
- Spring 数据 - 这是使用实体管理器的替代方法,您只需定义接口,Spring 将实际创建为您实现存储库功能的 bean。
- 设计 - 确保定义接口将有助于使您的存储库保持存储库状态。
- 更简单的模拟 - 虽然可以说您仍然可以在 Spring 中执行此操作而无需定义接口,但当您想用另一个实现替换实现时它仍然更清晰一些。
但实际上这只是 Spring 方式,如果您这样做,人们会发现您的代码更容易理解。
我来这里描述一个真实世界的例子。
我们最近想将一个大型生产数据库 (Oracle) 更改为另一个数据库 (SQL 服务器)。
对于数据库的不同区域,我们有不同的 DAO 接口和实现。例如,CustomerDAO、AccountsDAO 等
对于每个接口(如 CustomerDAO),我们都有一个实现 (CustomerDAOImplOracle)。
我们编写 DAO 的 SQL 服务器版本(SQL 语法和 jdbc 库当然不同)并以最小的代价交换它们是相对直接的更改我们的业务逻辑(使用 DAO 的服务)。
因此,CustomerDAOImplOracle 在 CustomerDAOImplSQLServer 上重新实现。等等...
我们学到了什么:
- 接口提供了良好的抽象并允许多种实现
- DAO 层允许我们在必要时"switch out" 数据库(或其客户端库)
- 从业务逻辑中隐藏数据库的实现细节降低了耦合度和复杂性
在DAO implementation
之前有一个DAO interface
的模式。我用谷歌搜索了这种模式的优点,一个引人注目的地方是支持多个数据库。
现在,我能理解的是,这里的多个数据库是指不同的数据库引擎,而不是多个数据源。显然,多个数据源不应该影响 DAO 实现如何由 DAO 接口构成。
我的问题是在什么情况下我们可能需要支持多个数据库引擎来处理相同的数据?另外,如果出现这种需要,将如何管理 REST endpoints
以支持不同的数据库?
他们会喜欢吗? /db1/courses/
, /db2/courses
?如果我在这个问题上有任何错误的假设或陈述,请纠正我。
我遇到过这种情况,我必须检查两个数据库并获取数据。另一个数据库是备份数据库。
这就是流程。
RestController --> Service --> DBService
--> DB1Repository --> Connect to DB1
--> DB2Repository --> Connect to DB2
我们可以随心所欲地设计,最后重要的是我们遵循 SOLID 原则。 基本上,高级组件不应该依赖于低级组件,但两者都应该依赖于抽象。
我只是想补充一下关于开始 Spring 开发的答案。这是一开始没有意义的事情之一。你最终会问自己:
- 只有 1 个数据库,所以这没有意义为什么要这样做?
- 当只有 1 个实现时我为什么要定义一个接口?
但实际上这些都不是您这样做的真正原因。但这是惯例和模式,这种风格正是人们所习惯的,随着时间的推移你会更喜欢它。还有其他一些原因:
- Spring 数据 - 这是使用实体管理器的替代方法,您只需定义接口,Spring 将实际创建为您实现存储库功能的 bean。
- 设计 - 确保定义接口将有助于使您的存储库保持存储库状态。
- 更简单的模拟 - 虽然可以说您仍然可以在 Spring 中执行此操作而无需定义接口,但当您想用另一个实现替换实现时它仍然更清晰一些。
但实际上这只是 Spring 方式,如果您这样做,人们会发现您的代码更容易理解。
我来这里描述一个真实世界的例子。
我们最近想将一个大型生产数据库 (Oracle) 更改为另一个数据库 (SQL 服务器)。
对于数据库的不同区域,我们有不同的 DAO 接口和实现。例如,CustomerDAO、AccountsDAO 等
对于每个接口(如 CustomerDAO),我们都有一个实现 (CustomerDAOImplOracle)。
我们编写 DAO 的 SQL 服务器版本(SQL 语法和 jdbc 库当然不同)并以最小的代价交换它们是相对直接的更改我们的业务逻辑(使用 DAO 的服务)。
因此,CustomerDAOImplOracle 在 CustomerDAOImplSQLServer 上重新实现。等等...
我们学到了什么:
- 接口提供了良好的抽象并允许多种实现
- DAO 层允许我们在必要时"switch out" 数据库(或其客户端库)
- 从业务逻辑中隐藏数据库的实现细节降低了耦合度和复杂性