用像 TypeORM 中的 api 代替 sql 语句的意义是什么?

2022-05-30 21:06:30 +08:00
 fanyingmao

要写个关联查询,研究 api 研究了半天,不能忍,我还是直接写个 sql 吧,换个 orm 框架 api 接口又不一样了,只有 sql 语句是不变的。

1726 次点击
所在节点    问与答
14 条回复
IvanLi127
2022-05-30 21:09:38 +08:00
换了数据库语句不一样了也不是什么好事。ORM 和 SQL 有啥区别应该网上有资料可查,你可以看看。我觉得问题不能局限在写查询上。
helone
2022-05-30 21:11:28 +08:00
就我个人而言,复用代码、语义清晰
XCFOX
2022-05-30 23:08:12 +08:00
当然首要是为了类型安全 (Type Safety),然后才是防止 SQL 注入、逻辑复用。

ORM 的一个重要功能就是将 数据库 里的表结构 转化为 对应语言的 Entity (Persistant Object)。
如果不使用 ORM 的话,用 SQL 从库里捞出来的数据得手动加类型断言,这个类型断言得随着每次 SQL 改动或者 表结构而变动,非常不容易维护。

ORM 的另一个功能也是 api 代替 sql 语句的重要意义是:API 抹平了不同数据库之间的差异。比如 mikro-orm( https://mikro-orm.io/),同一套 API 支持了 MongoDB, MySQL, MariaDB, PostgreSQL and SQLite 。用楼主的话说就是换个 数据库 SQL 语法 又不一样了 ,只有 ORM 的 API 是不变的。

我个人不喜欢 GoLang 的一个重要原因就是 Go 的多数 Orm 因为语言的缺陷无法实现完善的类型安全(对比 TypeScript 的 TypeORM 、C# 的 Entity Framework Core )。同样我也不喜欢 Java 的 mybatis 。
liprais
2022-05-30 23:39:40 +08:00
说 orm 可以屏蔽掉数据库之间差异的是认真的么
jhdxr
2022-05-31 00:35:37 +08:00
@liprais 我觉得这么说没啥问题啊。( web 场景下)大部分 CRUD 用 ORM 的确可以抹平不同 DB 之间的差异。每个 DB 独有的一些高级特性基本上也没法用 ORM 。
xiangyuecn
2022-05-31 07:51:53 +08:00
确实。简单的 sql ,不改也能不同数据库执行。复杂的,只能呵呵
waising
2022-05-31 09:08:18 +08:00
除了开源的框架项目,现实业务项目有很多要切换同类数据库的场景吗?
terranboy
2022-05-31 09:18:19 +08:00
可以写 SQL 大多数情况 用 ORM 更方便 更安全
wdwwtzy
2022-05-31 09:23:41 +08:00
你的这个问题其实正是使用 ORM 的意义之一
fanyingmao
2022-05-31 09:32:14 +08:00
总结下,就是简单的语句可以用 orm 方便,复杂的还是自己写 sql 吧,我写 sql 一点点用子语句调,比用 api 效率高多了。
qrobot
2022-05-31 11:26:13 +08:00
@XCFOX #3L

很有意思的一个点,ORM 支持的 sql 也支持,sql 不支持的查询 orm 同样不支持。 所以 orm 到底好在什么地方?

我认为 sql 和 orm 最大的区别

- 缓存 (查询 /修改)
- 可通过 entity 自动生成 insert into 或者 update 等语句,比自己手写会方便很多

至于关系性数据库的设计用 orm 作为查询, 简直就是反人类。当然 orm 提倡数据在中间层中进行查询使用,而不是在 sql 中直接提取完成
XCFOX
2022-05-31 14:21:41 +08:00
ORM 的类型安全还体现在查询条件的处理上。

比如对于一个 有 Age(Int) 字段的 User 表:
不使用 ORM:select * from User where age > 233 、select * from User where age > haha
XCFOX
2022-05-31 14:27:41 +08:00
ORM 的类型安全还体现在查询条件的处理上。

比如对于一个 有 Age(Int) 字段的 User 表:
不使用 ORM:select * from User where age = 233 、select * from User where age = haha ,
这两句在代码里实际上是字符串,都不会报错

使用 TypeORM:const user = await userRepository.findOneBy({ age: 233})、const user = await userRepository.findOneBy({ age: 'haha' }),TypeScript 能告诉你第二句的参数是非法的

使用 gorm: db.Where("age = ?", "22").Find(&users)、db.Where("age = ?", "haha").Find(&users),go 语言并不能判断第二句的输入有问题。
yekai584341028
2023-02-16 16:35:51 +08:00
typeORM 可以自动同步数据库和实体类的结构,数据表升级、回退只需要改实体类。当然自动修改列类型、删除列有点危险。

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

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

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

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

© 2021 V2EX