【问题标题】:Is it okay to Autowire multiple repositories into another repository in Spring Data JPA?可以将多个存储库自动装配到 Spring Data JPA 中的另一个存储库中吗?
【发布时间】:2021-11-17 05:25:29
【问题描述】:

如下图所示,是否可以将多个存储库(JPA 接口)自动装配到另一个存储库(类)中

@Repository
public class repositoryClass {
@Autowired
private Repository1 repo1;
@Autowired
private Repository2 repo2;
}

这里的存储库 1 和 2 是 Spring Data JpaRepository 接口

repositoryClass 的目的是从repository1 和repository2 获取sql 查询,然后使用hibernate 执行它们,因为我将repo1 和repo2 自动装配到repositoryClass 中

【问题讨论】:

  • 它闻起来像一个糟糕的设计。请提供更多详细信息。
  • @chrylis-cautiouslyoptimistic- 为什么这是一个糟糕的设计?
  • @Pirate 我不是说它,但这种模式通常表明将应该分开或以不同方式组织的概念混合在一起。
  • 它们的组织方式已经不同,它解决的问题是服务层不需要知道我们拥有的所有存储库。我们可以创建主存储库,该存储库将提供对 dao 层的访问,以提供可以执行的所有功能。
  • @chrylis-cautiouslyoptimistic-repositoryClass 的目的是从 repository1 和 repository2 获取 sql 查询然后执行它们,因为我正在将它们自动装配到类中

标签: java spring hibernate spring-data-jpa


【解决方案1】:

这是糟糕的设计。除了打破 SOLID 的许多原则之外,这还导致了非常高的耦合。让我们首先回顾一下存储库的用途:

存储库模式非常简单。接口为特定实体(例如用户)定义了具有所有逻辑读写操作的存储库。

我们可以由此得出结论,存储库只有一个职责,即 CRUD 对特定实体的操作。然后,基于 SRP 原则,更改存储库实现的原因是当映射实体发生更改时(例如,我们向用户表添加了新列并且我们想从数据库中获取它)或者我们想要添加一些新功能来执行更多 CRUD 操作(在映射实体上!)。

diagram1,如果要更改repository4中的某些内容,则必须更改repository3repository2repository1,所以 SRP 原则被打破。这是一场建筑灾难。这是由于不同存储库之间的高度耦合。现在让我们考虑图2中显示的其他设计。适配器用于使用多个存储库执行某些更复杂的操作,并将应用程序业务层与数据层分开。如果 repository4 发生变化,我们将不得不更改 SomeAdapterB 但这不会影响业务逻辑,因为适配器是应用程序的一种网关。

总之,不要让存储库相互依赖。使用适配器。

PS 当你在 spring 中自动装配依赖时,使用构造函数注入!

【讨论】:

    【解决方案2】:

    来自Microsoft 网站

    存储库模式是一种有据可查的数据处理方式 资源。在《企业应用架构模式》一书中, Martin Fowler 对存储库的描述如下:

    存储库执行域之间的中介任务 模型层和数据映射,作用类似于一组 内存中的域对象。客户端对象以声明方式构建查询 并将它们发送到存储库以获取答案。从概念上讲,一个 存储库封装了一组存储在数据库中的对象和 可以对它们执行的操作,提供一种方法 更接近持久层。 存储库也支持 目的是明确地和在一个方向上分离依赖关系 在工作域和数据分配或映射之间。

    在我看来,最有趣的部分是最后一句话。设计模式(在本例中为Repository Pattern)的作用是通过提供经过验证的解决方案使事情变得简单。按照您的代码中显示的那样做,您违反了许多原则,例如separation of concernssingle responsability principleinterface segregation

    让事情尽可能简单。

    【讨论】:

      【解决方案3】:

      可以在一个类中添加多个存储库,比如主存储库。

      @Repository
      public class MasterRepository {
          @Autowired
          private Repository1 repo1;
          @Autowired
          private Repository2 repo2;
      }
      

      您将获得的好处是您不需要在您使用的每个类中添加每个存储库。您只需自动装配 masterrepository 并使用它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-04-07
        • 2011-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多