当前位置: 首页 > news >正文

学习 ORM(JPA/Hibernate)的“收益”

你学了整套 ORM 体系,换来了什么?

ORM 的宣传口径是:你只需要操作 Java 对象,框架自动帮你生成 SQL、管理关系、处理缓存。你不需要写 SQL,不需要关心数据库细节。

这套说辞听起来很美,但代价是什么?

下面这张表,列出了你为了“不用写 SQL”而需要学习的全部内容。

一、为了“把对象映射成表”,你学到的收益

ORM 概念它的作用
@Entity告诉框架这个类是实体
@Table指定对应的数据库表名
@Column指定字段映射(列名、长度、是否可空)
@Id标记主键字段
@GeneratedValue指定主键生成策略(AUTO、IDENTITY、SEQUENCE、TABLE)
@Transient标记非持久化字段
@Enumerated枚举类型映射(ORDINAL / STRING)
@Temporal日期类型映射(DATE / TIME / TIMESTAMP)
@Lob大字段映射(BLOB / CLOB)
@Version乐观锁版本号字段
@Embeddable/@Embedded嵌入对象映射
@EmbeddedId复合主键
@MappedSuperclass父类字段继承

二、为了“关联其他表”,你学到的收益

ORM 概念它的作用
@OneToOne一对一关联
@OneToMany一对多关联
@ManyToOne多对一关联
@ManyToMany多对多关联
@JoinColumn指定外键列名
@JoinTable多对多中间表配置
@OrderBy关联集合的排序方式
mappedBy双向关联的对方字段
fetch = LAZY / EAGER关联加载时机
cascade = ALL / PERSIST / MERGE / REMOVE / REFRESH / DETACH级联操作类型
orphanRemoval = true / false孤儿对象删除策略

三、为了“操作数据”,你学到的收益

ORM 概念它的作用
EntityManagerJPA 核心操作接口
EntityManagerFactoryEntityManager 工厂
EntityTransaction事务管理
persist()保存实体
merge()合并实体(更新)
remove()删除实体
find()按主键查询
getReference()懒加载引用查询
flush()立即同步到数据库
detach()从持久上下文分离
clear()清空持久上下文
contains()判断是否托管

四、为了“查询数据”,你学到的收益

HQL / JPQL(一门全新的查询语言)
概念它的作用
SELECT ... FROM查询实体(注意:FROM 后面是实体名,不是表名)
JOIN FETCH关联预加载(为了解决 N+1)
WHERE+ 对象属性路径条件查询(用u.name而不是u.name的 SQL 字段名)
GROUP BY/HAVING分组聚合
ORDER BY排序
NEW构造器表达式直接构造 VO 对象
子查询支持但不完整
聚合函数支持 COUNT、SUM、AVG、MAX、MIN,但有限制
窗口函数不支持
递归 CTE不支持
UNION不支持
数据库特有函数(DATE_FORMATEXTRACTJSON_EXTRACT等)不支持,或需注册方言
Criteria API(一套更“类型安全”的查询构造器)
概念它的作用
CriteriaBuilder查询构建器入口
CriteriaQuery<T>定义查询返回类型
Root<T>查询根节点
Join<Z, X>关联查询
Predicate条件组合(AND / OR / NOT)
Path属性路径访问
Order排序条件
Expression表达式(算术运算、函数调用)
Subquery子查询构造
Metamodel静态元模型(需要代码生成器)

你学完这套 Criteria API,写出来的代码长这样:

CriteriaBuildercb=entityManager.getCriteriaBuilder();CriteriaQuery<User>query=cb.createQuery(User.class);Root<User>user=query.from(User.class);Join<User,Order>order=user.join("orders");Predicatepredicate=cb.and(cb.equal(user.get("name"),"张三"),cb.greaterThan(order.get("amount"),100));query.select(user).where(predicate).orderBy(cb.desc(user.get("createTime")));List<User>result=entityManager.createQuery(query).getResultList();

五、为了“理解框架行为”,你学到的收益

