V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
satoru
V2EX  ›  程序员

你最喜欢的 ORM 有哪些最讨厌的地方?

  •  
  •   satoru · 2022-07-16 07:29:19 +08:00 · 3028 次点击
    这是一个创建于 850 天前的主题,其中的信息可能已经有所发展或是发生改变。

    https://v2ex.com/t/866413 里看到大家提到很多没用过的 ORM 。 我用过的 ORM 每一个都有自己的局限,只说“XXX 最好用”可能不是很有意义,不如来聊聊自己最喜欢的 ORM 都有哪些最讨厌的地方?例如有什么没法方便地在框架内解决只好在外部 hack 的问题。

    20 条回复    2022-07-17 22:54:02 +08:00
    nutting
        1
    nutting  
       2022-07-16 08:30:08 +08:00 via iPhone   ❤️ 1
    真正的 ORM 我觉得关键是和关系型数据库天生不和谐
    satoru
        2
    satoru  
    OP
       2022-07-16 08:46:49 +08:00
    @nutting 想起了很久以前读的一篇[文章]( https://blog.codinghorror.com/object-relational-mapping-is-the-vietnam-of-computer-science/),Stackoverflow 的 cofounder 写的,说 ORM 是 CS 领域的越南战争。
    hervey0424
        3
    hervey0424  
       2022-07-16 10:29:16 +08:00
    efcore 更新数据的时候必须先查询, 并发高的时候如果没有锁就会出现问题
    DTCPSS
        4
    DTCPSS  
       2022-07-16 10:33:39 +08:00
    EF Core 不能在不把数据读到本机的前提下批量更新和删除数据库中的行,比如要把一个字段全部加 1
    satoru
        5
    satoru  
    OP
       2022-07-16 10:44:36 +08:00
    @hervey0424 @DTCPSS 听起来是个很常见的操作,你们一般怎么绕过这个限制去高效实现这种查询?
    msg7086
        6
    msg7086  
       2022-07-16 11:38:52 +08:00
    Rails 有 counters 相关的方法。

    # For the Posts with id of 10 and 15, increment the comment_count by 1
    Post.update_counters [10, 15], comment_count: 1
    # Executes the following SQL:
    # UPDATE posts SET comment_count = COALESCE(comment_count, 0) + 1 WHERE id IN (10, 15)

    抄吧(
    DTCPSS
        7
    DTCPSS  
       2022-07-16 12:38:54 +08:00   ❤️ 1
    @satoru 装第三方扩展包,或者手写 SQL
    zed1018
        8
    zed1018  
       2022-07-16 13:19:49 +08:00
    JPA/Hibernates 的持久态在有 transaction 的业务里,没有修改过的对象也会 save 一次,通常来讲问题不大,但是如果里面有 json 字段,然后 JSON 字段的实体类又跟数据库不一致的话会导致数据库的 json 字段值被覆盖一个错误的。
    NPC666
        9
    NPC666  
       2022-07-16 13:24:38 +08:00 via Android
    没有 没有 没有
    dcsuibian
        10
    dcsuibian  
       2022-07-16 13:26:27 +08:00
    同意#1 ,两种模型其实并不是非常和谐的。
    我现在都是用 DO 、PO 对应数据库单表,然后再转换成比较面向对象的结构。
    StarkWhite
        11
    StarkWhite  
       2022-07-16 14:25:41 +08:00
    prisma 等 fb graphql 生态 orm 库,复杂的 sql 还得手写,例如各种 join ,希望生态更完善些
    v2ex.com/t/589138
    makelove
        12
    makelove  
       2022-07-16 14:39:19 +08:00
    其实按 active record 模式自制一个薄的 orm 层用起来很好使,我自己的 app 都是这么干的
    satoru
        13
    satoru  
    OP
       2022-07-16 14:40:18 +08:00
    @zed1018 这个有点恐怖,不过我还不太理解为什么只有 JSON 字段会有这个问题
    zed1018
        14
    zed1018  
       2022-07-16 14:51:22 +08:00   ❤️ 1
    @satoru 因为其他字段没有,update 的 set 就里不会出现,那么数据库的值就不会改变。但是 JSON 字段,会被反序列化成当前实体类,然后 save 的时候按照当前实体类的实例序列化再 set 到数据库里,所以就不一样了。我会知道这个,是因为我们有个表的 json 是一个类似局部配置的字段,当时没有更新一个只读业务系统里的这个字段的实体类,所以发现这个字段改过一次以后要不了多久就会消失。
    wanguorui123
        15
    wanguorui123  
       2022-07-16 15:10:18 +08:00
    Hibernates 算是比较全面的 ORM 框架,缓存 /延迟加载 /局部字段更新都支持的比较完美,而且基础方法都可以用 HQL 写,迁移不同的数据库很方便,一般不涉及到非常复杂的报表查询不会用原生的 SQL ,大部分时候通过面向对象数据库操作和 XML 配置实现,虽然面向对象的方式操作数据库会损失一定的性能,但是后期维护非常方便。
    wdwwtzy
        16
    wdwwtzy  
       2022-07-16 15:22:29 +08:00
    EF Core 应该是我见过最好、或者说最像 ORM 的 ORM 了。
    不过他的理念确实有些地方有些死板,就像楼上说的,想更新一定要先查询出来
    windyboy
        17
    windyboy  
       2022-07-16 18:12:07 +08:00
    edgedb
    stevefan1999
        18
    stevefan1999  
       2022-07-17 02:40:18 +08:00 via Android
    TypeORM 不支持 Merge Into

    另外就是 EF 的 Migration 很麻煩
    bsg1992
        19
    bsg1992  
       2022-07-17 21:52:56 +08:00
    @wdwwtzy
    "不过他的理念确实有些地方有些死板,就像楼上说的,想更新一定要先查询出来"
    这个是其实并不是 ORM 的问题,ORM 提供的功能就是将数据映射成 Object ,然后对这个 Object 进行操作。
    你既然都不需要 Object 那 ORM 的作用也就等于失效了。
    类似这种绕过 Object 的需求 直接使用 Command 就好了。
    StarkWhite
        20
    StarkWhite  
       2022-07-17 22:54:02 +08:00
    hibernate 多表联查执行 1+n 条语句,性能太差
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1066 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 19:35 · PVG 03:35 · LAX 11:35 · JFK 14:35
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.