Hibernate 5.1.x命名策略(向后兼容Hibernate4.x)

Hibernate 5.1.x naming Strategy (backward compatible with Hibernate 4.x)

我正在使用 Spring Boot 1.3.3.RELEASE。默认情况下 Spring 引导使用休眠版本 4.x。我正在尝试使用新的 Hibernate,即 5.1.0 FINAL(截至目前)。

我正在使用 Gradle 所以要覆盖 Hibernate 版本我添加了以下行

ext['hibernate.version']="5.1.0.Final"

按照

的步骤

我正在使用以下命名策略

spring.jpa.properties.hibernate.naming.implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl

spring.jpa.properties.hibernate.naming.physical_strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

我有一个实体class

@Entity
public class AppUser {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    @Length(max = 100)
    private String username;

    @NotNull
    @Length(max = 100)
    private String firstName;

    @NotNull
    @Length(max = 100)
    private String lastName;

    @Length(max = 100)
    private String middleName;

    @NotNull
    @Length(max=100)
    private String email;

    @NotNull
    @Length(max = 100)
    private String password;

    @NotNull
    private boolean enabled;

}

在 Hibernate 上 4.x 它执行查询

create table app_user (
        id bigint not null auto_increment,
        email varchar(100) not null,
        enabled bit not null,
        first_name varchar(100) not null,
        last_name varchar(100) not null,
        middle_name varchar(100),
        password varchar(100) not null,
        username varchar(100) not null,
        primary key (id)
    )

在 5.x 它执行了查询

create table AppUser (
        id bigint not null auto_increment,
        email varchar(100) not null,
        enabled bit not null,
        firstName varchar(100) not null,
        lastName varchar(100) not null,
        middleName varchar(100),
        password varchar(100) not null,
        username varchar(100) not null,
        primary key (id)
    )

如何设置命名策略,使 Hibernate 在 Table 名称和列名称

上使用 5.x 下划线(如 4.x)

首先,你不需要 org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

因为它什么都不做,被 Hibernate 作为默认值使用。

Hibernate 5 没有您想要的策略。所有策略都符合 JPA(生成类似 AppUser 的名称)。所以你需要自己实现。

例如物理命名策略

public class UnderscorePhysicalStartegy extends PhysicalNamingStrategyStandardImpl {

    @Override
    public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context) {
        return context.getIdentifierHelper()
                .toIdentifier(NamingStrategyUtils.classToName(name.getText()));
    }

}

它使用NamingStrategyUtils

请记住,如果您指定了明确的名称

@Entity
@Table(name = "AppUser")
public class AppUser {

}

无论如何你都会有一个 table 名字 app_user。如果您不希望出现这种行为,请使用隐式命名策略。

我做了一些关于命名策略的研究工作。您可以参考 Hibernate5NamingStrategy,它会生成 table 和带有您需要的下划线的列名称以及约束名称(唯一的外键)。

此 class 用于生成名称:HibernateNamingStrategy

使用方法Hibernate5NamingStrategy

可以使用StrategyOptions配置命名策略。

例如,要使用不带前缀的策略(如 f_):

StrategyOptions options = StrategyOptions.builder().withoutPrefixes().build();
Hibernate5NamingStrategy strategy = new Hibernate5NamingStrategy(options);

其他示例:Hibernate 5 Implicit Naming Strategy

除此之外,ImprovedNamingStrategy for Hibernate 5 可用于模拟 Hibernate 4 ImprovedNamingStrategy 的行为。

我正在提供我的分析供任何人使用:

如果您在实体 classes 中提供 @Table@Column 注释提供下划线,即 user_id 即@Column(name="user_id"),它将占用列命名为 user_id;如果您将其作为用户标识提供,那么如果您不使用任何策略或隐式策略(特别是 spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl),它将变为 user_id。所以,如果你想要一个实体属性名称更改为带有下划线和小写字母的策略,即从 userId 到 user_id,你应该使用隐式或无策略(实际上使用隐式策略)。

如果您不希望您的命名策略在列名称或 class 名称中添加下划线,那么您需要使用的策略如下所示:spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl。您在注释 @Table@Column 的 名称属性中提供的内容将保持原样。

如果您不想提供注释并希望手动处理 table 名称和列名称,您应该扩展 class org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl 并覆盖所需的方法。如果您仍对此处的某些情况使用注解,请记住重写的方法将应用于这些注解中写入的名称。 spring.jpa.hibernate.naming.physical-strategy=example.CustomStrategy