ORM 概念它的作用
一级缓存(Persistence Context)同一个 EntityManager 内的对象缓存,自动管理
二级缓存跨 EntityManager 的缓存,需额外配置
查询缓存查询结果缓存,需配合二级缓存使用
脏检查机制框架自动检测托管对象的变化并生成 UPDATE
延迟加载访问关联对象时才触发查询,否则是代理对象
关联加载策略LAZY vs EAGER,选错了就是 N+1
会话管理什么时候打开 EntityManager,什么时候关闭
托管状态 / 游离状态 / 分离状态 / 删除状态四种状态的区分,以及状态转换规则
乐观锁实现机制@Version注解 + 版本号检查
事务传播行为需要配合 Spring 事务管理(@Transactional的各种属性)
方言(Dialect)不同数据库的 SQL 方言差异,需要选择正确的方言类

六、为了“处理复杂场景”,你学到的收益

ORM 概念它的作用
@NamedQuery预定义 JPQL 查询,启动时解析
@NamedNativeQuery预定义原生 SQL 查询
@SqlResultSetMapping原生 SQL 结果映射到实体
@ConstructorResult原生 SQL 结果映射到 VO
@EntityGraph动态控制关联加载图
@NamedEntityGraph预定义关联加载图
@Query(Spring Data JPA)在 Repository 接口上写 JPQL 或原生 SQL
@Modifying标记 UPDATE / DELETE 操作
@Transactional事务边界控制(其实跟 JPA 无关,是 Spring 的能力)
PersistenceUnitUtil工具类,判断实体状态
EntityManager.createNativeQuery()你终于退回了原生 SQL

这些“收益”的最终结果是什么?

你学完了:

  • 20+ 个注解
  • 10+ 个关联关系配置
  • 一套完整的查询语言(JPQL/HQL)
  • 一套复杂的 Criteria API
  • N+1 问题的识别与解决方案
  • 四种实体状态及转换规则
  • 一级缓存 / 二级缓存 / 查询缓存的区别与用法
  • 方言配置

你以为换来了“不用写 SQL”。

但事实是:

  • 复杂联表查询你写不出 JPQL → 退回到createNativeQuery()
  • 窗口函数、递归 CTE、UNION → JPA 不支持 → 退回到createNativeQuery()
  • 报表统计 > 3 张表 JOIN → JPQL 写起来比 SQL 还难懂 → 退回到createNativeQuery()
  • 需要调优 SQL 时,框架生成的那坨 SQL 你自己都看不懂 → 退回到createNativeQuery()

你学了一大套 ORM 体系,最终在复杂场景下,它只是你退回原生 SQL 路上的一个减速带。

破:MyBatis 至少还让你写 SQL,JPA 连让你写 SQL 都要绕一圈

MyBatis 的缺点是 XML 太啰嗦,但它至少让你直接写 SQL。你的 SQL 能力是完整的。

JPA 的问题是:你学了一套框架,但它主动阉割了你的 SQL 能力。你本来能写 SQL,但框架告诉你“用 JPQL”,你用了之后发现 JPQL 只有 SQL 1/3 的能力。剩下 2/3 的能力,你只能退回原生 SQL——但这时你发现,你学的那套 JPQL 语法在复杂场景下毫无用处。

你学了一套专有语法,结果它在你最需要的时候用不上。那学它的“收益”在哪?

立:SimpleDAO

SimpleDAO 不做对象关系映射,不管理对象状态,不制造缓存,不生成 SQL。

  • 你要查数据?写 SQL,调用list()
  • 你要联表?写 SQL,调用page()
  • 你要复杂报表?写 SQL,调用list()
  • 你要调优?复制 SQL 到数据库直接跑

你不需要学 JPQL、Criteria API、EntityManager、缓存策略、懒加载配置、四种状态转换、N+1 解决方案、方言配置、EntityGraph、二级缓存配置……

你只需要会 SQL,就会用 SimpleDAO。

因为它的核心能力只有一条:执行你写的 SQL,把结果映射成 Java 对象。

就这么简单。没有任何隐藏的“收益”,也没有任何隐藏的成本。

开源地址

  1. 核心框架:https://gitee.com/gao_zhenzhong/simple-dao
  2. 系统底座:https://gitee.com/gao_zhenzhong/simple-dao-starter
  3. 代码生成器:https://gitee.com/gao_zhenzhong/simple-dao-coder
  4. 实战案例:https://gitee.com/gao_zhenzhong/simple-dao-demo

