Contents

Spring JPA指南

1.概述

本教程展示了如何使用 Hibernate 作为持久性提供程序来设置带有 JPA 的 Spring。 有关使用基于 Java 的配置和项目的基本 Maven pom 设置 Spring 上下文的分步介绍,请参阅本文 。 我们将从在 Spring Boot 项目中设置 JPA 开始。如果我们有一个标准的 Spring 项目,那么我们将研究我们需要的完整配置。

2. Spring Boot 中的 JPA

Spring Boot 项目旨在使创建 Spring 应用程序变得更快、更容易。这是通过使用启动器和自动配置各种 Spring 功能(其中包括 JPA)来完成的。

2.1. Maven 依赖项

要在 Spring Boot 应用程序中启用 JPA,我们需要spring-boot-starterspring-boot-starter-data-jpa 依赖项:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>2.2.6.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    <version>2.2.6.RELEASE</version>
</dependency>

spring-boot-starter包含 Spring JPA 必要的自动配置。此外,spring-boot-starter-jpa项目引用了所有必要的依赖项,例如hibernate-core

2.2. 配置

Spring Boot 将Hibernate配置为默认的 JPA 提供程序,因此不再需要定义entityManagerFactory bean,除非我们想自定义它。

Spring Boot 还可以根据我们使用的数据库自动配置数据源bean。对于H2HSQLDBApache Derby类型的内存数据库,如果类路径上存在相应的数据库依赖项,Boot 会自动配置DataSource

例如,如果我们想在 Spring Boot JPA 应用程序中使用内存中的H2数据库,我们只需要在pom.xml文件中添加h2 依赖:

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.200</version>
</dependency>

这样,我们不需要定义dataSource bean,但如果我们想自定义它,我们可以。 如果我们想将 JPA 与MySQL数据库一起使用,我们需要mysql-connector-java依赖项。我们还需要定义dataSource配置。

我们可以在*@Configuration*类中或使用标准的 Spring Boot 属性来执行此操作。 Java 配置看起来与标准 Spring 项目中的配置相同:

@Bean
public DataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    dataSource.setUsername("mysqluser");
    dataSource.setPassword("mysqlpass");
    dataSource.setUrl(
      "jdbc:mysql://localhost:3306/myDb?createDatabaseIfNotExist=true");
    return dataSource;
}

要使用属性文件配置数据源,我们必须设置以spring.datasource为前缀的属性

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=mysqluser
spring.datasource.password=mysqlpass
spring.datasource.url=
  jdbc:mysql://localhost:3306/myDb?createDatabaseIfNotExist=true

Spring Boot 会根据这些属性自动配置一个数据源。

同样在 Spring Boot 1 中,默认连接池是Tomcat ,但在 Spring Boot 2 中已更改为HikariCP

如我们所见,如果我们使用 Spring Boot,基本的 JPA 配置相当简单。

然而,**如果我们有一个标准的 Spring 项目,我们需要更明确的配置,使用 Java 或 XML。**这就是我们将在下一节中关注的内容。

3. 在非引导项目中使用 Java 的 JPA Spring 配置

要在 Spring 项目中使用 JPA,我们需要设置EntityManager

这是配置的主要部分,我们可以通过 Spring 工厂 bean 来完成。这可以是更简单的LocalEntityManagerFactoryBean更灵活的LocalContainerEntityManagerFactoryBean

让我们看看如何使用后一个选项:

@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig{
   @Bean
   public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
      LocalContainerEntityManagerFactoryBean em
        = new LocalContainerEntityManagerFactoryBean();
      em.setDataSource(dataSource());
      em.setPackagesToScan(new String[] { "com.blogdemo.persistence.model" });
      JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
      em.setJpaVendorAdapter(vendorAdapter);
      em.setJpaProperties(additionalProperties());
      return em;
   }
   // ...
}

我们还需要显式定义我们在上面使用的DataSource bean :

@Bean
public DataSource dataSource(){
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql://localhost:3306/spring_jpa");
    dataSource.setUsername( "tutorialuser" );
    dataSource.setPassword( "tutorialmy5ql" );
    return dataSource;
}

配置的最后一部分是额外的 Hibernate 属性以及TransactionManagerexceptionTranslation beans:

@Bean
public PlatformTransactionManager transactionManager() {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
    return transactionManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation(){
    return new PersistenceExceptionTranslationPostProcessor();
}
Properties additionalProperties() {
    Properties properties = new Properties();
    properties.setProperty("hibernate.hbm2ddl.auto", "create-drop");
    properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
    return properties;
}

4. 使用 XML 的 JPA Spring 配置

接下来,让我们看看使用 XML 的相同 Spring 配置:

<bean id="myEmf"
  class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="com.blogdemo.persistence.model" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
    </property>
    <property name="jpaProperties">
        <props>
            <prop key="hibernate.hbm2ddl.auto">create-drop</prop>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
        </props>
    </property>
</bean>
<bean id="dataSource"
  class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.cj.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/spring_jpa" />
    <property name="username" value="tutorialuser" />
    <property name="password" value="tutorialmy5ql" />
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="myEmf" />
</bean>
<tx:annotation-driven />
<bean id="persistenceExceptionTranslationPostProcessor" class=
  "org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

XML 和新的基于 Java 的配置之间存在相对较小的差异。即,在 XML 中,对另一个 bean 的引用可以指向该 bean 或该 bean 的 bean 工厂。

但在 Java 中,由于类型不同,编译器不允许,因此首先从其 bean 工厂中检索EntityManagerFactory ,然后传递给事务管理器:

transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());

5. 完全无 XML

通常,JPA 通过META-INF/persistence.xml文件定义一个持久化单元。**从 Spring 3.1 开始,不再需要persistence.xml 。*LocalContainerEntityManagerFactoryBean现在支持packagesToScan属性,可以在其中指定要扫描@Entity*类的包。

该文件是我们需要删除的最后一段 XML。我们现在可以在没有 XML 的情况下完全设置 JPA。

我们通常会在persistence.xml文件中指定 JPA 属性。 或者,我们可以将属性直接添加到实体管理器工厂 bean:

factoryBean.setJpaProperties(this.additionalProperties());

作为旁注,如果 Hibernate 是持久性提供者,这也将是指定 Hibernate 特定属性的方式。

6.Maven配置

除了 Spring Core 和持久性依赖项——在Spring with Maven 教程 中有详细介绍——我们还需要在项目中定义 JPA 和 Hibernate 以及 MySQL 连接器:

<dependency>
   <groupId>org.hibernate</groupId>
   <artifactId>hibernate-core</artifactId>
   <version>5.2.17.Final</version>
   <scope>runtime</scope>
</dependency>
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>8.0.19</version>
   <scope>runtime</scope>
</dependency>

请注意,此处包含 MySQL 依赖项作为示例。我们需要一个驱动程序来配置数据源,但是任何支持 Hibernate 的数据库都可以。