Domain driven design 存储库模式会杀死ORM吗?
除了将关系数据转换为对象模型外,ORM还有其他作用,如:Domain driven design 存储库模式会杀死ORM吗?,domain-driven-design,orm,repository-pattern,Domain Driven Design,Orm,Repository Pattern,除了将关系数据转换为对象模型外,ORM还有其他作用,如: 延迟加载 自动变化检测 交易 但是,使用存储库模式将ORM的DTO转换为域模型,会发生以下情况: 无法利用延迟加载的好处,因为我需要填充整个域模型,存储库不知道data Domain需要什么 ORM无法检测到更改,因为域模型不是来自ORM世界 由于缺乏关于ORM 问题1:我是否遗漏了一些差距,在这些差距中,我可以在场景中充分利用延迟加载、事务和自动更改检测的好处?或者这些好处更多地用于另一种方法(如活动记录)而不是DDD 问题2:为什么在
一些平台采用代码优先的方法,这是一种改善这些问题的方法,但是这种功能在许多环境中并不总是存在,或者根本无法使用(例如在遗留数据库中),因此,这不是一个解决方案。我一直在想,如果从ORM中删除更改跟踪,那么开发人员会发现它们的价值要小得多 延迟加载永远不会发生。骨料始终以整体形式装载。如果您发现自己需要延迟加载,那么很可能您正在查询您的域模型。这是你不应该做的事。为此,请使用简单的查询层/读取模型 事务确实是DB关注的问题,不会直接影响DDD。聚合确实表示一致性边界,因此数据库事务是自然匹配的,但这就是它的结束 您仍然可以将ORM工具与DDD一起使用,但您可能会获得更少的里程数。我一点也不喜欢ORMs,如果我在这件事上有任何选择,我就是不使用它们。映射实际上并不是那么多的工作,如果在自定义映射器类中完成映射,它将以语言速度运行,而不是以某种代理机制运行 我见过一些实例,例如,使用ORM直接持久化域对象。然而,如果我必须使用(比如)属性标记任何东西,或者甚至更改我的设计,其中我必须将某些方法实现为
virtual
,或者甚至以特定的方式构造某些类,那么我不再认为我的域是永久无知的,这是我真正想要的(PI)
为什么在DDD书籍中提到ORM?只是为了让关系
域模型和延迟加载、事务和更改检测
全神贯注
您可以在中的蓝皮书中找到货物系统的DDD实现。它使用Hibernate作为ORM
应用程序服务中存在数据库事务,例如,请参见se.citerus.dddsample.application.impl.BookingServiceImpl
@Transactional
是来自Spring的注释,它导致方法被包装到数据库事务中
更改检测不会被丢弃。原始DDD模式中的存储库没有更新方法,因此使用更改检测(ORM)来更新域对象。例如:
@覆盖
@交易的
公共无效分配货物路线(最终行程,最终跟踪ID跟踪ID){
最终货物=cargoRepository.find(trackingId);
如果(货物==null){
抛出新的IllegalArgumentException(“无法将行程分配给不存在的货物”+trackingId);
}
货物分配路线(行程);
货物储存库。仓库(货物);
logger.info(“指定货物”+跟踪ID+“到新路线”);
}
实际上,在示例中,存储库有更新方法,因为cargoRepository.store()
是更新方法:
公共仓库(货物){
getSession().saveOrUpdate(货物);
//当父对象是组件时,“删除孤立对象”似乎无法正常工作
getSession().createSQLQuery(“从cargo_id=null的分支删除”).executeUpdate();
}
令人惊讶的是,您可以在官方示例中找到惰性集合的用法,例如在src/main/resources/se/citerus/dddsample/infrastructure/persistence/hibernate/Cargo.hbm.xml中:
...
因此,答案是您仍然可以享受ORM的所有好处
然而,使用存储库模式将ORM的DTO转换为域
模型,即:
谢谢你,埃本!现在我有另一个问题,为什么在DDD书籍中提到ORM?仅针对关系域模型?而延迟加载、事务和更改检测只是剩下的?在使用