Spring Framework中的JPA集成详解

Spring Framework中的JPA集成详解

spring-framework spring-framework 项目地址: https://gitcode.com/gh_mirrors/spr/spring-framework

概述

Spring Framework提供了对Java Persistence API(JPA)的全面支持,位于org.springframework.orm.jpa包下。这种支持方式类似于Spring对Hibernate的集成,同时能够感知底层实现以提供额外功能。

JPA在Spring环境中的三种配置方式

Spring JPA支持提供了三种配置JPA EntityManagerFactory的方法,应用程序通过它来获取实体管理器。

1. 使用LocalEntityManagerFactoryBean

这种方式仅适用于简单的部署环境,如独立应用程序和集成测试。

LocalEntityManagerFactoryBean创建一个适用于简单部署环境的EntityManagerFactory,其中应用程序仅使用JPA进行数据访问。它使用JPA的PersistenceProvider自动检测机制,大多数情况下只需指定持久化单元名称。

<bean id="myEmf" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
    <property name="persistenceUnitName" value="myPersistenceUnit"/>
</bean>

特点:

  • 不能引用现有的JDBC DataSource bean定义
  • 不支持全局事务
  • 持久化类的织入(字节码转换)是特定于提供商的
  • 通常需要在启动时指定特定的JVM代理
  • 仅适用于独立应用程序和测试环境

2. 从JNDI获取EntityManagerFactory

这种方式适用于部署到Jakarta EE服务器的情况。

<jee:jndi-lookup id="myEmf" jndi-name="persistence/myPersistenceUnit"/>

工作原理:

  • Jakarta EE服务器自动检测持久化单元
  • 整个持久化单元部署由Jakarta EE服务器处理
  • JDBC DataSource通过META-INF/persistence.xml文件中的JNDI位置定义
  • EntityManager事务与服务器的JTA子系统集成
  • Spring仅使用获取的EntityManagerFactory,通过依赖注入传递给应用对象

3. 使用LocalContainerEntityManagerFactoryBean

这种方式提供了Spring应用环境中完整的JPA能力,包括Tomcat等Web容器、独立应用程序和具有复杂持久化需求的集成测试。

<bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="someDataSource"/>
    <property name="loadTimeWeaver">
        <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
    </property>
</bean>

特点:

  • 提供对EntityManagerFactory配置的完全控制
  • 支持链接到现有的JDBC DataSource
  • 支持本地和全局事务
  • 需要运行时环境支持,如可织入的类加载器
  • 是功能最强大的JPA设置选项

多持久化单元处理

对于依赖多个持久化单元位置的应用程序,Spring提供了PersistenceUnitManager作为中央存储库。

<bean id="pum" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
    <property name="persistenceXmlLocations">
        <list>
            <value>org/springframework/orm/jpa/domain/persistence-multi.xml</value>
            <value>classpath:/my/package/**/custom-persistence.xml</value>
            <value>classpath*:META-INF/persistence.xml</value>
        </list>
    </property>
    <property name="dataSources">
        <map>
            <entry key="localDataSource" value-ref="local-db"/>
            <entry key="remoteDataSource" value-ref="remote-db"/>
        </map>
    </property>
    <property name="defaultDataSource" ref="remoteDataSource"/>
</bean>

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="persistenceUnitManager" ref="pum"/>
    <property name="persistenceUnitName" value="myCustomUnit"/>
</bean>

后台引导

LocalContainerEntityManagerFactoryBean支持通过bootstrapExecutor属性进行后台引导:

<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="bootstrapExecutor">
        <bean class="org.springframework.core.task.SimpleAsyncTaskExecutor"/>
    </property>
</bean>

特点:

  • 实际的JPA提供者引导被交给指定的执行器
  • 在应用程序引导线程并行运行
  • 暴露的EntityManagerFactory代理可以注入到其他应用程序组件中
  • 从6.2开始,JPA初始化在上下文刷新完成前强制执行

基于JPA实现DAO

虽然EntityManagerFactory实例是线程安全的,但EntityManager实例不是。注入的JPA EntityManager的行为类似于从应用服务器的JNDI环境中获取的EntityManager

使用@PersistenceUnit注解

public class ProductDaoImpl implements ProductDao {
    private EntityManagerFactory emf;

    @PersistenceUnit
    public void setEntityManagerFactory(EntityManagerFactory emf) {
        this.emf = emf;
    }

    public Collection loadProductsByCategory(String category) {
        EntityManager em = this.emf.createEntityManager();
        try {
            Query query = em.createQuery("from Product as p where p.category = ?1");
            query.setParameter(1, category);
            return query.getResultList();
        }
        finally {
            if (em != null) {
                em.close();
            }
        }
    }
}

使用@PersistenceContext注解

public class ProductDaoImpl implements ProductDao {
    @PersistenceContext
    private EntityManager em;

    public Collection loadProductsByCategory(String category) {
        Query query = em.createQuery("from Product as p where p.category = :category");
        query.setParameter("category", category);
        return query.getResultList();
    }
}

配置示例:

<beans>
    <!-- bean post-processor for JPA annotations -->
    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

    <bean id="myProductDao" class="product.ProductDaoImpl"/>
</beans>

或者使用更简洁的方式:

<beans>
    <!-- post-processors for all standard config annotations -->
    <context:annotation-config/>

    <bean id="myProductDao" class="product.ProductDaoImpl"/>
</beans>

总结

Spring Framework为JPA提供了全面的支持,从简单的独立应用到复杂的企业级应用都能找到合适的集成方式。开发者可以根据具体需求选择不同的配置方式,从简单的LocalEntityManagerFactoryBean到功能全面的LocalContainerEntityManagerFactoryBean。同时,Spring还简化了基于JPA的DAO实现,通过注解支持使代码更加简洁。理解这些不同的集成方式及其适用场景,将帮助开发者构建更高效、更易维护的数据访问层。

spring-framework spring-framework 项目地址: https://gitcode.com/gh_mirrors/spr/spring-framework

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

任轶眉Tracy

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

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

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

打赏作者

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

抵扣说明:

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

余额充值