三种整合方式

LocalEntityManagerFactoryBean:适用于那些仅使用 JPA 进行数据访问的项目,
该 FactoryBean 将根据JPA PersistenceProvider 自动检测配置文件进行工作,
一般从“META-INF/persistence.xml”读取配置信息,这种方式最简单,但不能设置
Spring 中定义的DataSource,且不支持 Spring 管理的全局事务
从JNDI中获取:用于从 Java EE 服务器获取指定的EntityManagerFactory,
这种方式在进行 Spring 事务管理时一般要使用 JTA 事务管理
LocalContainerEntityManagerFactoryBean:适用于所有环境的 FactoryBean,
能全面控制 EntityManagerFactory 配置,如指定 Spring 定义的 DataSource 等等。

整合步骤

1.导入相关依赖

08 Spring整合JPA - 图1

2.创建配置文件

db.properties

  1. jdbc.user=root
  2. jdbc.password=123456
  3. jdbc.driverClass=com.mysql.jdbc.Driver
  4. jdbc.jdbcUrl=jdbc:mysql:///jpa

applicationContext.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:context="http://www.springframework.org/schema/context"
  5. xmlns:tx="http://www.springframework.org/schema/tx"
  6. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
  8. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
  9. <!-- 配置自动扫描的包 -->
  10. <context:component-scan base-package="cn.carven.jpa"></context:component-scan>
  11. <!-- 配置 C3P0 数据源 -->
  12. <context:property-placeholder location="classpath:db.properties"/>
  13. <bean id="dataSource"
  14. class="com.mchange.v2.c3p0.ComboPooledDataSource">
  15. <property name="user" value="${jdbc.user}"></property>
  16. <property name="password" value="${jdbc.password}"></property>
  17. <property name="driverClass" value="${jdbc.driverClass}"></property>
  18. <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
  19. <!-- 配置其他属性 -->
  20. </bean>
  21. <!-- 配置 EntityManagerFactory -->
  22. <bean id="entityManagerFactory"
  23. class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
  24. <property name="dataSource" ref="dataSource"></property>
  25. <!-- 配置 JPA 提供商的适配器. 可以通过内部 bean 的方式来配置 -->
  26. <property name="jpaVendorAdapter">
  27. <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
  28. </property>
  29. <!-- 配置实体类所在的包 -->
  30. <property name="packagesToScan" value="cn.carven.jpa.spring.entities"></property>
  31. <!-- 配置 JPA 的基本属性. 例如 JPA 实现产品的属性 -->
  32. <property name="jpaProperties">
  33. <props>
  34. <prop key="hibernate.show_sql">true</prop>
  35. <prop key="hibernate.format_sql">true</prop>
  36. <prop key="hibernate.hbm2ddl.auto">update</prop>
  37. </props>
  38. </property>
  39. </bean>
  40. <!-- 配置 JPA 使用的事务管理器 -->
  41. <bean id="transactionManager"
  42. class="org.springframework.orm.jpa.JpaTransactionManager">
  43. <property name="entityManagerFactory" ref="entityManagerFactory"></property>
  44. </bean>
  45. <!-- 配置支持基于注解是事务配置 -->
  46. <tx:annotation-driven transaction-manager="transactionManager"/>
  47. </beans>

3. 实体类

  1. @Table(name="JPA_PERSONS")
  2. @Entity
  3. public class Person {
  4. private Integer id;
  5. private String lastName;
  6. private String email;
  7. private int age;
  8. @GeneratedValue
  9. @Id
  10. public Integer getId() {
  11. return id;
  12. }
  13. public void setId(Integer id) {
  14. this.id = id;
  15. }
  16. @Column(name="LAST_NAME")
  17. public String getLastName() {
  18. return lastName;
  19. }
  20. public void setLastName(String lastName) {
  21. this.lastName = lastName;
  22. }
  23. public String getEmail() {
  24. return email;
  25. }
  26. public void setEmail(String email) {
  27. this.email = email;
  28. }
  29. public int getAge() {
  30. return age;
  31. }
  32. public void setAge(int age) {
  33. this.age = age;
  34. }
  35. }

4.dao

  1. @Repository
  2. public class PersonDao {
  3. //通过 @PersistenceContext 获取到和当前事务关联的 EntityManager 对象
  4. @PersistenceContext
  5. private EntityManager entityManager;
  6. public void save(Person person){
  7. entityManager.persist(person);
  8. }
  9. }

5.service

  1. @Service
  2. public class PersonService {
  3. @Autowired
  4. private PersonDao personDao;
  5. // 事务注解
  6. @Transactional
  7. public void savePersons(Person p1, Person p2){
  8. personDao.save(p1);
  9. // int i = 10 / 0;
  10. personDao.save(p2);
  11. }
  12. }

6.测试类

  1. public class JPATest {
  2. private ApplicationContext ctx = null;
  3. private PersonService personService = null;
  4. {
  5. ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
  6. personService = ctx.getBean(PersonService.class);
  7. }
  8. @Test
  9. public void testPersonService(){
  10. Person p1 = new Person();
  11. p1.setAge(11);
  12. p1.setEmail("aa@163.com");
  13. p1.setLastName("AA");
  14. Person p2 = new Person();
  15. p2.setAge(12);
  16. p2.setEmail("bb@163.com");
  17. p2.setLastName("BB");
  18. System.out.println(personService.getClass().getName());
  19. personService.savePersons(p1, p2);
  20. }
  21. @Test
  22. public void testDataSource() throws SQLException {
  23. DataSource dataSource = ctx.getBean(DataSource.class);
  24. System.out.println(dataSource.getConnection());
  25. }
  26. }