A Guide to JPA with Spring


1.概述

本教程介绍如何使用Hibernate作为持久性提供程序来设置Spring with JPA。

有关使用基于Java的配置和项目的基本Maven pom设置Spring上下文的分步介绍,请参阅此文章。

我们首先在Spring Boot项目中设置JPA,然后如果我们有一个标准的Spring项目,我们将研究我们需要的完整配置。

注:这是一个关于使用Spring 4设置Hibernate 4的视频(我建议以完整的1080p观看):

2. JPA in Spring Boot

Spring Boot项目旨在更快,更轻松地创建Spring应用程序。这是通过使用启动器和自动配置来实现各种Spring功能,其中包括JPA。

2.1。Maven Dependencies

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

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

该弹簧引导启动包含春JPA必要的自动配置。此外,spring-boot-starter-jpa项目引用了所有必需的依赖项,例如hibernate-entitymanager。

2.2.Configuration

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

Spring Boot还可以自动配置dataSource bean,具体取决于所使用的数据库。对于类型为H2,HSQLDB和Apache Derby的内存数据库,如果类路径上存在相应的数据库依赖关系,Boot会自动配置DataSource。

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

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.195</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。

您可以在GitHub项目中找到更多在Spring Boot中配置JPA的示例。

我们可以看到,如果我们使用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[] { "org.baeldung.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属性以及TransactionManager和exceptionTranslation bean:

@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory emf) {
    JpaTransactionManager transactionManager = new JpaTransactionManager();
    transactionManager.setEntityManagerFactory(emf);

    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="org.baeldung.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中配置Spring的方式与基于Java的新配置之间存在相对较小的差异 - 在XML中,对另一个bean的引用可以指向bean或该bean的bean工厂。

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

txManager.setEntityManagerFactory(this.entityManagerFactoryBean()。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-entitymanager</artifactId>
   <version>5.2.17.Final</version>
   <scope>runtime</scope>
</dependency>

<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>6.0.6</version>
   <scope>runtime</scope>
</dependency>

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