P69 为什么用 JPA 半年后哭着换 MyBatis?
面试题:JPA/Hibernate 和 MyBatis 有什么区别?为什么很多团队用 JPA 后又换回 MyBatis?
1. 两者定位
- JPA/Hibernate:ORM 框架,把对象和表映射,开发者操作对象(Entity),SQL 由框架生成(HQL/JPQL/Criteria),主打"少写 SQL";
- MyBatis:半 ORM / SQL 映射框架,SQL 由开发者手写,框架负责参数绑定和结果映射,主打"SQL 可控"。
2. 对比
| 对比项 | JPA/Hibernate | MyBatis |
|---|---|---|
| SQL 控制 | 框架生成,复杂 SQL 难调优 | 手写 SQL,完全可控 |
| 学习曲线 | 难(缓存、懒加载、状态管理坑多) | 简单直观 |
| 动态 SQL | 条件拼装繁琐 | <if>/<foreach> 强大 |
| 性能 | 一二级缓存/懒加载用不好反而拖慢 | 可精准优化 SQL |
| 复杂报表/多表 join | 写起来痛苦 | 直接写 SQL 搞定 |
| 数据库迁移 | 方言层有一定隔离 | SQL 与库相关性强 |
| 代码量 | 实体/仓库少写 SQL | Mapper XML 多 |
3. 为什么"哭着换 MyBatis"
典型痛点:
- 复杂查询不好写:多表 join、子查询、动态条件,JPA 拼 Criteria 很痛苦,性能还难控制;
- N+1 问题:懒加载没用对,一条主查询带出 N 次子查询,性能崩;
- 缓存坑:一级缓存/二级缓存、脏数据、并发问题;
- SQL 不可见不可控:线上慢 SQL 想优化,却很难改 JPA 生成的 SQL;
- 状态管理复杂:detached/merge、级联操作误删数据。
而 MyBatis:SQL 看得见、调得动,团队里"会写 SQL"就能快速上手,符合很多互联网团队"SQL 为王"的风格。
4. 什么时候选 JPA
- 简单 CRUD 为主、对象模型复杂(领域驱动);
- 团队对 Hibernate 很熟;
- 多数据库兼容诉求强。
什么时候选 MyBatis:
- 复杂查询/报表多、性能要求高、SQL 优化频繁的互联网业务。
5. 加分点
- 客观说"不是 JPA 差,是场景不匹配";
- 提到 MyBatis-Plus:在 MyBatis 上补了通用 CRUD,兼顾两者优点;
- 提到"先做简单 CRUD 用 JPA 很爽,业务复杂后 SQL 控不住"是常见转型路径。
一句话总结
JPA 适合对象模型复杂的简单 CRUD,MyBatis 胜在 SQL 完全可控、动态 SQL 强大、容易优化;很多团队换 MyBatis 是因为复杂查询写不动、N+1 和缓存坑多、SQL 不可控,本质是互联网业务对 SQL 性能和可控性要求高。