对于 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
相关推荐
子兮曰5 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰5 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
爱勇宝5 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
胡写代码5 天前
别再前后端各写一套表单校验了
java·后端
大勇前进5 天前
原生 PHP 还是 Laravel?小项目到底要不要上框架
后端
vipxieliang5 天前
ValidX 在 DDD 领域驱动设计中的实践
java·spring boot
yuzhi_liu5 天前
我用 LangGraph4j 实现 Multi-Agent Supervisor
后端
alsmile5 天前
Node-RED 之外,国产规则引擎的新方案:基于标准语法,Go 先行实现
后端·开源·go
大白805 天前
PHP 内存溢出排查思路:看懂报错日志,精准定位问题
后端
二月龙5 天前
PHP 接口返回统一响应封装,让前后端对接更省心
后端