Spring Framework 整合 Hibernate 的全面指南

Spring Framework 整合 Hibernate 的全面指南

spring-framework spring-projects/spring-framework: 一个基于 Java 的开源应用程序框架,用于构建企业级 Java 应用程序。适合用于构建各种企业级 Java 应用程序,可以实现高效的服务和管理。 spring-framework 项目地址: https://gitcode.com/gh_mirrors/sp/spring-framework

前言

在现代企业应用开发中,对象关系映射(ORM)技术扮演着重要角色。Spring Framework 提供了对多种 ORM 技术的支持,其中 Hibernate 是最受欢迎的选择之一。本文将深入探讨 Spring 如何优雅地集成 Hibernate,帮助开发者构建高效、可维护的数据访问层。

Hibernate 版本支持说明

Spring Framework 6.0 对 Hibernate 的支持有以下要点:

  1. 对于 HibernateJpaVendorAdapter 和原生 Hibernate SessionFactory 配置,需要 Hibernate ORM 5.5+
  2. 推荐使用 Hibernate ORM 5.6 作为该代系的最后一个功能分支
  3. Hibernate ORM 6.x 仅支持作为 JPA 提供者(HibernateJpaVendorAdapter)
  4. 新项目推荐使用 Hibernate ORM 6.1/6.2 配合 JPA 风格配置

配置 SessionFactory

基础配置

在 Spring 容器中配置 SessionFactory 是集成 Hibernate 的第一步。通过将资源(如 JDBC DataSource 或 Hibernate SessionFactory)定义为 Spring bean,可以避免硬编码资源查找。

<beans>
    <!-- 配置数据源 -->
    <bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
        <property name="url" value="jdbc:hsqldb:hsql://localhost:9001"/>
        <property name="username" value="sa"/>
        <property name="password" value=""/>
    </bean>

    <!-- 配置SessionFactory -->
    <bean id="mySessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="myDataSource"/>
        <property name="mappingResources">
            <list>
                <value>product.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <value>
                hibernate.dialect=org.hibernate.dialect.HSQLDialect
            </value>
        </property>
    </bean>
</beans>

JNDI 数据源配置

如果需要使用 JNDI 数据源(通常由应用服务器管理),配置非常简单:

<beans>
    <jee:jndi-lookup id="myDataSource" jndi-name="java:comp/env/jdbc/myds"/>
</beans>

高级特性

Spring 还提供了 LocalSessionFactoryBuilder,可以与 @Bean 风格的配置无缝集成。LocalSessionFactoryBeanLocalSessionFactoryBuilder 都支持后台引导,Hibernate 初始化可以在给定的引导执行器上与应用程序引导线程并行运行。

基于原生 Hibernate API 实现 DAO

基本实现

Hibernate 的上下文会话功能允许 Hibernate 自己管理每个事务的当前 Session。这与 Spring 的每个事务同步一个 Hibernate Session 的方式类似。以下是一个基于原生 Hibernate API 的 DAO 实现示例:

public class ProductDaoImpl implements ProductDao {
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public Collection loadProductsByCategory(String category) {
        return this.sessionFactory.getCurrentSession()
                .createQuery("from test.Product product where product.category=?")
                .setParameter(0, category)
                .list();
    }
}

配置 DAO

在 Spring 容器中配置这个 DAO:

<beans>
    <bean id="myProductDao" class="product.ProductDaoImpl">
        <property name="sessionFactory" ref="mySessionFactory"/>
    </bean>
</beans>

这种 DAO 风格的优点是它只依赖于 Hibernate API,不需要导入任何 Spring 类。对于 Hibernate 开发者来说,这感觉更自然。

声明式事务管理

使用 @Transactional 注解

Spring 的声明式事务支持允许你用 AOP 事务拦截器替换 Java 代码中的显式事务划分 API 调用。你可以使用 Java 注解或 XML 在 Spring 容器中配置这个事务拦截器。

public class ProductServiceImpl implements ProductService {
    private ProductDao productDao;

