0

我检查了很多样本​​,但我没有找到合适的解决方案。一些文档说“理想情况下,您的业务逻辑层不应该知道有数据库。它不应该知道连接字符串或 SQL。”

我发现了一些将业务逻辑定位到 @Service 注释类的示例,但它们在 @Service 方法中使用 SQL/HQL。

理想的用法应该是什么?如果我们想更改数据库或持久性技术,我们应该只更改 @Repository 注释的类还是两者都更改?

4

3 回答 3

2

在您的服务方法中,您不应使用任何 SQL/HQL 语法或任何数据库工作。所有这些都应该在 DAO 层中,并被注释为@Repository。您应该只从您的服务方法中调用它们。这样,您将来可以轻松更改数据库。不然负担太重了

于 2012-10-27T14:55:14.503 回答
2

我更喜欢将所有与持久性相关的东西(即查询,以及处理 JDBC、JPA 或 Hibernate 的所有东西)放在 DAO 层中,并让服务层依赖这个 DAO 层来处理与持久性相关的东西。

但主要目标是不能在不影响服务层的情况下改变持久化技术。例如,如果从 Hibernate 切换到 JPA,这可能是可能的,但如果从 JPA 切换到 JDBC,就不可能了。原因是

  • JPA 自动持久化对实体所做的所有更改,而无需更新数据库查询,而 JDBC 则不需要,因此需要额外的更新查询
  • JPA 延迟加载实体之间的关联,而 JDBC 没有
  • ...

所以改变持久化技术会影响服务层,即使所有持久化的东西都被隔离在 DAO 中。

恕我直言,这种解耦的主要优点是

  • 每个班级的职责更加明确。它避免了将持久性相关代码与业务逻辑代码混合在一起。
  • 可测试性:您可以通过模拟 DAO 层轻松测试您的服务层。您可以轻松地测试 DAO 层,因为它所做的只是对数据库执行查询。
于 2012-10-27T14:57:25.590 回答
2

理想情况下,您的业务逻辑处理或由对域建模的对象组成。它不应该意识到持久性等问题。这就是像休眠这样的 O/R-Mapper 的全部内容。业务逻辑需要基于域属性(如员工姓名、上个月收入...)的所需对象。

持久层应该能够将业务需求转换为 SQL/HQL/Service 调用或所使用的任何技术要求。因此,业务逻辑层只有在业务逻辑发生变化时才会发生变化。

这将是理想世界的目标,但实际上它不适用于非平凡的问题。你无法避免某种程度的耦合。但正如@JB Nizet 所说,将耦合减少到合理的数量是值得的。使用 TDD 并遵守 SRP 等 OO 原则将帮助您实现目标。

于 2012-10-27T15:04:33.583 回答