在应用程序中,至少有两种方法可以处理域对象持久化和 ORM。
- 使用某种 ORM(xml 或注释)将域对象直接映射到持久性
- 关注点分离,以防您的域和持久模型(表格列)之间存在大量阻抗不匹配。这意味着,领域对象是持久性不可知的,并且有一些转换到一些相应的持久性对象,后者映射到 ORM。
纯 DDD 开发人员都知道,域不应该由您的数据库需求驱动,因此在我的项目中,我使用了这种关注点分离。有人会想到 YAGNI,有人会说“很棒”(比如 here )。根据我对可重用性的需要,我的项目将需要一些不同的数据库,所以我选择了领域模型和持久模型之间的关注点分离。
但是我遇到了 Spring-Data 的问题(某种性能损失)。
可能是一个细节,但假设一个 ORM 不具有 merge
或任何相关的功能,以将分离的实体重新附加到当前事务。
为了理解,让我们假设这个概念代码(在 Java 中):
@Transaction
public void participateToMeeting(String userId, String meetingId){
User user = userRepository.ofId(userId); //returns a User domain type
Meeting meeting = meetingRepository.ofId(meetingId); //returns a Meeting domain type
if(user != null && meeting != null) {
user.participate(meeting); // as attached entity, this would automatically persist the relationship
}
}
但是如果从今以后,持久化发生在持久化模型上,而不是直接在领域模型上,我们就会失去附件,因为在从领域到持久化对象的转换过程中(实际上,存储库现在会处理持久化对象(而不是领域模型直接)并仅将结果转换为域对象作为返回类型),managedEntity
状态将丢失。
@Transaction
public void participateToMeeting(String userId, String meetingId){
User user = userRepository.ofId(userId); //returns a User domain type (converted from UserPO to User)
Meeting meeting = meetingRepository.ofId(meetingId); //returns a Meeting domain type (converted from MeetingPO to UserPO)
if(user != null && meeting != null) {
userRepository.participateToMeeting(user, meeting);
//although not conventional, adding this kind of method allows to convert User and Meeting to some persistent object: UserPO and MeetingPO, before proceeding to persistence
}
}
问题来了:
在从 User
转换为 UserPO
时(在我的 infrastructure 层中),我丢失了实体“附件”。因此,在 userRepository.participateToMeeting
方法中,我必须再次从数据库中检索 UserPO
和 MeetingPO
(以附加它们)...因此涉及两个额外的请求。
是否有更好的做法来处理域对象/持久对象的转换而不会造成这种性能损失?
最佳答案
我不同意链接的文章。虽然我同意域模型和持久性模型之间的关注点是不同的,但 ORM 的全部目的是在域模型和持久性模型之间进行映射。由于 ORM 应该提供该映射,因此创建一个额外的类层次结构来促进映射是矫枉过正的,并且可能导致像您所描述的那样的问题。域模型类似于数据模型这一事实确实远不止巧合。相反,它们都代表同一领域的各个方面,因此应该具有高度的对应关系。 ORM 旨在解决对象模型和相应的关系模型之间的不匹配问题。在某些情况下映射会变得困难,但例如在 NHibernate 中,可以通过为组件映射实现自定义用户类型来解决这些问题。
关于c# - ORM/如何处理Domain对象和Persistent对象的对应关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17650073/