JPA与spring整合
1. 三种整合方式:
LocalEntityManagerFactoryBean
:仅适用于使用JPA进行数据库访问的项目,该配置将根据PersistenceProvider自动检测配置文件进行工作,但是不能设置spring中定义的DataSource,且不支持Spring管理的全局事务(PASS掉)- 从JNDI获取:用于从JavaEE服务器只懂得EntityManagerFactory,这种的事务管理要使用JTA
LocalContainerEntityManagerFactoryBean
:适用于所有环境的FatoryBean,能全面控制EntityManagerFactory配置(推荐)
2. 配置
-
配置ApplicationContext.xml
<?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:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <context:property-placeholder location="classpath:database.properties"/> <context:component-scan base-package="cn.ann"/> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${mysql.driver}"/> <property name="jdbcUrl" value="${mysql.url}"/> <property name="user" value="${mysql.username}"/> <property name="password" value="${mysql.password}"/> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> <!-- 配置JPA提供商适配器,可以通过内部 bean 的方式来配置 --> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/> </property> <!-- 配置实体类所在的包 --> <property name="packagesToScan" value="cn.ann.entity"/> <!-- 配置JPA基本属性,例如JPA实现产品的属性 --> <property name="jpaProperties"> <props> <!-- 配置orm基本属性 --> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> <!-- 二级缓存相关 --> <prop key="hibernate.cache.use_second_level_cache">true</prop> <prop key="hibernate.cache.region.factory_class"> org.hibernate.cache.ehcache.EhCacheRegionFactory </prop> <prop key="hibernate.cache.use_query_cache">true</prop> </props> </property> </bean> <!-- 配置事务 --> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <tx:advice id="txAdvice"> <tx:attributes> <tx:method name="*"/> <tx:method name="get*" propagation="SUPPORTS" read-only="true"/> <tx:method name="find*" propagation="SUPPORTS" read-only="true"/> </tx:attributes> </tx:advice> <!-- 配置事务到切面 --> <aop:config> <aop:pointcut id="txPc" expression="execution(* cn.ann.service..*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPc"/> </aop:config> </beans>
-
其他配置文件
-
database.properties
mysql.driver=com.mysql.cj.jdbc.Driver mysql.url=jdbc:mysql://localhost:3307/jpa_test?serverTimezone=Asia/Shanghai mysql.username=root mysql.password=password
-
ehcache.xml
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd" updateCheck="false"> <diskStore path="D:\\temp"/> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"/> </ehcache>
-
log4j.properties
log4j.rootLogger=ERROR, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
-
3. 测试
-
通过 @PersistenceContext 可以获取当前事务绑定的EntityManager对象
@PersistenceContext private EntityManager entityManager;
-
测试
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:applicationContext.xml") public class Demo { @Resource(name = "personService") private PersonService personService; @Test public void test01() { Person person = new Person(); person.setName("p1"); personService.save(person); } }
本文代码:点击此处