JPA(Java Persistence API)是Java EE5规范之一,是一个orm规范,由厂商来实现该规范。目前有hibernate,OpenJPA,TopLink和EclipseJPA等实现。
以下介绍Spring JPA 3种配置方式:
- LocalEntityManagerFactoryBean:
适用于那些仅使用JPA进行数据访问的项目。该FactoryBean根据 JPA PersistenceProvider自动检测配置文件进行工作,一般从“META-INF/persistence.xml”读取配置信息。这种方式最简单,但是此中配置方式不能设置Spring中定义的DataSource,且不支持Spring管理的全局事务。不建议使用此方式。这种方法实际上只适用于独立的应用程序和测试环境(这正是JPA规范设计它的原因)。
在Spring中的配置:
<bean id=”entityManagerFactory” class=”org.springframework.orm.jpa.LocalEntityManagerFactoryBean”>
<property name=”persistenceUnitName” value=”persistenceUnit”/>
</bean>
- 从JNDI中获取EntityManagerFactory
用于从Java EE服务器中获取指定的EntityManagerFactory,这种方式在Spring事务管理时一般要使用JTA事务管理。
Spring中的配置:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd">
<jee:jndi-lookup id="entityManagerFactory" jndi-name="persistence/persistenceUnit"/>
</beans>
在标准的Java EE 5启动过程中,Java EE服务器自动检测持久化单元(例如应用程序文件包中的META-INF/persistence.xml) ,以及Java EE部署描述符中定义给那些持久化单元命名上下文位置的环境的persistence-unit-ref项(例如web.xml)。
在这种情况下,整个持久化单元部署,包括持久化类的织入(字码码转换)都取决于Java EE服务器。 JDBC DataSource 通过在META-INF/persistence.xml 文件中的JNDI位置进行定义;EntityManager事务与服务器的JTA子系统整合。Spring仅仅用获得的 EntityManagerFactory, 通过依赖注入将它传递给应用程序对象,并为它管理事务(一般通过JtaTransactionManager)。
注意,如果在同一个应用程序中使用了多个持久化单元,JNDI获取的这种持久化单元的bean名称 应该与应用程序用来引用它们的持久化单元名称相符(例如@PersistenceUnit和 @PersistenceContext注解)。
在部署到Java EE 5服务器时使用该方法。关于如何将自定义JPA提供者部署到服务器,以及允许使用服务器提供的缺省提供者之外的JPA提供者,请查看服务器文档的相关说明。
- LocalContainerEntityManagerFactoryBean
适用于所有环境的FactoryBean,能全面控制EntityManagerFactory配置,非常适合那种需要细粒度定制的环境。原生的jpa的配置信息是必须放在META-INF目录下面的,并且名字必须叫做persistence.xml,这个叫做persistence-unit,就叫做持久化单元。
以下配置采用Spring+JPA整合配置,没在单独的persistence.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:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd ">
<!--i18n国际化配置-->
<bean id="messageSource"
class="org.springframework.context.support.ResourceBundleMessageSource"
p:basename="Messages">
</bean>
<!--@Controller, @Service, @Configuration />-->
<context:component-scan base-package="com.XXX.service" />
<mvc:resources mapping="/resources/**" location="/resources/" />
<mvc:default-servlet-handler/>
<mvc:annotation-driven />
<context:annotation-config />
<!-- 启动对@AspectJ注解的支持:使用cglib进行动态代理 -->
<aop:aspectj-autoproxy proxy-target-class="true" />
<!-- 数据库配置 -->
<!-- 数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="driverClassName" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${userName}" />
<property name="password" value="${password}" />
<property name="initialSize" value="${druid.initialSize}" />
<property name="maxActive" value="${druid.maxActive}" />
<property name="maxIdle" value="${druid.maxIdle}" />
<property name="minIdle" value="${druid.minIdle}" />
<property name="maxWait" value="${druid.maxWait}" />
<property name="removeAbandoned" value="${druid.removeAbandoned}" />
<property name="removeAbandonedTimeout" value="${druid.removeAbandonedTimeout}" />
<property name="timeBetweenEvictionRunsMillis" value="${druid.timeBetweenEvictionRunsMillis}" />
<property name="minEvictableIdleTimeMillis" value="${druid.minEvictableIdleTimeMillis}" />
<property name="validationQuery" value="${druid.validationQuery}" />
<property name="testWhileIdle" value="${druid.testWhileIdle}" />
<property name="testOnBorrow" value="${druid.testOnBorrow}" />
<property name="testOnReturn" value="${druid.testOnReturn}" />
<property name="poolPreparedStatements" value="${druid.poolPreparedStatements}" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="${druid.maxPoolPreparedStatementPerConnectionSize}" />
<property name="filters" value="${druid.filters}" />
</bean>
<!--JPA 配置 start-->
<!-- 实体管理器-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!-- 指定数据源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 指定Entity实体类包路径 -->
<property name="packagesToScan" >
<array>
<value>com.XXX.entity</value>
</array>
</property>
<!-- 指定Jpa持久化实现厂商类-->
<property name="jpaVendorAdapter">
<bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="false" />
<property name="database" value="MYSQL" />
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
<!-- <property name="showSql" value="true" /> -->
</bean>
</property>
<!-- 指定JPA属性-->
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.query.substitutions" value="true 1, false 0" />
<entry key="hibernate.default_batch_fetch_size" value="16" />
<entry key="hibernate.max_fetch_depth" value="2" />
<entry key="hibernate.generate_statistics" value="true" />
<entry key="hibernate.bytecode.use_reflection_optimizer" value="true" />
<entry key="hibernate.cache.use_second_level_cache" value="false" />
<entry key="hibernate.cache.use_query_cache" value="false" />
</map>
</property>
</bean>
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<!-- 支持注解方式声明式事务 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
<!-- dao包-->
<jpa:repositories base-package="com.XXX.dao" repository-impl-postfix="Impl" transaction-manager-ref="transactionManager" entity-manager-factory-ref="entityManagerFactory"/>
<!-- 事务 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*" />
<tx:method name="get*" read-only="true" />
<tx:method name="find*" read-only="true" />
<tx:method name="select*" read-only="true" />
<tx:method name="delete*" propagation="REQUIRED" />
<tx:method name="update*" propagation="REQUIRED" />
<tx:method name="add*" propagation="REQUIRED" />
<tx:method name="insert*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
<!-- 事务入口 -->
<aop:config>
<aop:pointcut id="allServiceMethod" expression="execution(* your service implements package.*.*(..))" />
<aop:advisor pointcut-ref="allServiceMethod" advice-ref="txAdvice" />
</aop:config>
<!--JPA 配置 end-->
<!--view配置-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
该bean有以下属性:
dataSource:用于指定Spring定义的数据源。
persistenceProvider:用于指定持久化实现厂商类,如hibernate为:org.hibernate.ejb.HibernateProvider 类。
jpaVendorAdapter:用于设置JPA实现厂商的特定属性,如设置hibernate的是否自动生成DDL的属性generateDdl,这些属性是厂商特定的,因此最好在这里设置。
目前spring提供HibernateJpaVendorAdapter,OpenJpaVendorAdapter,EclipseJpaVendorAdapter,TopLinkJpaVenderAdapter四个实现。
hibernate.show_sql =true:表示在日志系统debug级别下将打印所有生成的SQL。
其中最主要的属性是“database”,用来指定使用的数据库类型。目前支持以下数据库:DB2,DERBY,H2,HSQL,INFORMIX,MYSQL,ORACLE,POSTGRESQL,SQL_SERVER,SYBASE。
jpaProperties和jpaPropertyMap:指定JPA属性;对于jpaProperties设置的属性自动会放进jpaPropertyMap中;
jpaDialect:用于指定一些高级特性,如事务管理等。目前Spring提供HibernateJpaDialect,OpenJpaDialect,EclipseJpaDialect,TopLinkJpaDialect和DefaultJpaDialect实现。注意DefaultJpaDialect不提供任何功能,因此在使用特定实现厂商的JPA实现时需要指定jpaDialect实现,如使用hibernate就使用HibernateJpaDialect。当指定jpaVendorAdapter属性时可以不指定jpaDialect,会自动设置相应的JpaDialect实现;
jpaVendorAdapter:指定实现厂商专用特性,即generateDdl= false表示不自动生成DDL,database= HSQL表示使用hsqldb数据库;