ebony0319
V2EX  ›  Java

为什么我不喜欢 JPA

  •  
  •   ebony0319 · Jul 3, 2019 · 6047 views
    This topic created in 2516 days ago, the information mentioned may be changed or developed.
    • 第一我很蠢。
    • 第二 SQL 的世界是复杂的,而 JPA 是单纯的。

    比如根据标签找用户:

    表设计如下

    • 用户表
    • 用户标签表
    • 标签表

    sql 很好写(使用的是 postgresql):

    select  c.id,c.username
    from client_customer c
    inner join  client_custom_and_label cl on c.id= cl.custom_id
    inner join client_label l on cl.label_id=l.id
    group by c.id
    having array_agg(l.id) @> array[65,67]
    

    但是 jpa 里面:

    @Query(nativeQuery = true,value = "select  c.id,c.username\n" +
                "from client_customer c\n" +
                "inner join  client_custom_and_label cl on c.id= cl.custom_id\n" +
                "inner join client_label l on cl.label_id=l.id\n" +
                "group by c.id\n" +
                "having array_agg(l.id) @> array[:list]")
        List<Map<String,Object[]>> findByLabelId(@Param("list") List<Integer> list);
    

    当 list 的 size 等于 1 的时候非常好写,但是大于 1 的时候自动加了括号 array[(?, ?, ?)]:

    Hibernate: select  c.id,c.username
    from client_customer c
    inner join  client_custom_and_label cl on c.id= cl.custom_id
    inner join client_label l on cl.label_id=l.id
    group by c.id
    having array_agg(l.id) @> array[(?, ?, ?)]
    
    19 replies    2019-08-05 16:55:55 +08:00
    skypyb
        1
    skypyb  
       Jul 4, 2019 via Android   ❤️ 1
    在不就在使用 jpa 的同时用下 JdbcTemplate 处理一些 jpa 不方便处理的 sql 得了 ...
    ebony0319
        2
    ebony0319  
    OP
       Jul 4, 2019
    @skypyb 谢谢老哥指明一条道路.
    br00k
        3
    br00k  
       Jul 4, 2019   ❤️ 1
    可以用 querydsl
    adzchao
        4
    adzchao  
       Jul 4, 2019   ❤️ 1
    @ebony0319 资深 jpa 使用者 给你几个建议 默认你的表结构 是逻辑关联 也就是单表
    1,简单单标操作可以使用 jpa
    2,多表可以使用 mybatis 或者使用 NativeQueryRepository

    如果你是关系表 那就直接 jpa 干吧 根本不需要写一条 sql
    efaun
        5
    efaun  
       Jul 4, 2019   ❤️ 1
    jpa 本来就不是为多表而生的
    ShuangChenyue
        6
    ShuangChenyue  
       Jul 4, 2019   ❤️ 1
    如果这种多表关联的 sql 多了或者用到了很多 sql 函数
    用 mybatis-plus 吧
    就我的感受而言 mybatis-plus 很爽 比 jpa 更适用
    ebony0319
        7
    ebony0319  
    OP
       Jul 4, 2019
    @ShuangChenyue 我也是这样觉得的,但是 CTO 技术选型的时候就只能用 JPA,其实很无奈.
    anakinsky
        8
    anakinsky  
       Jul 4, 2019   ❤️ 1
    nativeQuery 也不能映射自定义对象,很蛋疼
    Takamine
        9
    Takamine  
       Jul 4, 2019   ❤️ 1
    菜鸡表示自己撸的时候还是用的 mybatis,简单查询直接走注解,复杂的走 XML,工作就是全走 XML。
    zjsxwc
        10
    zjsxwc  
       Jul 4, 2019
    搞不懂为什么要多表级联,
    笛卡尔积下来性能会很差,
    楼主的例子还不如分 2 次单表查询,
    尽量避免复杂 sql 的好处了维护方便。
    mmdsun
        11
    mmdsun  
       Jul 5, 2019 via Android
    jpa 可以配置一对多啊。用 hql 写起来也很方便。而且方便迁移数据库
    1340976576
        12
    1340976576  
       Jul 5, 2019
    这种复杂查询建议使用 JPA+QueryDSL
    abcbuzhiming
        13
    abcbuzhiming  
       Jul 8, 2019   ❤️ 1
    @mmdsun 迁移数据库是伪命题,这已经不是数据库群雄争霸的时代了,你能遇上一次项目更换数据库,那简直可以去买彩票
    abcbuzhiming
        14
    abcbuzhiming  
       Jul 8, 2019   ❤️ 2
    jpa 最大的问题,不光是楼主说的“ SQL 是复杂的”。要我来说的话,JPA 上下不靠:

    1.该简单的时候简单不起来,你们去看看别的动态语言,尤其是 ActiveRecord 和链式调用的创始者 Ruby on Rail,是怎么处理单表查询的,是怎么用链式调用拼查询条件的。JPA 压根就做不到这么简单

    1.该复杂的时候恶心的要死,需要写原生 SQL 的场合 JPA 那个费劲,那个丑陋啊。。。

    根本原因在于,关系模型和对象模型是有区别的,老是有人生搬硬套想用对象模型去描述关系模型,也不想想这招要能成功的话,关系数据库不早就被对象数据库干掉了?

    Java 界的 Spring Data JPA 和.net 界 Entity Framework,都是上个时代面向对象思想到高峰时的典型产物,其实压根就不符合现在这个时代,Sql 现在越来越有生命力,想彻底屏蔽 sql 细节,别做梦了
    wc951
        15
    wc951  
       Jul 9, 2019 via Android
    @abcbuzhiming 你是没遇到通用中间件在不同项目里适配多种数据库的
    abcbuzhiming
        16
    abcbuzhiming  
       Jul 9, 2019
    @wc951 中间件的特点是距离业务有一定距离,不和业务直接关联,真要用到必须原生 sql 直接上的,都是和业务强相关,此时中间件就失灵了,中间件不能屏蔽 sql 的复杂度
    chihiro2014
        17
    chihiro2014  
       Jul 10, 2019
    JPA 基于类来进行查询,那种很方便。但是遇上复杂查询,还是 mybatis 更好
    SkyLine7
        18
    SkyLine7  
       Jul 10, 2019
    第一 jpa 也可以写 native sql
    第二 mybatis 不便于迁移
    nnnToTnnn
        19
    nnnToTnnn  
       Aug 5, 2019
    @ebony0319 e.....mmmm jpa 提取数据,逻辑用 Stream,肯定没有原生 sql 写起来方便,舍弃了这些,迎来的是多数据库的支持,以及高效的缓存(是不是真的高效,没测试过,官网是这样说的)
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2885 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 466ea39e · 59ms · UTC 09:43 · PVG 17:43 · LAX 02:43 · JFK 05:43
    ♥ Do have faith in what you're doing.