写在最后

MyBatis 让你学了几十个标签、上百个属性、十几个注解、31 个异常,最终换来的是“在 XML 里拼一个字符串”。

JPA 让你学了 20+ 个注解、10+ 个关联关系、一套 JPQL 语法、一套 Criteria API、四种状态转换、三种缓存策略、一套方言体系……最终换来的是“写了复杂查询时,还得退回到原生 SQL”。

但是,我们也要承认一个事实:单表对象化确实是一个真实的收益。

在单表 CRUD 的场景下,JPA 和 Hibernate 确实能帮你省掉写 INSERT、UPDATE、DELETE 和按主键 SELECT 的 SQL。你不用写 INSERT INTO user (name, age) VALUES (?, ?),直接 user.setName(“张三”) 然后 entityManager.persist(user) 就行。

这个收益是真实的,不是带引号的。

问题是:单表 CRUD 只是企业持久层开发的一小部分——远不到 10%。

剩下的 90%(多表联查、子查询、聚合报表、批量更新、跨表条件筛选……),才是你真正要面对的业务场景。而这些场景下,JPA 帮不了你,你只能退回到原生 SQL。

所以,单表对象化是一个真实的收益,但它覆盖的只是业务中很小的一部分。用一个覆盖 10% 场景的收益,换取 90% 场景下的复杂度和限制,这笔账怎么算,你自己权衡。

两个方向,殊途同归。

SimpleDAO 让你什么都不用多学,你只需要会 SQL,就会用它。

它把“你不用学什么”当作核心收益。

哪一个收益是真的,你自己算账。

http://www.gsyq.cn/news/1579382.html

相关文章:

  • ArkUI组件
  • 深圳口碑好的饭堂承包服务商
  • 数字孪生项目案例 | 科技风工厂可视化
  • 喜讯!泰克尼康参编《宇航级民用食品安全要求》团体标准正式发布实施!
  • 防晒工作服衬衫
  • 解锁Windows远程桌面多用户连接的终极解决方案:RDP Wrapper配置详解
  • TDengine 时序数据库实战笔记(20260622)
  • AI+产业落地:从试点尝鲜到价值闭环的六大场景
  • 第03章|分而治之:Sub-Agents 的核心概念与应用价值
  • 2048游戏模拟
  • 中小运营商 5G 核心网建设方案
  • Linux安装vcpkg
  • 基于FME的高程点与等高线矛盾检查
  • 让Mac应用保持最新:Latest使用全攻略
  • 10 分钟搭好语音 AI Agent,LiveKit 凭什么成为 OpenAI 的基建选择
  • Emacs AI助手:3个理由让你在编辑器中体验大型语言模型的强大能力
  • 前后端分离德州酒吧小程序:存酒管理、扫码点单、在线组局逻辑代码拆解
  • 承接定制AI智能控制会议医疗录播主机
  • RAG 检索精度优化之道:数据清洗与预处理全流程深度解析
  • 【AI原生LoRA技术权威指南】:SITS 2026低秩适配全栈解析——覆盖训练、部署、量化3大实战瓶颈
  • Reproxy:微服务时代边缘代理的终极解决方案
  • DFIG双馈风机、低电压穿越LVRT+转子侧快速短接、网侧矢量补偿控制仿真(带参考文献)
  • 基于KNN算法的健身会员个性化锻炼与饮食方案推荐研究
  • 维铂叁科普知识丨数字防伪印章
  • 从概念验证到百万QPS商用:3家头部AI OS厂商同步采用的插件生命周期管理模型(含GitHub Star超2.4k的开源参考实现)
  • RTKLIB中关于不同的码通道
  • 单模型采样的统计学本质与系统性偏差分析 | 上篇单模型采样的统计学本质与系统性偏差分析 | 上篇
  • 2026 降AI率工具实测对比:公认好用的,科研党救急指南
  • 作为宝妈研究者我给孩子选的脑营养不是最贵的是最对的
  • 为什么92%的AI中台项目在Adapter层失败?20年架构老兵亲授6个反模式诊断清单与即时修复checklist