涉及到了 Spring 和 Hibernate 的核心机制,也是很多人刚开始用 JPA 时容易混淆的点。
✅ 一、什么是 Session?
在 Hibernate 中,Session 是核心接口,表示一次和数据库的“会话”。
• 它负责:
• 管理实体(增删改查)
• 执行 HQL、SQL
• 追踪实体变化(脏检查)
• 缓存一级数据
• Hibernate 的 Session 通常和数据库连接是一对一的短生命周期对象,在 Spring 里,默认情况下,它是和当前事务绑定的,也就是 一个事务,一个 Session。
✅ 二、@EntityManager 和 Session 有啥关系?
这俩其实是一回事,只是接口层级不同:
|
名称 |
来源 |
本质 |
说明 |
|---|---|---|---|
|
EntityManager |
JPA 标准接口 |
JPA 的标准会话对象 |
和 JPA 提供的通用操作有关 |
|
Session |
Hibernate 专属接口 |
Hibernate 的实现 |
Hibernate 提供更多底层能力,如 StatelessSession |
👉 换句话说:你注入的 @PersistenceContext EntityManager,其实底层就是 Hibernate 的 Session 的一层封装。
可以通过 unwrap() 获取原生 Session:
Session session = entityManager.unwrap(Session.class);
✅ 三、那 JdbcTemplate 又是啥?
JdbcTemplate 是 Spring 提供的 JDBC 封装工具类,和 Hibernate 没关系。
|
项目 |
JdbcTemplate |
EntityManager / Session |
|---|---|---|
|
底层 |
直接用 JDBC API |
ORM 框架(Hibernate) |
|
类型 |
面向 SQL 和行 |
面向对象(Entity) |
|
特点 |
快速、轻量、无缓存、无脏检查 |
有生命周期管理、脏检查、缓存 |
|
适合场景 |
简单SQL、批处理、报表查询 |
复杂对象关系映射、业务模型管理 |
🌰 一个例子来理解三者区别:
如果你要更新用户名字,可以这样写:
• 用 EntityManager(JPA 风格):
User user = entityManager.find(User.class, 1L);
user.setName("Alice"); // 脏检查 + 自动 update
• 用 Hibernate 的原生 Session(底层操作):
Session session = entityManager.unwrap(Session.class);
session.createQuery("UPDATE User u SET u.name = :name WHERE u.id = :id")
.setParameter("name", "Alice")
.setParameter("id", 1L)
.executeUpdate();
• 用 JdbcTemplate(纯 SQL 风格):
jdbcTemplate.update("UPDATE users SET name = ? WHERE id = ?", "Alice", 1L);
✅ 四、总结下区别和关系:
|
特性 |
EntityManager |
Hibernate Session |
JdbcTemplate |
|---|---|---|---|
|
来源 |
JPA 规范 |
Hibernate 实现 |
Spring JDBC |
|
是否 ORM |
是 |
是 |
否 |
|
是否追踪实体变化 |
是 |
是 |
否 |
|
是否自动管理事务 |
是(依赖 Spring 配置) |
是(依赖 Spring) |
是(依赖 Spring) |
|
是否缓存对象 |
有一级缓存 |
有一级缓存 |
无缓存 |
|
灵活性 |
中等 |
高 |
非常高(但需手动处理) |
如果你项目中同时用到了 @EntityManager 和 JdbcTemplate,一般是因为:
• 大多数业务场景用 JPA(EntityManager/Session)处理对象;
• 需要极致性能、灵活查询、复杂统计的时候,会用 JdbcTemplate。
浙公网安备 33010602011771号