存储库模式 – 如何理解它,以及它如何与“复杂”实体协同工作?

我很难理解版本库模式。

关于这个话题有很多意见,比如在Repository模式中做对了,而像Repository这样的其他东西是新的Singleton或者再次像不要使用DAO使用Repository或者只是采用Spring JPA Data + Hibernate + MySQL + MAVEN在哪里存储库似乎与DAO对象相同。

我已经厌倦了阅读这个东西,因为它不能像很多文章中显示的那样困难。

我是这样看的:看来我想要的是这样的:

------------------------------------------------------------------------ | Server | ------------------------------------------------------------------------ | | | | Client <-|-> Service Layer <-|-> Repository Layer <-|-> ORM / Database Layer | | | | | ------------------------------------------------------------------------ 

Service Layer采用*DTO对象,并将这些对象传递给Repository Layer ,它只不过是知道一个实体如何存储的“人”。

例如假设你有一些工具的组成( 请注意,这只是伪代码

 @Entity class ToolSet { @Id public Long id; @OneToOne public Tool tool1; @OneToOne public Tool tool2; } @Entity class Tool { @Id public Long id; @OneToMany public ToolDescription toolDescription; } @Entity class ToolDescription { @Id public Long id; @NotNull @OneToOne public Language language public String name; public String details; } 

我没有得到的是我从客户端获取ToolSetDTO对象的部分。

据我了解,到目前为止,我可以用ToolSetRepository.save(ToolSetDTO toolSetDto)编写一个ToolSetRepository ,它知道如何存储一个ToolSetDTO 。 但几乎每个教程都不会通过*DTO而是通过Entity

这里有什么困扰我的是,如果你从上面拿我的ToolSet例子,我必须执行以下步骤:

  1. toolSetDto并检查是否为null
  2. 对于toolSetDto拥有的每个tool*Dto toolSetDto
    a)如果有一个有效的id然后从DTO转换成Entity否则创build一个新的数据库条目
    b) toolDescriptionDto并将其转换/保存到数据库或创build一个新条目
  3. 在检查上面的ToolSet (entity)之后,将其设置为在数据库中保存

所有这些都太复杂了,不能让服务函数(客户端的接口)来处理这个。

我在想的是创build一个例如ToolSetRepository但这里的问题是

  • 是否需要一个ToolSet实体对象或它使用DTO对象?
  • 在任何情况下: *Repository允许使用其他存储库对象? 就像我想要保存ToolSet但是我必须先存储ToolToolDescription – 我会在ToolSetRepository里面使用ToolRepositoryToolSetRepository吗?
    如果是这样的话:为什么不打破版本库模式? 如果这个模式基本上是服务和我的ORM框架之间的一个层,由于依赖性的原因,添加对其他*Repository类的依赖关系并不“正确”。

我不知道为什么我不能把我的头靠近这个。 这听起来并不复杂,但像Spring Data一样还是有帮助的。 另一件令我烦恼的事情,因为我真的不知道这是如何让事情变得更容易。 特别是因为我已经使用Hibernate – 我没有看到好处(但也许这是另一个问题)。

所以..我知道这是一个很长的问题,但是我已经把它研究了几天了。 现在已经存在的代码已经开始变得混乱了,因为我无法看穿这个模式。

我希望有人能给我一个比大多数的文章和教程更大的图片,这些文章和教程没有超越实现一个非常简单的存储库模式的例子。

您可以阅读我的“存储库傻瓜” 后了解存储库的简单原则 。 我认为你的问题是你正在使用DTO,在这种情况下,你并没有真正使用存储库模式,你正在使用一个DAO。

存储库和dao之间的主要区别在于一个存储库只返回被调用层理解的对象。 大多数情况下,存储库由业务层使用,因此它会返回业务对象。 一个dao返回可能或可能不是整个业务对象的数据,即数据不是一个有效的业务概念。

如果你的业务对象只是数据结构,这可能是一个暗示,你有一个build模问题,即糟糕的devise。 使用“丰富”或至less适当封装的对象,存储库更有意义。 如果你只是加载/保存数据结构,可能你不需要一个仓库,ORM就足够了。

如果您正在处理由其他对象(聚合)组成的业务对象,并且该对象需要其所有部分才能保持一致 (聚合根),那么存储库模式是最好的解决scheme,因为它将抽象所有持久性详细信息。 您的应用程序将只需要一个“产品”,无论需要多less个表或查询来恢复对象,存储库都会将其作为一个整体返回。

根据您的代码示例,您没有“真正的”业务对象。 你有Hibernate使用的数据结构。 业务对象是基于业务概念和用例而devise的。 该存储库使得BL不可能关心该对象如何被持久化。 从某种意义上说,存储库就像对象和模型之间的“转换器/映射器”,它将被持久化。 基本上回购“减less”对象的持久性数据所需的。

一个业务对象不是一个ORM实体。它可能来自技术angular度,但是从deviseangular度来看,一个业务模型是其他模型持久化的东西。 在许多情况下,这些不直接兼容。

最大的错误是根据存储需求和思维devise您的业务对象。 与许多开发人员认为的相反,ORM的目的不是坚持业务对象。 其目的是模拟一个rdbms上的“oop”数据库​​。 ORM映射是在数据库对象和表之间,而不是在应用程序对象(处理业务对象时更less)和表之间。