Spring Framework中的JPA集成详解
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 项目地址: https://gitcode.com/gh_mirrors/spr/spring-framework
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考