用像 TypeORM 中的 api 代替 sql 语句的意义是什么? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
fanyingmao
V2EX    问与答

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

  •  
  •   fanyingmao 2022-05-30 21:06:30 +08:00 2265 次点击
    这是一个创建于 1230 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

    14 条回复    2023-02-16 16:35:51 +08:00
    IvanLi127
        1
    IvanLi127  
       2022-05-30 21:09:38 +08:00 via Android
    换了数据库语句不一样了也不是什么好事。ORM 和 SQL 有啥区别应该网上有资料可查,你可以看看。我觉得问题不能局限在写查询上。
    helone
        2
    helone  
       2022-05-30 21:11:28 +08:00
    就我个人而言,复用代码、语义清晰
    XCFOX
        3
    XCFOX  
       2022-05-30 23:08:12 +08:00   2
    当然首要是为了类型安全 (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 。
    img src="https://cdn.v2ex.com/static/img/avatar_normal.png" class="avatar" border="0" align="default" alt="F281M6Dh8DXpD1g2" data-uid="27647" />
        4
    F281M6Dh8DXpD1g2  
       2022-05-30 23:39:40 +08:00 via iPhone   1
    说 orm 可以屏蔽掉数据库之间差异的是认真的么
    jhdxr
        5
    jhdxr  
       2022-05-31 00:35:37 +08:00
    @liprais 我觉得这么说没啥问题啊。( web 场景下)大部分 CRUD 用 ORM 的确可以抹平不同 DB 之间的差异。每个 DB 独有的一些高级特性基本上也没法用 ORM 。
    xiangyuecn
        6
    xiangyuecn  
       2022-05-31 07:51:53 +08:00
    确实。简单的 sql ,不改也能不同数据库执行。复杂的,只能呵呵
    waising
        7
    waising  
       2022-05-31 09:08:18 +08:00
    除了开源的框架项目,现实业务项目有很多要切换同类数据库的场景吗?
    terranboy
        8
    terranboy  
       2022-05-31 09:18:19 +08:00
    可以写 SQL 大多数情况 用 ORM 更方便 更安全
    wdwwtzy
        9
    wdwwtzy  
       2022-05-31 09:23:41 +08:00 via iPhone
    你的这个问题其实正是使用 ORM 的意义之一
    fanyingmao
        10
    fanyingmao  
    OP
       2022-05-31 09:32:14 +08:00
    总结下,就是简单的语句可以用 orm 方便,复杂的还是自己写 sql 吧,我写 sql 一点点用子语句调,比用 api 效率高多了。
    qrobot
        11
    qrobot  
       2022-05-31 11:26:13 +0800
    @XCFOX #3L

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

    我认为 sql 和 orm 最大的区别

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

    至于关系性数据库的设计用 orm 作为查询, 简直就是反人类。当然 orm 提倡数据在中间层中进行查询使用,而不是在 sql 中直接提取完成
    XCFOX
        12
    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
        13
    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
        14
    yekai584341028  
       2023-02-16 16:35:51 +08:00
    typeORM 可以自动同步数据库和实体类的结构,数据表升级、回退只需要改实体类。当然自动修改列类型、删除列有点危险。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2199 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 35ms UTC 00:47 PVG 08:47 LAX 17:47 JFK 20:47
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86