当前位置: 首页 > 知识库问答 >
问题:

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

马天逸
2023-03-14

我很难理解存储库模式。

关于这个主题有很多意见,比如在存储库模式中做得对,但也有其他东西,比如存储库是新的单例,或者像在不要使用DAO使用存储库或只是使用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编写ToolSetRepository。保存(ToolSetDTO ToolSetDTO)它“知道如何存储”一个ToolSetDTO。但几乎所有教程都不是通过*DTO,而是通过实体

这里让我感到困扰的是,如果你以我上面的工具集为例,我必须执行以下步骤:

  1. 工具集设置为并检查是否为null
  2. 对于toolSetDto
    a)拥有的每个tool*Dto如果有一个有效的id,则从Dto转换为实体否则创建一个新的数据库条目
    b)toolsdescriptiondto并将其转换/保存到数据库或创建一个新条目
  3. 在检查完以上内容后,实例化工具集(实体),并将其设置为在数据库中持久化

所有这些都太复杂了,不能简单地让服务功能(客户端接口)来处理。

我想的是创建一个例如ToolSetRepository,但这里的问题是

  • 它是采用ToolSet实体对象还是使用DTO对象?
  • 在任何情况下:*Repository是否允许使用其他存储库对象?就像当我想保存ToolSet但我必须首先存储ToolToolDescription-我会在ToolRepositoryToolDescriptionRepository内部使用ToolSetRepository吗?
    如果是这样:为什么它不破坏存储库模式?如果这个模式基本上是服务和我的ORM框架之间的一层,它只是不“感觉正确”添加依赖到其他*Repository类由于依赖原因。

我不知道为什么我不能理解这件事。听起来没那么复杂,但仍然有帮助,比如Spring Data。另一件事困扰着我,因为我真的不明白这如何让事情变得更容易。尤其是因为我已经在使用Hibernate了——我看不出它有什么好处(但这可能是另一个问题)。

所以我知道这是一个很长的问题,但我已经花了几天时间进行研究。我现在正在处理的已有代码开始变得一团糟,因为我无法看穿这种模式。

我希望有人能给我一个比大多数文章和教程更大的图景,这些文章和教程除了实现一个非常非常简单的存储库模式示例之外。


共有1个答案

左丘耀
2023-03-14

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

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

如果您的业务对象只是数据结构,这可能暗示您存在建模问题,即糟糕的设计。存储库对于“丰富”或至少正确封装的对象更有意义。如果你只是加载/保存数据结构,你可能不需要存储库,orm就足够了。

如果您正在处理由其他对象(聚合)组成的业务对象,并且该对象需要其所有部分才能保持一致(聚合根),那么存储库模式是最佳解决方案,因为它将抽象所有持久性细节。你的应用程序只会请求一个“产品”,存储库会将其作为一个整体返回,而不管恢复对象需要多少表或查询。

根据您的代码示例,您没有“真实”的业务对象。您有Hibernate使用的数据结构。业务对象是基于业务概念和用例设计的。存储库使BL可以不关心该对象是如何持久化的。在某种程度上,存储库充当对象和将被持久化的模型之间的“转换器/映射器”。基本上,repo将对象“减少”到持久化数据所需的大小。

业务对象不是ORM实体。它可能从技术角度来看,但从设计观点来看,一个模型业务内容,另一个模型持久性内容。在许多情况下,这些并不直接兼容。

最大的错误是根据存储需求和心态设计业务对象。与许多开发人员所认为的相反,ORM的目的不是持久化业务对象。它的目的是在rdbms之上模拟“oop”数据库。ORM映射在您的db对象和表之间,而不是应用对象(在处理业务对象时更少)和表之间。

 类似资料:
  • 问题内容: 我很难理解存储库模式。 关于该主题有很多意见,例如在Repository模式中做得正确,但其他信息,例如Repository是新的Singleton或再次,例如在Do n’t use DAO use Repository中, 或者只是以某种方式使用Spring JPA Data + Hibernate + MySQL + MAVEN 存储库似乎与DAO对象相同。 我厌倦了阅读这些东西,

  • 问题内容: 这个问题已经在这里有了答案 : 9年前关闭。 可能重复: 什么是SQL注入? 我看到很多php代码在stackoverflow上四处飘荡,字符串的转义太少了。 谁能 说明什么是SQL注入; 说明它可以对您的服务器,数据和代码执行的操作; 举例说明如何执行SQL注入 给php示例代码如何防止SQL注入 问题答案: 我也无法抗拒。 SQL注入是“一种代码注入技术,可利用应用程序数据库层中发

  • 问题内容: 我已经阅读了很多资源,但仍然坚持了解时间的复杂性。我阅读的资源是基于各种公式的,我理解这是用来表示时间复杂度的,但是我不知道如何。任何人都可以以一种可以理解的清晰方式向我解释这个原则。 问题答案: 参考:如何计算时间复杂度算法 我找到了一篇与 如何计算任何算法或程序的时间复杂度* 有关的好文章 * 计算时间复杂度最常用的指标是Big O表示法。这消除了所有恒定因素,因此当N接近无穷大时

  • 问题内容: 我正在编写一个应用程序,希望在其中具有文档的近实时协作编辑功能(非常类似于Google Documents样式编辑)。 我知道如何跟踪光标位置,这很简单。只需使用可存储在数据库中的当前用户ID,文件名,行号和行号每半秒或第二秒轮询服务器,该轮询请求的返回值就是其他用户游标的位置。 我不知道该怎么做,就是以一种不会使您的光标移开并强制完全重新加载的方式来更新文档,因为这样做对我来说太慢了

  • 请解释Spring中关于异常的以下内容: 这是什么意思? 在什么条件下抛出? 如何预防? 这篇文章是关于使用Spring的应用程序中出现的全面问答。

  • 本文向大家介绍Doctype作用?严格模式与混杂模式如何区分?它们有何意义?相关面试题,主要包含被问及Doctype作用?严格模式与混杂模式如何区分?它们有何意义?时的应答技巧和注意事项,需要的朋友参考一下 参考回答: Doctype声明于文档最前面,告诉浏览器以何种方式来渲染页面,这里有两种模式,严格模式和混杂模式。 严格模式的排版和JS 运作模式是 以该浏览器支持的最高标准运行。 混杂模式,向