这是我参与11月更文挑战的第 13 天,活动详情查看:2021最后一次更文挑战
本篇文 Spring Data JPA 属性的第二篇,第一篇见 Spring Data JPA-属性详解 JdbcProperties 和 DataSourceProperties;第一篇中主要是 jdbc 的配置,本篇主要是 jpa 自己的配置;在 spring 代码中,Spring Data JPA 对应的配置在 orm.jpa
package 下,包括两个配置类:JpaProperties
和 HibernateProperties
。
JpaProperties
: prefix 是spring.jpa.*
HibernateProperties
: prefix 是spring.jpa.hibernate.*
JpaProperties
这个配置主要服务于 Spring 创建的 JPA EntityManagerFactory;具体属性配置如下:
java @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 可以看到所有的数据库枚举类型,如下图所示:
一般情况下,我们不需要明确指定类型,默认为 dafault。
mappingResources
一般不会使用,在之前基于 xml 配置时,会使用 mappingResources 属性定义多个 orm.xml,大致如下:
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,详细可以参考:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto.data-initialization.using-jpa
- 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
java if (isGenerateDdl()) { jpaProperties.put(AvailableSettings.HBM2DDL_AUTO, "update"); }
showSql
开启时,执行的 sql 会通过日志输出出来,一般多用于测试场景
HibernateProperties
java @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,我们期望它的逻辑名称为 phonenumer,而在数据库中实际的物理名称为 pnum,则:
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
取决于newgeneratormappings参数的配置
引用
- https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto.data-initialization.using-jpa
- https://zhuanlan.zhihu.com/p/64844767
- https://blog.csdn.net/WZH577/article/details/99698187