DDD 持久化的时候如何避免无效 DB 操作?
source link: https://www.v2ex.com/t/936712
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
DDD Repository 中的 save(T t) 方法实现 insert 和 update ,如果 t 中只有某个字段发生改变,那么只需更新这个字段即可,而不是更新全部字段,一般即使全部更新的话问题也不是很大,但是如果 t 中有列表或者设计到多张表,这个时候可能增加对 DB 的操作,请问如何解决这种问题?
从网上找到 snapshot 解决方法:
大家有没有什么实践或建议?
第 1 条附言 · 5 小时 56 分钟前
美团的分享:40:45分提了 Diff ,但是也不详细
huijiewei 6 小时 46 分钟前 这个是持久层的基础库应该考虑的事情,每个 ORM 都有动态更新查询的功能
|
TWorldIsNButThis 6 小时 28 分钟前 不清楚 hibernate 有没有相关配置
而且一般这种涉及多张表的也很少有高频次更新操作 |
vczyh 6 小时 0 分钟前 @huijiewei 现在就是需要实现 Repository ,所以遇到这个问题,我感觉 ORM 解决不了这个问题,请大佬赐教,比如这样一个场景:
- save 一个 List<R> 一般是 rList.foreach(r=>save(r)),如果有的 r 没有修改,以上操作明显会导致多余的对 DB 的访问。 |
rozbo 5 小时 55 分钟前 这个问题可以通过和 ai 沟通得到它的看法,我觉得很有道理,ai 认为,性能不能仅从某一个点考虑,要考虑整体,比如是否符合逻辑,是否有容错性和副作用等,如果一味的追求极致的性能,应该直接操作 sql 语句。。。选择了 orm 就要接受它的低效率
|
vczyh 5 小时 37 分钟前 @huijiewei 可能我没有表达清楚。我想表达的是 DDD 对持久化的影响,不是 ORM 批量的问题,DDD 聚合根中的一个 List 属性中的一个元素发生了变化,我实现的时候只想执行一条 update(item),而不是不管元素有没有修改,全部元素都执行一次 update ,即使一些 ORM 会对后者进行优化,我觉得不应该依赖这种,而且还得设置 allowMultiQueries=true 参数。
如果不用 DDD ,其实没有这种无效访问 DB 的问题。 |
huijiewei 5 小时 30 分钟前 @vczyh 如果聚合根里面的一个 List 属性中一个元素单独变化对聚合根没有影响的话,单独用领域对象去更新就好了。
https://insights.thoughtworks.cn/ddd-persist-aggregation/ DDD 这个说实话,没有领域专家介入,光靠程序员非常难。 |
rozbo 5 小时 25 分钟前 @vczyh 个人看法:DDD 就是个理想。。
DDD 还要求不让用导航属性呢,完全按照到 DDD ,可能确实提高了维护性,但是极大的降低了开发效率。 我觉得只要领悟它的思想就成,不必要 100%做到,做到“心中有剑”这一步就够了。 |
vczyh 5 小时 4 分钟前 via iPhone @huijiewei 博文中一个观点挺好的:让持久化入侵到领域服务,这样没有性能问题,整个领域内聚且逻辑可复用,只不过损失了领域不强依赖持久的优点。
|
Leviathann 5 小时 4 分钟前 确认了一下,hibernate 就是这样的,在事务结束时做 dirty check ,只有变更过的 entity 才会生成对应的 update statement
|
rozbo 4 小时 57 分钟前 @vczyh 我不知道你什么语言,dotnet 下有个框架叫 `abp`是我见过的对 ddd 规范理解最深刻的框架了。它实现了模块化,按照它的架构,项目中的每一个部分都是可以复用的,项目中的每个部分也都是可以替换的,比如可以把数据库从 pgsql 换成 mysql 甚至是 mongodb ,也可以无缝把基于依赖的实现换成基于微服务的实现(这一点我在别的框架完全没见过,可以说是 micro service ready ,原理是抽象了一个 application 层,application 层实现了这个模块的功能接口,同时自动生成了 application client 也实现了这个接口,如果有一天你想换成微服务,只要把 appcation interface 的实现换成 application client ,然后把 application 部署成一个独立的 endpoint 就可以无缝切换,代码都不用改)。
但是,你一眼都可以看到,为了实现这些美好的特性,它的开发效率是极低的,新建一个项目都有七八个细分项目,包括 domain 、domain shared 、application 、application contracts 、application client 、http api 、http host 等等,可以说非常的繁琐。但好在,如果你坚持严格按照它的 DDD 模式,你将有很多这些模块可以复用。。不过这一过程非常痛苦 |
crysislinux 4 小时 47 分钟前 via Android 我建议做好依赖反转就好了。domain 是最高级的,其他部分都依赖它。其他就不要想太多了。比如数据库我觉得没啥抽象的必要性,只要保证 repository 一级是抽象的就行了
|
vczyh 4 小时 41 分钟前 via iPhone @crysislinux 我现在想的是把 Repository 改一下,原来希望一个 save 方法把整个聚合根持久化,我现在可以增加多个方法,比如 saveOrderItem(OrderItem)
|
THESDZ 4 小时 39 分钟前 版本?或者显示的状态标记?
|
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK