DAO 层和 ORM,能区分,但又不完全能区分,我裂开了

2021-05-06 14:22:54 +08:00
 waibunleung

desc:是这样的,小弟从 php 转到 go 一个月时间不够,项目的目录结构需要自己搭建。于是就找网上的项目组织目录参考,发现有一部分目录结构里有 dao 层的分层概念。这个在 java 里面比较常见,在 php 中用得比较多的是 orm,不知道 go 中是不是也适合这样搞。

于是引起了我一顿梳理 dao 和 orm 之间的关系。但仍有如下疑问:

  1. 究竟项目使用了 orm 之后,还需不需要再分一层 DAO 层出来?如果要分,此时的 DAO 层里面写的是什么逻辑?求 demo 举例
  2. ORM 不是正好替代了 DAO 的角色吗?还是说 DAO 可以通过 ORM 来实现?此时 DAO 层的实现是怎么样的?在 ORM 外面包一层,意义在哪里?
  3. 在项目代码分层上(语言无关),DAO 和 ORM 分别是什么层面上的东西?

真的纠结了三四天了,每天看完都有不同的结论,求大佬们指点一下你们在项目中是怎么划分的~

7549 次点击
所在节点    程序员
78 条回复
catcn
2021-05-06 23:22:22 +08:00
orm 的定义基本就是 Model 里边对数据库的一个映射啦。dao 就是一个事务里边的的组合体就好啦。上边再来一个 service,基本就成型了。web 的话,还有一个 handler 的层。
charlie21
2021-05-06 23:46:57 +08:00
@waibunleung #30
https://xblog.lufficc.com/blog/the-core-conception-of-laravel
https://segmentfault.com/a/1190000004875930

看 UserRepository 是如何注入到 UserController ( 放 __construct 当参数,框架的 IoC 机制会将它自动注入) 里的。
这里 UserRepository 就是一个服务,UserController 就是消费这个服务的消费者。生产者消费者关系(谁是 service,谁在消费 service )搞清楚就 OK 了:有个生产者消费者的概念就 OK 了

关于 “分层目的是方便出错排错 / layered architecture 好在哪里” 的文章
https://learnku.com/articles/48397
https://learnku.com/articles/5813/overview-of-hierarchical-model-for-web-pyramid-development-framework
https://docs.microsoft.com/en-us/dotnet/architecture/modern-web-apps-azure/common-web-application-architectures
bthulu
2021-05-07 08:34:24 +08:00
@waibunleung 看语言表达能力的, 像 java 这种假泛型, 一般还是得针对每个表建立一个 dao 类. 真泛型像 c#这种, 就不用这么麻烦
vicalloy
2021-05-07 09:23:19 +08:00
主要还是看 ORM 的表现能力,如果 ORM 的表现能力不足,使用 DAO 封一下可用让代码更为清晰。
如果 ORM 表现能力足够强,加 DAO 更多的是 Java 设计模式看的太多,有些生搬硬套。

注:
Python 和 Ruby 相关的应用就没看到有谁去加一层 DAO 。
pkoukk
2021-05-07 09:46:19 +08:00
orm 比较纯粹,一个 sturct 一般就是对应一张表
DAO 比较复杂,提供出来的函数中可能包含了多个 orm
纠结名词意义不大,自己写写就知道了
waibunleung
2021-05-07 10:00:16 +08:00
@pkoukk 在写,就是觉得 ORM 用着挺方便的,加一层 DAO 是有好处,但是看着好像不太大的样子
konakona
2021-05-07 10:12:24 +08:00
DAO 里的代码看一看你就能发现它跟 ORM 的 Repository 部分的作用是一样的,封装了对模型的操作访问方法。

ORM 是对数据的映射关系,gorm 就是这个作用,gorm 一开始会写类型声明和映射关系,类似 Laravel eloquent 一开始声明和 hasmany()那些。

都可以对号入座的。
waibunleung
2021-05-07 10:23:58 +08:00
@konakona 所以是有了 orm 之后其实不需要 dao 层了?
waibunleung
2021-05-07 10:38:40 +08:00
@catcn 组合体怎么理解?
waibunleung
2021-05-07 11:23:00 +08:00
@konakona 问题是不知道 dao 里面写的什么代码?!
konakona
2021-05-07 13:28:47 +08:00
@waibunleung

我有个项目可以给你简单参考下我当初是怎么理解和怎么做的:
dto 看这里 https://github.com/54853315/weapp-MrsZhangPrivateKitchen-Backend/tree/master/pkg/api
引用这些 dto 的 orm 看这里 https://github.com/54853315/weapp-MrsZhangPrivateKitchen-Backend/tree/master/models
konakona
2021-05-07 13:30:25 +08:00
补充下上条:
由于我大部分 dto 比较“偷工减料”,dto 你看这一份: https://github.com/54853315/weapp-MrsZhangPrivateKitchen-Backend/blob/master/pkg/api/dto/user.go

然后再看下 user 控制器和 user model 是怎么与它交互的就差不多够了。
konakona
2021-05-07 13:31:26 +08:00
waibunleung
2021-05-07 15:12:11 +08:00
@konakona 看了一下,你的 model 层除了定义了实体类型以外,还在此层基于 orm 封装了一些数据存取函数,这样看你的 model 像是 DAO + model,那你的 DTO 的职责只是定义了数据传输的对象结构,不知道我这样理解有没有错
dayudayupao
2021-05-07 15:59:29 +08:00
dao 可以跟 orm 共存啊,dao 作为在 mvc 设计模式下的数据访问层,这个数据到底是谁提供的,mysql?redis?mongo?hbase?
其实不关心啊,orm 作为一种特定数据存储组件的一个封装而已,对业务来说其实可以是黑盒;其实日常情况下,dao 可以封装缓存层,比如将 mysql 的数据拉到 redis 缓存,业务逻辑层无需关注是怎么缓存的,交给 dao 做就好了
waibunleung
2021-05-07 16:06:57 +08:00
@dayudayupao 所以 dao 层可以用 orm 去搞对吧?写的函数就类似于我 7 楼写的那样?
passerbytiny
2021-05-07 16:08:43 +08:00
dao 是一种业务逻辑层,orm 是一种基础设施,它俩是两码事。这 ORM 还只是仅参与 DAO 层的基础设施,你要是碰到贯穿所有层次的基础设施,比如 Java 的 Spring,要是还想分层,估计直接死翘翘。
dayudayupao
2021-05-07 16:27:01 +08:00
@waibunleung 写法都是灵活的,就像 @kop1989 所说的那样,dao 方法定义是业务驱动,只关心我要什么,而在 dao 里,需要写 sql 的时候就写,不需要写比如 orm 封装了就不用写,看 orm 来定,也就是说 dao 里面跟 orm 是强耦合的,你需要对特定的 orm 做出适配,这些都是 dao 做的事. 综合来看如果你底层数据库组件有可能变化,或者不确定会不会变化,就可以 dao,orm 都共存.
在我看来,不管什么情况,共存看起来层次会分明点,即使是透传.
konakona
2021-05-07 17:10:25 +08:00
@waibunleung 兄弟,你的理解不太对。

我在 Model 里做的事情就是 eloquent 里会做的事情。
我在 DTO 里做的事情就是 Repository 里会做的事情。
waibunleung
2021-05-07 20:03:21 +08:00
@konakona 这又涉及到了 eloquent 和 Repository 的 区别了...
你在 model 里面定义了一些数据操作的函数,在 DTO 里面只有数据传输对象,我是这么理解的...

eloquent = 数据表映射 + 数据操作
如果你用了 Repository pattern,那数据操作应该放在 Repository,eloquent 仅仅是一些数据表映射,属性定义就好了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/775162

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX