一、结论
对于 Spring Boot 项目:
text
推荐:
EntityManager
不推荐:
HibernateTemplate
甚至可以说:
text
Spring Boot + JPA
基本已经不再使用 HibernateTemplate
二、HibernateTemplate 是什么
来自:
java
org.springframework.orm.hibernate3.HibernateTemplate
或者:
java
org.springframework.orm.hibernate5.HibernateTemplate
属于 Spring 早期对 Hibernate 的封装。
当年(Spring2.x、Spring3.x)写法:
java
public class UserDao {
private HibernateTemplate hibernateTemplate;
public void update(User user){
hibernateTemplate.merge(user);
}
}
当时的 Hibernate 原生代码:
java
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.merge(user);
tx.commit();
session.close();
代码比较繁琐。
所以 Spring 提供了:
java
HibernateTemplate
帮你处理:
text
获取Session
关闭Session
异常转换
事务同步
三、EntityManager 是什么
JPA标准接口:
java
javax.persistence.EntityManager
Spring Boot 默认就是:
text
Spring Data JPA
↓
EntityManager
↓
Hibernate
关系:
text
EntityManager
↓
Hibernate Session
实际上:
java
entityManager.merge(entity);
最终也是调用:
java
Session.merge(entity);
四、merge() 本质区别
HibernateTemplate
源码(Hibernate3时代):
java
hibernateTemplate.merge(entity)
内部:
java
Session session = getSession();
session.merge(entity);
最后:
java
return mergedObject;
EntityManager
java
entityManager.merge(entity);
最终:
java
Session.merge(entity);
所以从 Hibernate 角度:
text
HibernateTemplate.merge
=
EntityManager.merge
=
Session.merge
最终执行逻辑几乎一样。
五、最大的区别
不是 merge 本身。
而是:
text
整个框架体系
HibernateTemplate
依赖:
java
SessionFactory
代码:
java
@Autowired
private HibernateTemplate hibernateTemplate;
DAO风格:
java
hibernateTemplate.save()
hibernateTemplate.update()
hibernateTemplate.merge()
hibernateTemplate.find()
典型老项目:
text
Spring3
Hibernate3
Struts1
Struts2
EntityManager
依赖:
java
@PersistenceContext
private EntityManager entityManager;
代码:
java
entityManager.persist()
entityManager.merge()
entityManager.remove()
entityManager.find()
典型现代项目:
text
Spring Boot
JPA
Hibernate5/6
六、Spring Boot 官方推荐
Spring Boot 官方路线:
text
Repository
↓
JPA
↓
EntityManager
↓
Hibernate
例如:
java
@Repository
public interface UserRepository
extends JpaRepository<User,Long> {
}
底层就是:
java
EntityManager
不是:
java
HibernateTemplate
七、性能有区别吗
几乎没有。
例如:
java
entityManager.merge(user);
最终:
java
Session.merge(user);
java
hibernateTemplate.merge(user);
最终:
java
Session.merge(user);
执行 SQL:
sql
update user set ...
完全一样。
八、Spring Boot 推荐哪种写法
推荐级别:
第一推荐
java
JpaRepository
例如:
java
public interface UserRepository
extends JpaRepository<User,Long> {
}
第二推荐
java
@PersistenceContext
private EntityManager entityManager;
复杂查询:
java
entityManager.createQuery(...)
第三推荐
特殊场景:
java
Session session =
entityManager.unwrap(Session.class);
直接使用 Hibernate API:
java
session.createQuery(...)
不推荐
java
HibernateTemplate
原因:
text
属于老Spring时代产物
JPA标准不兼容
Spring Boot生态基本不用
大量新特性不支持
九、如果是新项目
Spring Boot 3.x + Hibernate 6.x
推荐:
java
@Service
@Transactional
public class UserService {
@PersistenceContext
private EntityManager entityManager;
public void update(Long id){
User user =
entityManager.find(User.class,id);
user.setUserName("张三");
// 不需要 merge
// 脏检查自动更新
}
}
甚至:
java
userRepository.save(user);
都可以省掉。
因为:
text
Managed Entity
+
@Transactional
+
Dirty Checking
已经足够。
所以如果你的项目是:
text
Spring Boot 2.x / 3.x
Hibernate 5.x / 6.x
建议优先使用:
java
EntityManager
或者直接:
java
JpaRepository
而不要再引入:
java
HibernateTemplate