如果业务逻辑明确变更内容,也可以直接使用 JPQL/HQL 或原生 SQL 执行更新 意思是不使用session吗?
非常棒的问题!你说得对,这里确实涉及到是不是还要用 Session ——我来详细解释一下这句话背后的含义:
✅ 先回答你的问题:
“如果业务逻辑明确变更内容,也可以直接使用 JPQL/HQL 或原生 SQL 执行更新”,并不是说不使用 Session,而是说不使用“脏检查”的机制来触发更新操作。
Hibernate 的 Session 仍然参与,但你可以选择跳过“实体对象 -> 内存 -> 脏检查 -> SQL”的这一整套流程,而是自己直接告诉 Hibernate 去执行更新操作。
🧩 举个对比说明:
❌ 使用默认 Hibernate 的方式(依赖脏检查):
User user = session.get(User.class, 1);
user.setName("Alice");
session.getTransaction().commit(); // Hibernate 检测到 name 变化,生成 update 语句
优点:简单
缺点:可能不必要地触发 update,还得在 session 中维持对象状态
✅ 使用 JPQL 或原生 SQL(主动更新):
// 使用 JPQL(更新 name)
session.createQuery("UPDATE User u SET u.name = :name WHERE u.id = :id")
.setParameter("name", "Alice")
.setParameter("id", 1)
.executeUpdate();
或者:
// 使用原生 SQL
session.createNativeQuery("UPDATE users SET name = :name WHERE id = :id")
.setParameter("name", "Alice")
.setParameter("id", 1)
.executeUpdate();
✅ 优点:
• 不需要先加载对象(省一次查询)
• 不进入脏检查(不用维护快照)
• 控制精细,效率高,适合批量更新
⚠️ 缺点:
• 不会自动同步 Hibernate 缓存中的 entity(可能造成缓存与 DB 不一致)
• 写起来稍微“SQL 味儿”重,不那么 ORM 化
🧠 总结:
所以说:你还是使用 Session 来执行更新语句,但你绕过了 Hibernate 的实体管理和脏检查系统,变成你主动告诉 Hibernate 要更新什么。
这种方式在:
• 批量更新
• 不需要查询实体的场景
• 追求性能的地方
尤其有用。
浙公网安备 33010602011771号