接上文 Hibernate命名策略:物理名称
参考文章 Hibernate 5 naming strategy examples
Spring Boot 配置项:
spring.jpa.hibernate.naming.implicit-strategy
该配置项有5个值,见下面的默认实现类和4个扩展实现类。
使用 PhysicalNamingStrategyStandardImpl 直接映射表名和字段名,不进行驼峰转换。
逻辑名称实现接口
org.hibernate.boot.model.naming.ImplicitNamingStrategy
默认实现类
org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
该实现类又扩展出以下几个实现类
org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl
org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl
org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
其中三个是由Hibernate实现,另一个由SpringBoot实现。
接下来看看他们之间的区别:
首先定义一个嵌入元素类,其中一个字段使用 Column 注解明确写明字段,另一个字段不使用注解。
@Embeddable
public class EmbeddableElement {
@Column(name = "quoted_field")
private String quotedField;
private String regularField;
// getter and setter
}
定义三个实体类:
基础表和链接表
@Entity
public class OwnedEntity {
@Id
private Long id;
@ElementCollection
@CollectionTable
Set<EmbeddableElement> ownedElements;
// getter and setter
}
一对多表
@Entity
@Table(name = "mainTable")
public class MainEntity {
@Id
private long id;
@ElementCollection
private Set<EmbeddableElement> mainElements;
@OneToMany(targetEntity = DependentEntity.class)
Set<DependentEntity> dependentEntities;
@OneToOne(targetEntity = OwnedEntity.class)
OwnedEntity ownedEntity;
// getter and setter
}
多对一表
@Entity
@Table(name = "dependentTable")
public class DependentEntity {
@Id
private long id;
@ManyToOne
MainEntity mainEntity;
@ElementCollection
@CollectionTable(name = "dependentElements")
Set<EmbeddableElement> dependentElements;
// getter and setter
}
首先看基类 ImplicitNamingStrategyJpaCompliantImpl,得到建表语句如下:
CREATE TABLE OwnedEntity (id BIGINT NOT NULL, PRIMARY KEY (id));
CREATE TABLE OwnedEntity_ownedElements (OwnedEntity_id BIGINT NOT NULL, quoted_field VARCHAR(255), regularField VARCHAR(255));
CREATE TABLE mainTable (id BIGINT NOT NULL, ownedEntity_id BIGINT, PRIMARY KEY (id));
CREATE TABLE MainEntity_mainElements (MainEntity_id BIGINT NOT NULL, quoted_field VARCHAR(255), regularField VARCHAR(255));
CREATE TABLE mainTable_dependentTable (MainEntity_id BIGINT NOT NULL, dependentEntities_id BIGINT NOT NULL, PRIMARY KEY (MainEntity_id, dependentEntities_id));
CREATE TABLE dependentTable (id BIGINT NOT NULL, mainEntity_id BIGINT, PRIMARY KEY (id));
CREATE TABLE dependentElements (DependentEntity_id BIGINT NOT NULL, quoted_field VARCHAR(255), regularField VARCHAR(255));
Hibernate 原始命名策略 ImplicitNamingStrategyLegacyHbmImpl (仅区别语句)
CREATE TABLE mainTable_dependentEntities (MainEntity_id BIGINT NOT NULL, dependentEntities BIGINT NOT NULL, PRIMARY KEY (MainEntity_id, dependentEntities));
区别在于关联表名后缀不是 Table 而是 Entities
JPA命名策略 ImplicitNamingStrategyLegacyJpaImpl (仅区别语句)
CREATE TABLE mainTable_mainElements (mainTable_id BIGINT NOT NULL, quoted_field VARCHAR(255), regularField VARCHAR(255));
区别在于关联表主名后缀不是 Entity,而是 Table
策略 ImplicitNamingStrategyComponentPathImpl (仅区别语句)
CREATE TABLE MainEntity_mainElements (MainEntity_id BIGINT NOT NULL, quoted_field VARCHAR(255), mainElements_regularField VARCHAR(255));
区别在于嵌入式关联表中没有明确写明字段名的字段会添加属性名称前缀
策略 SpringImplicitNamingStrategy (仅区别语句)
CREATE TABLE mainTable_dependentEntities (MainEntity_id BIGINT NOT NULL, dependentEntities_id BIGINT NOT NULL, PRIMARY KEY (MainEntity_id, dependentEntities_id));
与 Hibernate 原始命名策略的区别仅在于关联表的字段多加后缀 _id
strategy primaryTable joinTable collectTable ImplicitNamingStrategyJpaCompliantImpl Entity类名 Entity物理名称 + 引用Entity的物理名称 Entity类名 + 属性名称 ImplicitNamingStrategyLegacyHbmImpl – Entity物理名称 + 属性名称 – ImplicitNamingStrategyLegacyJpaImpl – – Entity物理名称 + 属性名称 ImplicitNamingStrategyComponentPathImpl – – Entity属性名称 + 属性名称 SpringImplicitNamingStrategy – Entity的物理名称 + 属性名称 –