使用 Spring Data JPA 搭配 Hibernate 时,Spring Data JPA 主要负责“上层抽象”,Hibernate 负责“底层实现”,两者通过 JPA 规范 实现协作。下面分层说明它们之间的协作原理:
一、核心角色划分
角色 | 说明 |
---|---|
Spring Data JPA | 提供开发友好的接口(如 JpaRepository ),简化数据库操作 |
JPA(Java Persistence API) | 定义ORM规范(比如 @Entity , @OneToMany 等) |
Hibernate | JPA 的一个实现,负责底层数据库操作(SQL生成、连接管理等) |
二、协作流程分解
以下是一个典型的流程,从你调用接口开始,到 Hibernate 执行 SQL:
1️⃣ 你调用 UserRepository.findByName("Tom")
- 这是一个接口方法,继承自
JpaRepository
。 - Spring Data JPA 会根据方法名自动解析成查询逻辑(叫做方法名解析策略)。
2️⃣ Spring Data JPA 创建查询代理对象
- 启动时,Spring 使用代理技术(JDK 动态代理 / CGLIB)为你的
UserRepository
生成实现类。 - 代理类背后调用了 JpaRepository 接口的默认实现(SimpleJpaRepository)。
3️⃣ 调用委托给 EntityManager
SimpleJpaRepository
调用 JPA 的核心接口EntityManager
来执行业务逻辑(例如查询、保存等)。
4️⃣ Hibernate 执行 ORM 映射
EntityManager
实际由 Hibernate 实现,内部使用 Session。- Hibernate 根据实体类的注解信息(如
@Entity
、@Column
等)构造 SQL。 - 最终执行 JDBC 操作访问数据库。
三、具体协作链路图(概念图)
你写的代码
↓
UserRepository(接口) ← ← ← Spring 自动创建代理对象
↓
SimpleJpaRepository(实现类)
↓
EntityManager(JPA 接口)
↓
Hibernate(JPA 实现)
↓
JDBC
↓
数据库
四、补充说明
- JPA 规范是桥梁:Spring Data JPA 和 Hibernate 通过共同遵守 JPA 规范解耦。
- Hibernate 可以替换:如果你愿意,也可以用 EclipseLink、OpenJPA 等替代 Hibernate,但 Hibernate 是默认实现。
- Spring Boot 自动配置:自动创建
EntityManagerFactory
、数据源等,省去大量配置。
总结
Spring Data JPA 负责接口定义和方法封装,让你专注于业务逻辑;
Hibernate 负责 ORM 细节,依据 JPA 规范进行数据的持久化操作。
两者通过 JPA 接口(EntityManager) 无缝协作,提升开发效率的同时保持灵活性和规范性。
源码调试链路说明
下面是 使用 Spring Data JPA + Hibernate 时的源码调试链路,以调用 userRepository.findByName("Tom")
为例,一步步跟踪背后的源码执行过程:
Spring Data JPA + Hibernate 源码调试链路
场景入口
@Autowired
private UserRepository userRepository;
userRepository.findByName("Tom");
1️⃣ 接口方法被代理(Spring 创建 Repository 代理对象)
Spring 启动时会扫描你定义的 UserRepository
,并使用 RepositoryFactoryBeanSupport
创建代理对象:
RepositoryFactoryBeanSupport → getObject() → getRepository()
返回的是一个代理对象,代理逻辑是通过 JpaRepositoryFactory
实现的。
2️⃣ 创建 SimpleJpaRepository
实例作为默认实现类
JpaRepositoryFactory → getTargetRepository()
→ return new SimpleJpaRepository<>(domainClass, entityManager);
你实际调用的 userRepository.findByName()
会委托给 SimpleJpaRepository
。
3️⃣ 解析方法名:findByName
→ 自动生成查询
JpaRepositoryFactory → getRepositoryFragments()
→ 查询方法解析器:QueryLookupStrategy → resolveQuery()
→ 最终使用的是:PartTreeJpaQuery 或 StringQuery
核心逻辑: Spring Data 通过方法名 findByName
解析出一个 JPQL 查询,形如:
SELECT u FROM User u WHERE u.name = :name
4️⃣ 构造查询并执行:调用 EntityManager.createQuery(...)
SimpleJpaRepository.findByName() → JpaQueryExecution → AbstractJpaQuery.doExecute()
→ entityManager.createQuery(jpql).setParameter("name", "Tom").getResultList();
5️⃣ Hibernate 接管 EntityManager 调用
Spring 使用的是 Hibernate 实现的 EntityManager
,即 HibernateEntityManager
(已在 5.x 中被合并到 SharedEntityManagerCreator
中)。
SharedEntityManagerCreator.invoke()
→ HibernateQueryImpl.getSingleResult()
内部使用 Hibernate 的核心类:
Session
(Hibernate 的核心)QueryImpl
- SQL 生成器(AST Parser 或 CriteriaQuery)
Hibernate 将 JPQL 转换为 SQL,并执行 JDBC 操作。
6️⃣ Hibernate 执行 SQL 并返回结果
org.hibernate.loader.Loader → doQuery()
→ ResultSet → 实体映射器(EntityTuplizer)→ 实例化对象并返回
最终得到的实体对象将封装在 List 中返回给 SimpleJpaRepository
,你拿到结果。
总结流程图
你调用方法:
↓
userRepository.findByName()
↓
SimpleJpaRepository
↓
QueryLookupStrategy → JPQL
↓
EntityManager.createQuery(...)
↓
Hibernate 解析 JPQL → SQL
↓
JDBC 查询
↓
ResultSet → 实体映射
↓
返回 List<User>
建议调试入口(关键类)
类名 | 功能 |
---|---|
SimpleJpaRepository | 核心实现类 |
QueryLookupStrategy | 方法解析器 |
JpaQueryFactory / PartTreeJpaQuery | 动态生成查询 |
SharedEntityManagerCreator | Spring 提供的 EntityManager 代理 |
org.hibernate.query.QueryImpl | Hibernate 具体执行 SQL 的入口 |
org.hibernate.loader.Loader | 负责加载和映射数据库数据 |
我们可以使用 IDEA 或 Eclipse,可以通过设置断点进入这些类进行逐步调试。
也可以启用 Hibernate SQL 日志,看到真实 SQL:
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true