Spring Data JPA-属性详解 JpaProperties 和 HibernateProperties

3,195 阅读3分钟

这是我参与11月更文挑战的第 13 天,活动详情查看:2021最后一次更文挑战

本篇文 Spring Data JPA 属性的第二篇,第一篇见 Spring Data JPA-属性详解 JdbcProperties 和 DataSourceProperties;第一篇中主要是 jdbc 的配置,本篇主要是 jpa 自己的配置;在 spring 代码中,Spring Data JPA 对应的配置在 orm.jpa package 下,包括两个配置类:JpaPropertiesHibernateProperties

  • JpaProperties: prefix 是 spring.jpa.*
  • HibernateProperties: prefix 是 spring.jpa.hibernate.*

JpaProperties

这个配置主要服务于 Spring 创建的 JPA EntityManagerFactory;具体属性配置如下:

@ConfigurationProperties(prefix = "spring.jpa")
public class JpaProperties {
   private Map<String, String> properties = new HashMap<>();
   private final List<String> mappingResources = new ArrayList<>();
   private String databasePlatform;
   // 要操作的目标数据库,默认自动检测。也可以使用“databasePlatform”属性进行设置。
   private Database database;
   // 是否在启动时初始化 schema
   private boolean generateDdl = false;
   // 是否开启打印 sql 语句,这个在测试时非常常见
   private boolean showSql = false;
   // 用于决定是否注册 OpenEntityManagerInViewInterceptor,它会一个请求线程绑定一个JPA EntityManager
   private Boolean openInView;

database

database 属性,通过 idea 可以看到所有的数据库枚举类型,如下图所示:

image.png

一般情况下,我们不需要明确指定类型,默认为 dafault。

mappingResources

一般不会使用,在之前基于 xml 配置时,会使用 mappingResources 属性定义多个 orm.xml,大致如下:

<property name="mappingResources">
    <list>
        <value>sql/user.xml</value>
        <value>Sql/user1.xml</value>
    </list>
</property>

generateDdl

当开启 ddl 时,就可以通过定义的实体,自动生成创建 Schema 的 DDL,它们将会在应用启动时初始化数据库;在一定程度上讲,就是你不需要与SQL打交道了。

这里要区别对待下 spring data jpa 的 spring.jpa.generateDdl 和 Hibernate 的spring.jpa.hibernate.ddl-auto,详细可以参考:docs.spring.io/spring-boot…

  • spring.jpa.generate-ddl 是更高层次上的抽象,他和具体的JPA实现无关
  • spring.jpa.hibernate.ddl-auto 是和 Hibernate 相关的更具体的设置。前者会影响到后者,最好不要两者混用,容易混淆。在实践中,直接用后者就行。

spring.jpa.hibernate.ddl-auto 可选有这几种:create, create-drop, none, update, validate等;

  • create 表示每次应用启动的时候,都会将之前的表全部drop掉,重新根据实体类生成一遍。
  • create-drop 在 create 的基础上,在应用关闭的时候还会drop一次。
  • update 可能是比较常用的,每次启动的时候会看看实体类有什么变化,然后看需不需要更改表结构。
  • validate 不会对表进行更改,但是会看看他和实体类是否对应
  • none 什么都不做

spring.jpa.generate-ddl 配置为 true 时,默认是 update,代码见:org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter#buildJpaPropertyMap

if (isGenerateDdl()) {
   jpaProperties.put(AvailableSettings.HBM2DDL_AUTO, "update");
}

showSql

开启时,执行的 sql 会通过日志输出出来,一般多用于测试场景

image.png

HibernateProperties

@ConfigurationProperties("spring.jpa.hibernate")
public class HibernateProperties {
   private final Naming naming = new Naming();
   private String ddlAuto;
   private Boolean useNewIdGeneratorMappings;

naming

表示命名策略,有两种可选模式(hibernate 5 之后版本才提供的):

  • implicitStrategy:负责模型对象层次的处理,将对象模型处理为逻辑名称。
  • physical-strategy: 负责映射成真实的数据名称的处理,将上述的逻辑名称处理为物理名称

当没有使用 @Table 和 @Column 注解时,implicit-strategy 配置项才会被使用,当对象模型中已经指定时,implicit-strategy 并不会起作用。physical-strategy 一定会被应用,与对象模型中是否显式地指定列名或者已经被隐式决定无关。

例如 Entity 中有个字段名为 phoneNumber,我们期望它的逻辑名称为 phone_numer,而在数据库中实际的物理名称为 p_num,则:

phoneNumber ----implicitStrategy---> phone_number
phone_number ----physicalStrategy---> p_num

useNewIdGeneratorMappings

开启时意味着,可以为主键指定 javax.persistence.GenerationType 中的 4 种类型 AUTO, TABLE,IDENTITY SEQUENCE 生成策略。

  • SEQUENCE

采用数据库提供的 sequence 机制生成主键,需要数据库支持 sequence。如 oralce、DB、SAP DB、PostgerSQL、McKoi 中的 sequence。MySQL 这种不支持 sequence 的数据库则不行(可以使用 identity)。

  • TABLE

使用一个特定的数据库表格来保存主键。(用的比较少)

  • IDENTITY

主键由数据库自动生成

  • AUTO

取决于new_generator_mappings参数的配置

引用