JPA与spring整合

1. 三种整合方式:

  1. LocalEntityManagerFactoryBean:仅适用于使用JPA进行数据库访问的项目,该配置将根据PersistenceProvider自动检测配置文件进行工作,但是不能设置spring中定义的DataSource,且不支持Spring管理的全局事务(PASS掉
  2. 从JNDI获取:用于从JavaEE服务器只懂得EntityManagerFactory,这种的事务管理要使用JTA
  3. LocalContainerEntityManagerFactoryBean:适用于所有环境的FatoryBean,能全面控制EntityManagerFactory配置(推荐

2. 配置

  1. 配置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>
    
  2. 其他配置文件

    • 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. 测试

  1. 通过 @PersistenceContext 可以获取当前事务绑定的EntityManager对象

    @PersistenceContext
    private EntityManager entityManager;
    
  2. 测试

    @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);
        }
    }
    

本文代码:点击此处

posted @ 2019-12-11 14:09  _ann  阅读(177)  评论(0编辑  收藏  举报