• 请不要在回答技术问题时复制粘贴 AI 生成的内容
gitrebase
V2EX  ›  程序员

大家喜欢用 ORM 还是直接写 SQL

  •  1
     
  •   gitrebase · Dec 29, 2023 · 28326 views
    This topic created in 1048 days ago, the information mentioned may be changed or developed.

    OP 主要用的 Java 和 Go ,但是感觉这俩主流语言的 ORM 框架( JPA 、GORM )都不如 C#、Python 的 ORM 好用( JOOQ 、ent 、XORM 感觉国内用的还是有点少),而 SQL / SQL builder ( JdbcTemplate 、sqlx )在动态条件查询时需要在代码里拼 SQL 字符串也有点🥚疼

    其实就是最近在玩 Spring 新出的 JdbcClient ( JdbcTemplate 的封装版),感觉在 Java 有多行字符串后,在 Java 代码里写 SQL 完全不是什么问题,而且也不用使用难用的 XML 去定义 resultMap (直接在 Java 里定义 record 或者 class 然后用构造器就可以了)

    public record User(Long id, String name, Integer sex) {
    }
    
    @GetMapping("/users/in")
    public Iterable<User> listInIds(@RequestParam List<Integer> ids) {
        return jdbcClient.sql("""
                SELECT *
                FROM `user`
                WHERE `id` IN (:ids)
                """)
                .param("ids", ids)
                .query(User.class)
                .list();
    }
    

    但是在碰到动态条件的 where 语句的时候,在 Java 代码里手搓 SQL 看着也很让人头大……这时候 MyBatis 提供的 dynamic SQL 就很好用了

    但真的不喜欢 XML……

    MyBatis-Plus 也了解过,但说不上来为什么,总是感觉不太喜欢这个库……

    155 replies  •  2024-01-04 01:52:02 +08:00
    1  2  
    ❮ ❯
    james122333
    james122333
    Dec 29, 2023 via Android
    101
    当然允许的情况是 sql 除了 xml 等外部设定当语言用的除外 除非用...
    用 sql 就像在下命令传参 直觉且少 orm 需要注意的细节
    orm 少个设定就找个半天了 除非这个 orm 够轻量没有一堆不必要的功能 即便如此 orm 短处就在那 动态 sql 语句就搞死人了 你也无法兼顾动态和直觉
    这篇感觉想钓鱼
    james122333
    james122333
    Dec 29, 2023 via Android
    102
    至于某些框架提供拼接 sql 语法的函数恰恰证明不是纯 orm
    题外话 laravel 还是快拿掉优雅这标签吧 不费什么资源力气才叫优雅 重的东西就不要叫优雅了
    netabare
    netabare
    Dec 29, 2023 via iPhone
    103
    ORM 能在出现例如 n+1 等常见问题的时候报错编译失败,直接写 sql 就没有这层检查了。
    zhuangzhuang1988
    zhuangzhuang1988
    Dec 29, 2023
    104
    肯定看情况啊,
    有不是非 A 即 B
    Immortal
    Immortal
    Dec 29, 2023
    105
    要不试试 sqlc
    msg7086
    msg7086
    Dec 29, 2023
    106
    ORM 也可以做多表联合查询,甚至可以根据具体情况做统一优化。
    比如有些 MySQL 的子查询性能有问题,ORM 可以改写成先查询出 ID 然后再用 IN(ID)另外做一次查询。
    再有比如说 MySQL 的大数 LIMIT 有性能问题,ORM 可以改写成先通过索引查出结果,然后再用 IN(ID)返回实际数据。

    你当然可以全手动优化,一个一个查询找出来再一个一个改。但我可以抽象成一个插件,插进 ORM 里整个系统就全改好了。

    上面这个 LIMIT 性能问题我之前自己的系统里刚遇到过。我自己做的一个 BT 站,几十万条记录,翻页翻得卡死。后来找到个 fast_page ,往 ORM 上加上,马上系统性能就上去了。我就加了这么一句:
    posts = posts.fast_page if params[:page].to_i > 50
    谁愿意写 SQL 谁去写,反正我懒。
    shijingshijing
    shijingshijing
    Dec 29, 2023
    107
    有了 ChatGPT ,再难的 SQL 也能写。
    james122333
    james122333
    Dec 29, 2023 via Android
    108
    @netabare

    这不是应该偷懒以及省资源就会主动想到解法的吗...
    CaspianJou
    CaspianJou
    Dec 29, 2023
    109
    一直习惯 JPA + Query DSL ,动态条件判断了用 Query DSL 拼就行
    james122333
    james122333
    Dec 29, 2023 via Android
    110
    @msg7086

    这与是否为 orm 无关吧 修改优化 sql 语句那是额外功能
    msg7086
    msg7086
    Dec 29, 2023
    111
    @james122333 抽象就是 ORM 的优势之一啊。抽象了以后就可以在更高维度进行优化了。
    zeroday
    zeroday
    Dec 29, 2023
    112
    常用 sql 都是自动生成的
    james122333
    james122333
    Dec 29, 2023 via Android
    113
    @msg7086

    那只是 parser 不同...
    bocchi1amos
    bocchi1amos
    Dec 29, 2023
    114
    感觉 orm 有点笨重,有时真不如我直接写 sql 。。
    nxforce
    nxforce
    Dec 29, 2023
    116
    有一说一,这个 JdbcClient 还真挺好用,特别是 IDEA 支持在 Java 代码里对 SQL 语句进行智能提示和高亮。

    数据库字段有变更,刷新一下连接,Java 代码里的 SQL 的 field 字段还支持变红警告。

    基本上可以抛弃 XML 写 SQL 了。
    rustz992
    rustz992
    Dec 29, 2023
    117
    不错我也是这个想法,别人的 sql 语句 有时候一看起来就感觉后面没法维护
    EscYezi
    EscYezi
    Dec 30, 2023 via Android
    118
    工作中 java 用 mybatis plus ,算是 orm 和 sql 混用,尽量用 mybatisplus 单表查询,不在 xml 里写 sql.但奈何总会有联表查询查询的业务。
    其实我更喜欢 jooq 那种,根据表结构生成 sqlbuilder ,然后用代码来写 type safe 的 sql
    sngxx
    sngxx
    Dec 30, 2023 via iPhone
    119
    写 sql 要把查出来的东西转成对象,一个一个字段搞能把人累死,还容易出 bug 。写工程重要的是实现,效率和稳定
    ipangpang
    ipangpang
    Dec 30, 2023
    120
    可以类比成 喜欢汇编还是喜欢 c 语言
    Int100
    Int100
    Dec 30, 2023
    121
    ORM 还是好用的
    msg7086
    msg7086
    Dec 30, 2023
    122
    @james122333 这里在讨论的本来不就是 ORM 的 Parser 部分吗?难道我们在讨论字段转对象这部分?
    说实话我没看懂你的意思。
    wonderfulcxm
    wonderfulcxm
    Dec 30, 2023 via iPhone
    123
    直接写 sql 挺好的啊,如果说一条 sql 手写起来麻烦,用 orm 拼出来只会更难。
    james122333
    james122333
    Dec 30, 2023 via Android
    124
    @msg7086

    orm 重点在物件映射 而不是整个 query string 都给 parse 了 这就是额外功能阿
    sun1991
    sun1991
    Dec 30, 2023
    125
    @flyingfz +1
    自从发现了 Dapper, 就一直用它到现在了, 并且由于它的影响, 做 JAVA 也喜欢用 JDBI.
    抛开公司开发规定不谈, 对于不会和不想学 SQL 的来说, ORM 是救星.
    ORM 应付解决简单问题 OK, 复杂情况只会再增加额外复杂度. 而且由于各个 ORM 实现不同, 切换比较麻烦. 相比之下 SQL 是标准化的, 各个实现相差不大.
    以前有过 MD 和 MP3 孰优孰劣的热烈讨论, 现在 MD 已经死的透透的了... 要是 ORM 真的如他宣传般好用, 几十年历史的 SQL 根本不会活到现在, 或者还被人拿出来谈论和 ORM 哪个好.
    cndenis
    cndenis
    Dec 30, 2023
    126
    这个问题还是要看情况,是做 CURD 还是做数据分析。数据分析动不动就几十上百行的 SQL ,转化为 ORM 的语法太痛苦。
    简单的 CURD 用 ORM 还是方便一些。
    我喜欢 Python 的 Peewee 这样的 SQL 拼装器式的 ORM 。
    我认为有些 ORM 太自以为是,所谓的 Code First 就是扯蛋的事。数据比代码更持久而且更有价值,做业务系统升级时,旧代码可以重构扔掉,旧数据一般都得保留兼容。做数据的基础上写代码才是正道,而不是把数据库当做代码的附属物。
    msg7086
    msg7086
    Dec 30, 2023
    127
    @james122333 但是你看看标题,问的是用 ORM 还是直接写 SQL ,所以谈的就是他的 parser 部分啊。
    msg7086
    msg7086
    Dec 30, 2023
    128
    @james122333 我又想了想。
    你说 ORM 在于对象映射。问题是对象映射的核心就是抽象,而优化起来简单本身就是抽象带来的好处。
    比如原本的 LIMIT 语句被 ORM 抽象成了分页组件,然后这个分页组件就可以被针对性附加优化。
    比如原本的 JOIN 语句被 ORM 抽象成了对象与对象之间的关系,然后这个关系也可以按照需求被针对性优化。有些数据库 JOIN 或者子查询更快,那就用 JOIN 或者子查询。有些则是分两次查询更快。有些场景下甚至需要联合查询多个数据库(比如合并查询 ElasticSearch 和 MySQL 等),这些都可以先抽象成对象,然后再在 ORM 内部针对性实现。
    ORM 本来就不是简单把返回值变成对象就完事了。
    jonsmith
    jonsmith
    Dec 30, 2023
    129
    之前用 gorm ,现在用的 Squirrel 。原生容易写错,一般用 orm 更好点。但是相比来说 laravel 、TP 的 orm 更好用
    superBearL
    superBearL
    Dec 30, 2023
    130
    Java 简单 sql MP ,复杂 SQLxml ,我喜欢结合起来用。MP 的 LambdaQuery 可以避免手写 SQL 打错字的烦恼
    09an6YfX8rNvIG92
    09an6YfX8rNvIG92
    Dec 30, 2023
    131
    jpa 感觉还可以,勉强用用,普通的连表、动态参数可以用 jpql ,复杂的老老实实用 sql
    zzhaolei
    zzhaolei
    Dec 30, 2023
    132
    gorm 本质也 sql 拼接,不算一个真正的 orm 。gorm 最好用的就是查询数据不需要一个个的 binding 了,通过反射直接写入 struct 、slice 、map 等。

    现在 go database/sql 也要加类似的机制,所以 gorm 的存在性又降低了一点。

    目前 go 的 orm 应该只有 ent 算是比较好的,假如改了表的字段,ent 能在编译时校验,gorm 是不行的
    changdy
    changdy
    Dec 30, 2023
    133
    @cndenis 正解 .一直都说 java 的 orm 太垃圾.所以才有 mybatis 这种工具的生存空间.
    可是每次我看我司动辄十多个查询条件,上百行的 sql 语句也都是心想 这东西真的放到 orm 中也未必轻松啊.

    更何况各种 orm 对方言支持比较弱..基本上达不到宣称的 能够不同数据库之间进行切换

    反过来思考一下 ..java 那么多用户选择 mybatis 也可能是因为 java 大部分时间都用来干了脏活累活..
    kenvix
    kenvix
    Dec 30, 2023
    134
    MyBatis 算个锤子的 ORM ,顶死就一个 SQL 模板引擎,Java 的 ORM 看看 JOOQ 吧
    kenvix
    kenvix
    Dec 30, 2023
    135
    私以为,没有自动扫表生成 POJO 、DAO 的库是不能称作 ORM 的
    gitrebase
    gitrebase
    OP
    Dec 30, 2023
    136
    @joyhub2140 #116 是的,用着很爽很流畅,但痛点就是复杂点的查询场景还得拼字符串……
    gitrebase
    gitrebase
    OP
    Dec 30, 2023
    137
    @zzhaolei 我感觉 GORM 只要别叫 ORM ,就没什么问题,还是很好用的;其实我也觉得把 GORM 当做一个很好用的 SQL Builder 就行,GORM 的很多封装后的东西都很好用,比如 Scopes 、CreateInBatch 、Upsert 之类的,还是能降低很多开发时间的
    Chieh
    Chieh
    Dec 30, 2023
    138
    EF 同时支持写 raw SQL ,因此用 ORM
    a1b2c3T
    a1b2c3T
    Dec 30, 2023 via iPhone
    139
    试试 mp 吧←_←,真的挺好使的
    tangqiu0205
    tangqiu0205
    Dec 30, 2023
    140
    @flmn 目前项目里用了几个月,只能说简单的查询还可以,select 想要加个聚合函数就不好搞了,另外 join 感觉也不好用。官方文档就根没写一样。现在新功能都用 gorm 写了。
    tangqiu0205
    tangqiu0205
    Dec 30, 2023
    141
    go 用的 gorm ,ent 太难用了,根据时间分表查询至今不知道怎么搞。
    11ssss
    11ssss
    Dec 30, 2023
    142
    个人角度讲我喜欢用 ORM 框架 JPA 没有之一,即优化了 hibernate 的复杂,又比 mybatis 优雅。而且基于对象的操作更适合在 Java 程序中使用。
    站在公司角度 我们目前在做的产品,要根据不同项目适配不同国产化数据库。选择硬编码写 SQL 这种方式也不合理。直接用 JPA 屏蔽了底层语法差异。
    pengtdyd
    pengtdyd
    Dec 30, 2023
    143
    个人见解:

    这个不能二选一吧,首先用 ORM 的前提是数据库物理模型要整理的非常清楚,业务逻辑理的特别顺才能事半功倍。否则如果是没有物理模型,表的关系非常乱,这种情况,我个人还是喜欢用 SQL ,不然特别复杂的 SQL ,都不知道怎么写,心智负担特别严重。
    chenzw2
    chenzw2
    Dec 30, 2023
    144
    通常都是混用,单表取值用 ORM ,复杂的用 SQL
    asuraa
    asuraa
    Dec 30, 2023
    145
    我喜欢 orm 而且喜欢 EntityFramewok Core 和 ActiveRecord
    james122333
    james122333
    Dec 30, 2023 via Android
    146
    @msg7086

    orm 运作不 parse query string
    orm 也并不需要优化你的请求才叫 orm
    我说的是这是额外的功能 并不是 orm 必需
    与抽象是否能够做到此事是两回事
    james122333
    james122333
    Dec 30, 2023 via Android
    147
    @msg7086

    况且很多 orm 实现的複杂语法也都是类同拼接 query string 直接拿来改来裸 sql 用也不无可能
    msg7086
    msg7086
    Dec 30, 2023
    148
    @james122333 不知道你到底想说什么。抽象才能带来额外的功能的可能性,支持额外的功能就是 ORM 的优势之一。如果你只是想翻来覆去抠字眼的话请不要再回复我了,纯粹是浪费你我的时间。
    james122333
    james122333
    Dec 30, 2023 via Android
    149
    @msg7086

    额外功能不是只有 orm 才有的优势 只是 orm 有做而已
    这并不是抠字眼 这种非 orm 常规的功能就不要拿来当 orm 必备的优势了 因为这么说纯 sql 封装的也可以实现这功能
    james122333
    james122333
    Dec 30, 2023 via Android
    150
    @msg7086

    实现额外功能与是否为对象无关 以这功能纯 sql 实现大可以用字典取代对象 也可以启动时分析一次即可
    f14g
    f14g
    Dec 31, 2023 via Android
    151
    外行只希望别被注入了就行🤔
    lucaslee
    lucaslee
    Dec 31, 2023
    152
    由于老项目就是 orm 的,所以就接着用了。一般场景 orm 的开发效率还是不错的,略复杂或者需要关注性能的可能需要手搓 SQL 了。但不推荐把 SQL 写代码里,比较难维护。
    OneMan
    OneMan
    Dec 31, 2023
    153
    jfinal 的 ActiveRecord 挺好用的
    troywinter
    troywinter
    Jan 2, 2024
    154
    复杂业务基本都是 sql 或者贴近 sql 的 orm mapping ,stackoverflow 也是自己搞了 dapper ,如果 ef 框架好用,他们也不用自己发明轮子了
    volvo007
    volvo007
    Jan 4, 2024 via iPhone
    155
    @chenqh 你的直觉没错。多对多的关系需要中间表,中间表.id + A.id + B.id 这样。这里中间表 id 最多会有 A 行数 x B 行数 个,等于中间表做了一个排列组合的中转站。如果是“多对多对多”,那么嵌套中间表就可以…… 我现在经常会和一个有 300 多张表的数据库打交道,天天看得眼花😂
    1  2  
    ❮ ❯
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   1259 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 89ms · UTC 23:47 · PVG 07:47 · LAX 15:47 · JFK 18:47
    ♥ Do have faith in what you're doing.