Orm 数据映射器和存储库之间到底有什么区别?

Orm 数据映射器和存储库之间到底有什么区别?,orm,repository,repository-pattern,datamapper,domain-model,Orm,Repository,Repository Pattern,Datamapper,Domain Model,我一直在试图找出数据映射器和存储库之间的区别,但到目前为止我还没有找到。在我看来,专家程序员说“存储库是映射层上的另一个抽象层,查询构造代码集中在映射层上”。这似乎可以理解,但还是有点抽象。我以前读过这篇关于stackoverflow的文章,它让我更加困惑: 我想我需要的是简单的解释和具体的/实际的例子,说明这两种模式的区别,以及存储库做什么和数据映射器做什么,反之亦然。你们中有谁知道一个很好的例子来说明数据映射器和存储库的概念吗?如果是同一个示例,就更好了,一个使用数据映射器,另一个使用存储

我一直在试图找出数据映射器和存储库之间的区别,但到目前为止我还没有找到。在我看来,专家程序员说“存储库是映射层上的另一个抽象层,查询构造代码集中在映射层上”。这似乎可以理解,但还是有点抽象。我以前读过这篇关于stackoverflow的文章,它让我更加困惑:


我想我需要的是简单的解释和具体的/实际的例子,说明这两种模式的区别,以及存储库做什么和数据映射器做什么,反之亦然。你们中有谁知道一个很好的例子来说明数据映射器和存储库的概念吗?如果是同一个示例,就更好了,一个使用数据映射器,另一个使用存储库。谢谢,我非常感谢。到现在为止我仍然很困惑

假设您的应用程序管理
Person
对象,每个实例都有
name
age
jobTitle
属性

您希望持久化这些对象,从持久化介质中检索它们,并可能更新(例如,在它们的生日,增加年龄)或删除它们。这些任务通常称为CRUD,来自创建、读取、更新和删除

最好将“业务”逻辑与处理
Person
对象持久性的逻辑分离。这允许您在不影响业务逻辑的情况下更改持久性逻辑(例如,从DB到分布式文件系统)

您可以通过将所有持久性逻辑封装在
存储库
后面来实现这一点。假设的
PersonRepository
(或
Repository
)允许您编写如下代码:

personjohndoe=personRepository.get(p=>p.name==“johnDoe”);
johnDoe.jobTitle=“IT专家”;
personRepository.update(约翰多)

这只是业务逻辑,不关心对象的存储方式和位置

存储库
的另一端,您可以使用
数据映射器
和将查询从功能描述(
p=>p.name==“John Doe”
转换为持久性层能够理解的内容)转换成的东西

持久化层可以是DB,在这种情况下,
DataMapper
Person
对象与
PersonsTable
中的行进行转换。然后,查询转换器将函数查询转换为
SELECT*fromPersonTable,其中name==“johndoe”

另一个持久化层可以是文件系统,也可以是另一种DB格式,它选择将
Person
对象存储在两个表中,
PersonAge
PersonJobTitle

在后一种情况下,
DataMapper
负责将
johnDoe
对象转换为两行:一行用于
PersonAge
表,另一行用于
PersonJobTitle
表。然后,查询逻辑需要将函数查询转换为两个表上的
join
。最后,
DataMapper
需要知道如何从查询结果构造
Person
对象

在大型复杂系统中,您希望使用能够独立开发和测试的小型组件来完成小型、明确定义的任务:

  • 当业务逻辑想要读取或持久化对象时,它处理
    存储库
    ,而不关心如何实现
  • Repository
    在需要在特定持久性介质中读取/写入对象时,处理
    DataMapper
  • 对于查询,
    Repository
    依赖于
    DataMapper
    提供的模式(例如
    jobTitle
    值位于
    PersonTable
    表的
    jobTitle
    列中),但不依赖于映射器的任何实现
  • 对于DB持久性,
    DataMapper
    依赖于一个DB层,它屏蔽了Oracle/Sybase/MSSQL/OtherProvider详细信息

这些模式并不“不同”,它们只是揭示了不同的基本特征。

我意识到这个答案有点晚了,但它可能会帮助将来偶然发现同一个问题的人,发现可用的答案并不能完全回答这个问题(我第一次遇到这个问题时的感觉)

在阅读了PoEAA(Martin Fowler)之后,我也很难识别数据映射器和存储库之间的区别

我发现这两个概念最终归结为:

  • 存储库的作用类似于域对象的集合,具有强大的查询功能(Evans,DDD)
  • 数据映射器“在对象和数据库之间移动数据,同时使它们彼此独立,并使映射器本身独立”(Fowler,PoEAA)
存储库是一个通用概念,不一定要将任何内容存储到数据库中,它的主要功能是提供对域对象的类似于集合(支持查询)的访问(无论它们是否从数据库中获取都不重要)。存储库本身可能(通常也会)包含数据映射器


数据映射器充当域对象和数据库之间的中间层,允许它们独立发展,没有任何一个依赖于另一个。数据映射器可能具有“查找”或查询功能,但这并不是它们的主要功能。您越是发现自己在DataMapper中使用复杂的查询逻辑,就越想开始考虑将该查询逻辑解耦到存储库中,同时让DataMapper发挥其主要功能,将域对象映射到数据库,反之亦然。

我明白了,谢谢您的解释。我认为存储库