为什么我不喜欢 JPA

2019-07-03 23:46:58 +08:00
 ebony0319

比如根据标签找用户:

表设计如下

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[(?, ?, ?)]
5192 次点击
所在节点    Java
19 条回复
skypyb
2019-07-04 08:30:56 +08:00
在不就在使用 jpa 的同时用下 JdbcTemplate 处理一些 jpa 不方便处理的 sql 得了 ...
ebony0319
2019-07-04 08:51:36 +08:00
@skypyb 谢谢老哥指明一条道路.
br00k
2019-07-04 09:51:48 +08:00
可以用 querydsl
adzchao
2019-07-04 10:03:42 +08:00
@ebony0319 资深 jpa 使用者 给你几个建议 默认你的表结构 是逻辑关联 也就是单表
1,简单单标操作可以使用 jpa
2,多表可以使用 mybatis 或者使用 NativeQueryRepository

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

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

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

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

Java 界的 Spring Data JPA 和.net 界 Entity Framework,都是上个时代面向对象思想到高峰时的典型产物,其实压根就不符合现在这个时代,Sql 现在越来越有生命力,想彻底屏蔽 sql 细节,别做梦了
wc951
2019-07-09 09:53:51 +08:00
@abcbuzhiming 你是没遇到通用中间件在不同项目里适配多种数据库的
abcbuzhiming
2019-07-09 11:00:50 +08:00
@wc951 中间件的特点是距离业务有一定距离,不和业务直接关联,真要用到必须原生 sql 直接上的,都是和业务强相关,此时中间件就失灵了,中间件不能屏蔽 sql 的复杂度
chihiro2014
2019-07-10 00:15:24 +08:00
JPA 基于类来进行查询,那种很方便。但是遇上复杂查询,还是 mybatis 更好
SkyLine7
2019-07-10 16:57:15 +08:00
第一 jpa 也可以写 native sql
第二 mybatis 不便于迁移
nnnToTnnn
2019-08-05 16:55:55 +08:00
@ebony0319 e.....mmmm jpa 提取数据,逻辑用 Stream,肯定没有原生 sql 写起来方便,舍弃了这些,迎来的是多数据库的支持,以及高效的缓存(是不是真的高效,没测试过,官网是这样说的)

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

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

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

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

© 2021 V2EX