JPA 为何如此难用,是我姿势不对吗

2021-02-10 11:44:17 +08:00
 XiLemon

RT,明天就过年了,我还在写 JPA 的东西,我快吐了。。。

声明:因为是第一次用,不熟悉,另外,个人认为是本人不理解 JPA 的设计思想,所以用起来很不顺手。

槽点:

  1. 多个条件,组合查询,当有些条件没有传参的时候怎么处理
    • 代码层面处理:用 specification 来处理,写起来好啰嗦,过于麻烦
    • @Query 注解,写原生 SQL 也挺恶心的
  2. 指定 update 条件
    应该不支持吧,只能用 @Query 注解写原生的 SQL,一旦字段比较多,而且部分可能为空的情况,写起来也是噩梦
  3. 多表关联查询
    JPA 不推荐多表关联查询?用起来也不够方便。

我是在用 MyBatis 的思路来用 JPA,完全不对路子。MyBaits 很灵活,在使用 JPA 的时候,感觉到处都是限制和不便。比如要用乐观锁,JPA 虽然有 @Version 注解处理,但是只能在 save 的时候才能用到。

用 MyBatis 感觉是在呼吸自由的新鲜空气,用 JPA 感觉是在地下室。。。

那么用 JPA 的朋友,是真的不需要灵活性,从业务设计上就完全解决了这些情况么。

本帖带有强烈的个人主观印象,用词如有冒犯到 JPA 用户,请强势打脸,教我做人!

打工人,打工魂,打工人是人下人 o(╥﹏╥)o

提前祝大家新年快乐!

8489 次点击
所在节点    Java
61 条回复
winglight2016
2021-02-11 08:38:27 +08:00
@XiLemon #25 OOP 现在似乎已经不流行了,我也不知道还有什么比较新的资料,可能《 head first oop 》可以看看吧。

OOP 是个思维模式,也许可以从需求分析到实体设计这个流程试一下。
XiLemon
2021-02-11 11:08:09 +08:00
@mmdsun 关联没有超过 3 张表
@passerbytiny 我也不想用诶
@winglight2016 >…<
hantsy
2021-02-11 11:53:52 +08:00
@mikulch Java Persistence with Hibernate 最初是 06 年发布, JPA 1.0,人邮出版的影印版本正文有 800 多页。本来之前有一个 Hibernate in action 。这本书算是 Hibernate in action 第二版。

http://jpwh.org/

Java Persistence with Hibernate 第二版已经更新到了 JPA 2.1, 而后面 JPA 2.2 仅有几个 API 变化, 主要为了与 Java 8 API 对齐。

https://github.com/hantsy/ee8-sandbox

虽然 JPA 3.0 发布了( Jakarta EE 9,2020 年),但其 API 与 JPA 2.2 完全一样 ,只是移到 Eclipse 下换了 Namespace(javax->jakarta),引入了 API 不兼容。

Java EE/Jakarta EE 标准变化的没那么快,Spring 5 才更新到 Java EE 8/Jakarta EE 8.
hantsy
2021-02-11 12:16:43 +08:00
@onikage 如果脑子里面的都是表,基本用不来 JPA 。

以前我们一个项目,最终 200 个表,使用 JBoss Seam 框架写的(基于 JPA+JSF+EJB3 标准)。
charlie21
2021-02-11 12:25:38 +08:00
OOP 是最帮助产生就业岗位的,通过权限因素(比如 继承 封装 多态 接口)把很简单的事写得很复杂(一个函数或一句 sql 能搞定的呢现在多了 n 个类)放在历史项目里又要人维护,越能凭空增加工作量就越能给 IT 行业增加多少就业岗位。

OO 时代是不能过去的,如果相对的 FP 时代起来了那么等于在 “开发快但就业岗位少 or 开发慢但就业岗位多” 的选择里 搬起石头砸自己的脚 ... 依附于 OO 的 JPA 推得动是有原因的,尤其在国外。你可以说 这就是闭眼坑雇主,但凭空制造多几个就业岗位 同事会感谢你 未来的你也会感谢现在的自己。

最好一边感谢 OO 带来的就业空间一边学习 OO 向的技能。OOP 作为 solid engineering 思维模式本身是没啥好学的,但帮助了 IT 行业的横行扩展的社会工程学因素就是它了、IT 行业何德何能制造了这么多就业岗位呢 原因就是它了。

是设计过的。是醉翁之意不在酒的
hantsy
2021-02-11 12:27:50 +08:00
@onikage 再扯远一点,经常看看有人讨论 DDD 。

可以看看 DDD 原书代码中,在抽象 Domain Models 的时候根本就不考虑 ORM 。

https://github.com/citerus/dddsample-core/tree/master/src/main/java/se/citerus/dddsample/domain/model

考虑到 Data Persitence 的时候,才用到 ORM 。

https://github.com/citerus/dddsample-core/blob/master/src/main/resources/hibernate.cfg.xml

可以看出这个例子中 Classes 与表设计对应上有多大差别。

在 Hibernate 开始诞生的时候,就有很多关于 ORM 中 Object 和 Relation 应该不一致( Mismatch ) 的文章,来表述 OOP 设计与面象数据设计的差别。

直到现在国内的程序员大多数都是面象数据的思维。这主要源于大学多少学过一点 SQL,用 MyBatis 拿来就可以上手而已。而 Hibernate 这种框架,本身背后有一套自己的设计体系,不仅仅是一个 ORM 那么简单。
hantsy
2021-02-11 14:13:29 +08:00
@Kirsk

Spring 框架本身对 JPA 进行了深度集成,使用 LocalContainerEntityFactoryBean, 可以完全去掉 JPA 的配置文件( orm.xml, persitence.xml , 目前在 Java EE 中,前者可选,后者是必须的),本身就是对 JPA 的 Local EntityManager 使用上简化,同时失去了在分布式 XA 环境下的功能。JPA 一个主要的目的是在 Java EE 规范上代替 EJB 2 的 EntityBean 规范,而 JPA 一个主要的场景就是与 EJB 3.x 结合使用。

Spring Data JPA 前身是 hades (不知道是这个名字,忘记了)是对 Hibernate 的封装。hades 正式被 Spring 吸引后,成立了 Spring Data 项目,Spring Data JPA 是 JPA 的封装,实际上国内大部分人都是用一个 Repository 类而已,对 JPA 本身了解的人很少。

https://github.com/hantsy/ee7-sandbox/tree/master/jpa ( JPA 2.1 新增功能,Java EE 7, 2013 年)

https://github.com/hantsy/ee8-sandbox/ 以 JPA 开头的项目( JPA 2.2 新增功能很少,Java EE 8, 2018 年,Jakarta EE 8,2019 年)
php01
2021-02-11 16:23:07 +08:00
去看看弱类型语言的 orm,比如说 php 的。写起来让你感动到想哭
hantsy
2021-02-11 20:02:48 +08:00
@php01 Doctrine 基本复制了 Hibernate 概念, 写起来也差不多,只是 OOP 方面,PHP 语言本身还有欠缺,写起来肯定不如 Hibernate 舒服。

https://github.com/hantsy/angularjs-zf2-sample/blob/master/module/Album/src/Album/Model/Album.php (现在我 PHP 关注的少,现在 PHP 8 可以直接使用 Attribute 来写,代替 Comment 中的 Annotation )
php01
2021-02-12 00:21:57 +08:00
@hantsy 看看 Eloquent 呗,谁还用玩具呀
nicevar
2021-02-12 12:05:41 +08:00
应用场景问题,JPA 用于后台管理这类比较方便,比如 zf 企业前端喜欢用 extjs,能直接绑定,配合 lombok 这类插件绝大多数情况数据查询逻辑都不用写,直接就完事了。
很多公司的项目都是这样,后台管理用 JPA,提供 API 服务之类的模块不用
hantsy
2021-02-12 13:55:54 +08:00
@php01 我们不讨论吧。我过了玩泥巴的年龄。

首先,PHP 从 5.2 提供大部分强语言特性,不再是弱类型语言。2,Doctrine 不管哪个方面都是比 Eloquent 更胜一筹。Doctrine 还有 Symfony 影响了很多 PHP 的语言特性和工业标准( PSR 等)。
php01
2021-02-12 15:05:17 +08:00
@hantsy 你说的第二点,Doctrine 和 Eloquent,谁更好,或许每个人有每个人的标准。但是你说的第一点,这个是有标准的,PHP 就是弱类型语言,只是他的特性可以提供强类型供人们选择而已。
SkyLine7
2021-02-18 08:54:28 +08:00
楼主用的是 springdata jpa 吗 我觉得还行 就是 sql 调优比较难
XiLemon
2021-02-18 09:46:56 +08:00
@SkyLine7 #54 对呀,感觉很不习惯,现在配合 QueryDSL,感觉好点吧,-_-||
unbright
2021-02-23 10:43:18 +08:00
复杂的 querydsl 还行,就是可读性。。。。。而且对数据库的有些原生函数支持较弱,可以用 expression,一般来说如果关联表非常多的话要么就是设计没做好,要么就是需求没弄好(狗头),可以结合大数据任务写入 es,查询尽量简单
XiLemon
2021-02-23 11:06:09 +08:00
@unbright #56 最后还是用了 QueryDSL,感觉还行。帮别的组做东西,需求确实很凌乱,很坑。
15190049162
2021-03-10 10:29:58 +08:00
我感觉 JPA 太理想化了,很多复杂的 SQL 支持的并不好,但是自动生成简单 SQL 还是很香的,要是 mybatis 支持自动生成简单 SQL 也挺好的。反正我用 mbp
ychost
2021-03-12 12:42:26 +08:00
JPA 比较麻烦且生成的 SQL 比较难看,之前我也特别喜欢用 JPA 但是每次都得去复制 JpaSpecification 的 API 很麻烦,用多了还是觉得 tk.mybatis 比较香一点
hwlfcwl
2022-11-08 16:29:04 +08:00
不要用 jpa, jpa 用的是很爽,但是底层自动生成的 sql 语句在一些关联过多的地方会产生过度联表查询,导致数据库压力过大。而如果由开发者介入,去忽略一些关联,确实能缓解问题,但则随着模型越多,需要修改的地方也在增加,不利于代码的维护。还不如一开始手写 sql 一把梭哈呢。 总之很鸡肋。

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

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

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

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

© 2021 V2EX