    public void setProductDao(ProductDao productDao) {
        this.productDao = productDao;
    }

    @Transactional
    public void increasePriceOfAllProductsInCategory(final String category) {
        List productsToChange = this.productDao.loadProductsByCategory(category);
        // ...
    }

    @Transactional(readOnly = true)
    public List<Product> findAllProducts() {
        return this.productDao.findAllProducts();
    }
}

容器配置

在容器中,你需要设置 PlatformTransactionManager 实现(作为 bean)和一个 <tx:annotation-driven/> 条目,以在运行时启用 @Transactional 处理。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/tx
        https://www.springframework.org/schema/tx/spring-tx.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 省略 SessionFactory, DataSource 等配置 -->

    <bean id="transactionManager"
            class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <tx:annotation-driven/>

    <bean id="myProductService" class="product.SimpleProductService">
        <property name="productDao" ref="myProductDao"/>
    </bean>
</beans>

编程式事务管理

实现方式

你可以在应用程序的更高层次划分事务,覆盖任意数量操作的底层数据访问服务。以下是一个编程式事务管理的示例:

public class ProductServiceImpl implements ProductService {
    private TransactionTemplate transactionTemplate;
    private ProductDao productDao;

    public void setTransactionManager(PlatformTransactionManager transactionManager) {
        this.transactionTemplate = new TransactionTemplate(transactionManager);
    }

    public void setProductDao(ProductDao productDao) {
        this.productDao = productDao;
    }

    public void increasePriceOfAllProductsInCategory(final String category) {
        this.transactionTemplate.execute(new TransactionCallbackWithoutResult() {
            public void doInTransactionWithoutResult(TransactionStatus status) {
                List productsToChange = this.productDao.loadProductsByCategory(category);
                // 执行价格增加操作...
            }
        });
    }
}

容器配置

<beans>
    <bean id="myTxManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="mySessionFactory"/>
    </bean>

    <bean id="myProductService" class="product.ProductServiceImpl">
        <property name="transactionManager" ref="myTxManager"/>
        <property name="productDao" ref="myProductDao"/>
    </bean>
</beans>

事务管理策略

事务管理器选择

TransactionTemplateTransactionInterceptor 都将实际的事务处理委托给 PlatformTransactionManager 实例。对于 Hibernate 应用,可以是:

  1. HibernateTransactionManager(用于单个 Hibernate SessionFactory,在底层使用 ThreadLocal Session)
  2. JtaTransactionManager(委托给容器的 JTA 子系统)

你甚至可以自定义 PlatformTransactionManager 实现。

分布式事务

对于跨多个 Hibernate 会话工厂的分布式事务,你可以将 JtaTransactionManager 作为事务策略与多个 LocalSessionFactoryBean 定义结合使用。如果所有底层 JDBC 数据源都是事务性容器数据源,业务服务可以跨任意数量的 DAO 和会话工厂划分事务,只要它使用 JtaTransactionManager 作为策略。

缓存处理

HibernateTransactionManagerJtaTransactionManager 都允许使用 Hibernate 进行适当的 JVM 级缓存处理,而无需容器特定的事务管理器查找或 JCA 连接器(如果不使用 EJB 启动事务)。

容器管理与本地定义资源的比较

在容器管理的 JNDI SessionFactory 和本地定义的 SessionFactory 之间切换不需要更改任何应用程序代码。Spring 的事务支持不依赖于容器。当配置了除 JTA 之外的任何策略时,事务支持也可以在独立或测试环境中工作。特别是在典型的单数据库事务情况下,Spring 的单资源本地事务支持是 JTA 的轻量级且强大的替代方案。

spring-framework spring-projects/spring-framework: 一个基于 Java 的开源应用程序框架,用于构建企业级 Java 应用程序。适合用于构建各种企业级 Java 应用程序,可以实现高效的服务和管理。 spring-framework 项目地址: https://gitcode.com/gh_mirrors/sp/spring-framework

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

甄旖昀Melanie

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值