对于 Spring Boot 项目 使用Hibernate

一、结论

对于 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
相关推荐
IT_陈寒4 小时前
为什么我的JavaScript异步代码总是不按顺序执行?
前端·人工智能·后端
星栈4 小时前
Node 框架怎么选?Express、Koa、Egg、NestJS 场景化选型指南
后端·node.js
锋行天下4 小时前
打造企业内部知识库系统RAG全栈项目
前端·后端·架构
音符犹如代码5 小时前
后端视角看 EventBus:发布订阅总线的原理、场景与用法
java·spring boot·guava
码事漫谈5 小时前
Kimi K3 真实体验:全网评价整理,优缺点一次性说清楚
后端
Fanta丶5 小时前
16.Activiti8 SpringBoot3.X 部署与测试
后端
用户208046804565 小时前
Python3 数据类型转换新手实战指南
后端
苏三说技术6 小时前
为什么Spring要“抛弃”Feign?
后端
神奇小汤圆6 小时前
Java代理模式深度解析:静态代理 vs 动态代理 vs CGLIB
后端
爱勇宝6 小时前
AI不会淘汰所有人,但会淘汰这6种人
前端·后端·程序员