一、基本概念
1. MyBatis
- 是一个 半自动的 ORM 框架(Object-Relational Mapping),用于简化 JDBC 开发。
- 它允许你通过 XML 或注解配置 SQL 语句,将 Java 对象与 SQL 查询结果进行映射。
2. MyBatis-Plus(MP)
- 是在 MyBatis 基础上的 增强工具包,由 baomidou 团队开发,
- 目的是 简化开发、提升效率,实现 开箱即用的 CRUD 操作。
3. JPA(Java Persistence API)
- 是一种 规范(接口和注解),不提供具体实现;
- 定义了 ORM(对象关系映射)应该怎么做,比如 @Entity、@Id、@OneToMany 等注解;
- 你可以用 Hibernate、EclipseLink、TopLink、OpenJPA 等去实现它。
4. Hibernate
- 是 JPA 的一个 主流实现;
- 在 JPA 规范出现之前就存在(那时以 SessionFactory 为核心);
- 后来兼容 JPA,逐渐过渡到使用 EntityManager 等 JPA 风格接口。
5. Spring Data JPA
- 是 Spring 官方开发 的一个项目;
- 是对 JPA(及其实现,如 Hibernate)进行的高层封装;
- 大幅简化了数据访问层的开发:只需定义接口,连 SQL 和实现类都不写;
- 默认使用 Hibernate 作为底层实现(当然你可以配置其他 JPA 实现)。
Spring Data JPA 、JPA、Hibernate 的关系
层级 | 框架/技术 | 作用说明 |
---|
1️⃣ 高层封装 | Spring Data JPA | 简化数据访问,屏蔽大量样板代码 |
2️⃣ 标准接口 | JPA | 提供统一的 ORM 编程接口规范 |
3️⃣ 具体实现 | Hibernate | JPA 的实现者,负责真正操作数据库 |
二、详细功能/特性对照表
功能 / 特性 | MyBatis | MyBatis-Plus | Hibernate | Spring Data JPA |
---|
手写 SQL | ✅ 全部手写 | ✅ 支持手写 + 提供自动 CRUD | ❌ 主要用 HQL/JPQL 或实体映射 | ❌ 使用方法命名生成,或使用 JPQL |
动态 SQL | ✅ 、 标签等 | ✅ 同 MyBatis,支持 Wrapper 方式构造条件 | ❌ 使用 Criteria API 或 JPQL 动态拼接 | ❌ 支持 @Query + 参数拼接、Specification |
自动 CRUD | ❌ 全部自定义 | ✅ 提供 BaseMapper 自动增删改查 | ✅ 提供 EntityManager 接口操作实体 | ✅ 提供 JpaRepository 接口快速操作 |
分页支持 | ❌ 需手写分页 SQL | ✅ 内置分页插件 PageHelper | ❌ 需 Criteria 或 HQL + 手动分页 | ❌ 需 PageRequest 参数封装 |
Lambda 条件构造器 | ❌ 不支持 | ✅ 支持 QueryWrapper.lambda() 方式构建条件 | ❌ 使用 CriteriaQuery/JPQL 构建 | ❌ 使用 Specification |
关联查询(多表) | ✅ 手动写 JOIN | ✅ 手动写 JOIN | ✅ 实体间关联注解(如 @OneToMany) | ✅ 实体间注解 + 方法命名(或 @Query) |
缓存支持 | ✅ 一级缓存 | ✅ 同 MyBatis,支持一级缓存 | ✅ 一级 + 二级缓存(如 EhCache) | ✅ 依赖 Hibernate 实现的缓存机制 |
代码侵入性 | 高(需写 Mapper 接口 + XML) | 中等(需继承 BaseMapper) | 低(注解驱动) | 低(接口继承 JpaRepository 即可) |
开发效率 | 中(适合复杂 SQL) | 高(CRUD 快速,复杂查询灵活) | 中(需建模、配置多) | 高(快速构建数据层) |
SQL 控制力 | ✅ 极强 | ✅ 强(也可自动) | ❌ 较弱(自动生成,不易控制) | ❌ 较弱(命名方式自动推导) |
适合复杂查询场景 | ✅ 最合适 | ✅ 支持 wrapper + 手写 SQL | ❌ 需要使用 Criteria/HQL 构建 | ❌ 复杂场景需写 Specification / JPQL |
学习成本 | 中 | 低(封装好,文档全) | 高(需理解 ORM 全流程) | 中(Spring 熟悉则容易上手) |
是否支持规范 JPA | ❌ 否 | ❌ 否 | ✅ 是(JPA 规范主要实现) | ✅ 是(JPA 的 Spring 封装) |
三、性能对比
框架 | 性能特点 |
---|
MyBatis | ✅ 性能最优,执行原生 SQL,无额外开销。开发者手写 SQL,控制精细,适合大数据量、高并发场景。 |
MyBatis-Plus | ✅ 在 MyBatis 基础上扩展,性能几乎无损。自动 CRUD 生成的 SQL 性能接近手写 SQL。 |
Hibernate | ❌ 性能相对低一点,尤其在复杂对象映射、关联加载时。懒加载、缓存配置不当时易引起性能问题。 |
Spring Data JPA | ❌ 基于 Hibernate,使用上简单但封装更深,自动生成 SQL 可能不够高效,性能不可控。 |
四、事务控制对比
框架 | 事务控制方式 | 特点说明 |
---|
MyBatis | 手动或 Spring 事务 | 使用 @Transactional 控制事务,通常与 Spring 配合使用 |
MyBatis-Plus | 同 MyBatis | 支持 Spring 事务注解(如 @Transactional),无额外增强 |
Hibernate | 内建事务管理器 + Spring 支持 | Hibernate 有自己的 Session 和事务机制,集成 Spring 后统一使用 @Transactional |
Spring Data JPA | 基于 JPA 规范事务 | 默认开启事务支持,使用 @Transactional 注解管理,简洁清晰 |
五、在 Spring Boot 中默认使用的是 Spring Data JPA
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
默认情况下,它使用的是 Hibernate 作为 JPA 实现。
六、Hibernate学习成本高,为什么 Spring Data JPA 用起来简单?
1.为什么说 Hibernate 学习成本高?
要点 | 说明 |
---|
抽象多、概念多 | Hibernate 有很多抽象和机制,比如一级缓存、二级缓存、延迟加载、级联操作、实体生命周期、脏数据检查等。要理解清楚这些需要较深的 ORM 原理知识。 |
隐藏 SQL,调试困难 | Hibernate 默认自动生成 SQL,如果不了解其机制,很容易出现性能问题或意外行为,排查困难。 |
懒加载陷阱 | 比如常见的 LazyInitializationException 异常(在 session 关闭后再访问延迟加载字段),新手很容易踩坑。 |
复杂关联映射难配置 | 多对多、一对多映射,特别是双向关联和级联策略配置(mappedBy、cascade、orphanRemoval)对初学者不友好。 |
批量操作、性能调优难 | Hibernate 默认不适合批量操作,大量数据写入/更新时需要特殊配置和写法来提升效率。 |
事务管理更敏感 | Hibernate 与事务绑定紧密,一旦理解不清楚事务边界,可能造成数据丢失或回滚失败等问题。 |
缓存与一致性难掌控 | 一级缓存自动生效、二级缓存需要配置,但如何正确地保证一致性是个挑战。 |
2.为什么 Spring Data JPA 用起来简单?
原因 | 说明 |
---|
封装了很多 Hibernate 细节 | 你只需要定义 Repository 接口,连实现类都不需要写,查询也可用方法命名自动生成。 |
适合简单 CRUD | 如果只是做基础的增删改查,Spring Data JPA 能极大减少代码量。 |
内置配置好、约定优于配置 | Spring Boot 帮你做好了大部分 Hibernate 的默认配置,不需要深入 Hibernate 本身。 |