Hibernate 5 Naming Strategy Configuration – Hibernate 5 命名策略配置

最后修改: 2018年 9月 19日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

Hibernate 5 provides two different naming strategies for use with Hibernate entities: an Implicit Naming Strategy and a Physical Naming Strategy.

Hibernate 5提供了两种不同的命名策略供Hibernate实体使用:隐式命名策略和物理命名策略。

In this tutorial, we’ll see how to configure those naming strategies to map entities to customized table and column names.

在本教程中,我们将看到如何配置这些命名策略,以将实体映射到自定义的表和列名称。

For readers who are new to Hibernate, make sure to check out our introduction article here.

对于刚刚接触Hibernate的读者,请务必查看我们的介绍性文章

2. Dependencies

2.依赖性

We’ll use the basic Hibernate Core dependency for this tutorial:

我们将在本教程中使用基本的Hibernate Core依赖性

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.3.6.Final</version>
</dependency>

3. Implicit Naming Strategy

3.隐含的命名策略

Hibernate uses a logical name to map an entity or attribute name to a table or column name. This name can be customized in two ways: it can be derived automatically by using an ImplicitNamingStrategy or it can be defined explicitly by using annotations.

Hibernate使用逻辑名称将实体或属性名称映射到表或列名称。这个名字可以通过两种方式定制:它可以通过使用ImplicitNamingStrategy自动得出,也可以通过使用注解明确定义。

The ImplicitNamingStrategy governs how Hibernate derives a logical name from our Java class and property names. We can select from four built-in strategies, or we can create our own.

ImplicitNamingStrategy管理Hibernate如何从我们的Java类和属性名称中导出一个逻辑名称。我们可以从四个内置策略中选择,也可以创建自己的策略。

For this example, we’ll use the default strategy, ImplicitNamingStrategyJpaCompliantImpl. Using this strategy, the logical names will be the same as our Java class and property names.

在这个例子中,我们将使用默认策略,ImplicitNamingStrategyJpaCompliantImpl.使用这个策略,逻辑名称将与我们的Java类和属性名称相同。

If we want to deviate from this strategy for a specific entity, we can use annotations to make those customizations. We can use the @Table annotation to customize the name of an @Entity. For a property, we can use the @Column annotation:

如果我们想为某个特定的实体偏离这一策略,我们可以使用注解来进行这些定制。我们可以使用@Table注解来定制一个@Entity的名称。对于一个属性,我们可以使用@Column注解。

@Entity
@Table(name = "Customers")
public class Customer {

    @Id
    @GeneratedValue
    private Long id;

    private String firstName;

    private String lastName;

    @Column(name = "email")
    private String emailAddress;
    
    // getters and setters
    
}

Using this configuration, the logical names for the Customer entity and its properties would be:

使用这种配置,Customer实体及其属性的逻辑名称将是。

Customer -> Customers
firstName -> firstName
lastName -> lastName
emailAddress -> email

4. Physical Naming Strategy

4.物理命名策略

Now that we configured our logical names, let’s have a look at our physical names.

现在我们配置了我们的逻辑名称,让我们看看我们的物理名称。

Hibernate uses the Physical Naming Strategy to map our logical names to a SQL table and its columns.

Hibernate使用物理命名策略,将我们的逻辑名称映射到SQL表及其列。

By default, the physical name will be the same as the logical name that we specified in the previous section. If we want to customize the physical names, we can create a custom PhysicalNamingStrategy class.

默认情况下,物理名称将与我们在上一节中指定的逻辑名称相同。如果我们想定制物理名称,我们可以创建一个自定义的PhysicalNamingStrategy类。

For example, we may want to use camel case names in our Java code, but we want to use underscore separated names for our actual table and column names in the database.

例如,我们可能想在我们的Java代码中使用骆驼大写的名字,但我们想在数据库中使用下划线分隔的实际表和列的名字。

Now, we could use a combination of annotations and a custom ImplicitNamingStrategy to map these names correctly, but Hibernate 5 provides the PhysicalNamingStrategy as a way to simplify this process. It takes our logical names from the previous section and allows us to customize them all in one place.

现在,我们可以使用注释和自定义ImplicitNamingStrategy的组合来正确映射这些名称,但Hibernate 5提供了PhysicalNamingStrategy作为简化这一过程的方法。它采用了上一节中的逻辑名称,并允许我们在一个地方对它们进行自定义。

Let’s see how this is done.

让我们看看这是如何做到的。

First, we’ll create a strategy that converts our camel case names to use our more standard SQL format:

首先,我们将创建一个策略,将我们的骆驼大写名字转换为使用我们更标准的SQL格式。

public class CustomPhysicalNamingStrategy implements PhysicalNamingStrategy {

    @Override
    public Identifier toPhysicalCatalogName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
        return convertToSnakeCase(identifier);
    }

    @Override
    public Identifier toPhysicalColumnName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
        return convertToSnakeCase(identifier);
    }

    @Override
    public Identifier toPhysicalSchemaName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
        return convertToSnakeCase(identifier);
    }

    @Override
    public Identifier toPhysicalSequenceName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
        return convertToSnakeCase(identifier);
    }

    @Override
    public Identifier toPhysicalTableName(final Identifier identifier, final JdbcEnvironment jdbcEnv) {
        return convertToSnakeCase(identifier);
    }

    private Identifier convertToSnakeCase(final Identifier identifier) {
        final String regex = "([a-z])([A-Z])";
        final String replacement = "$1_$2";
        final String newName = identifier.getText()
          .replaceAll(regex, replacement)
          .toLowerCase();
        return Identifier.toIdentifier(newName);
    }
}

Finally, we can tell Hibernate to use our new strategy:

最后,我们可以告诉Hibernate使用我们的新策略。

hibernate.physical_naming_strategy=com.baeldung.hibernate.namingstrategy.CustomPhysicalNamingStrategy

Using our new strategy against the Customer entity, the physical names would be:

使用我们针对Customer实体的新策略,物理名称将是:

Customer -> customers
firstName -> first_name
lastName -> last_name
emailAddress -> email

5. Quoted Identifiers

5.引用的标识符

Because SQL is a declarative language, the keywords that form the grammar of the language are reserved for internal use, and they cannot be employed when defining a database identifier (e.g., catalog, schema, table, column name).

因为SQL是一种声明性语言,构成该语言语法的关键词被保留给内部使用,在定义数据库标识符(例如,目录、模式、表、列名)时不能使用这些关键词。

5.1. Manual Escaping Using Double Quotes

5.1.使用双引号进行手动转义

The first option to escape a database identifier is to wrap the table or column name using the double quotes:

转义数据库标识符的第一个选项是用双引号包裹表或列名。

@Entity(name = "Table")
@Table(name = "\"Table\"")
public class Table {
 
    @Id
    @GeneratedValue
    private Long id;
 
    @Column(name = "\"catalog\"")
    private String catalog;
 
    @Column(name = "\"schema\"")
    private String schema;
 
    private String name;
 
    //Getters and setters 
} 

5.2. Manual Escaping Using the Hibernate-specific Backtick Character

5.2.使用Hibernate特有的回车符进行手动转义

Alternatively, we can also escape a given database identifier using the backtick character:

另外,我们也可以使用反诘字符转义给定的数据库标识符。

@Entity(name = "Table")
@Table(name = "`Table`")
public class Table {
 
    @Id
    @GeneratedValue
    private Long id;
 
    @Column(name = "`catalog`")
    private String catalog;
 
    @Column(name = "`schema`")
    private String schema;
 
    @Column(name = "`name`")
    private String name;
 
    //Getters and setters 
}

5.3. Global Escaping Using Hibernate Configuration

5.3.使用Hibernate配置进行全局逃逸

Another option is to set the hibernate.globally_quoted_identifiers property to true. This way, Hibernate is going to escape all database identifiers. As a result, we don’t have to quote them manually.

另一个选择是将hibernate.global_quoted_identifiers属性设置为true。这样一来,Hibernate就会转义所有的数据库标识符。因此,我们不需要手动引用它们。

In order to use quoted identifiers in CustomPhysicalNamingStrategy, we need to explicitly use the isQuoted() method when creating a new Identifier object:

为了在CustomPhysicalNamingStrategy中使用带引号的标识符,我们需要在创建一个新的标识符对象时明确使用isQuoted()方法。

Identifier.toIdentifier(newName, identifier.isQuoted());

6. Conclusion

6.结论

In this quick article, we’ve learned the relationship between the Implicit and Physical Naming Strategies.

在这篇快速文章中,我们已经了解了隐性命名策略和实体命名策略之间的关系。

We have also seen how to customize the implicit and physical names of an entity and its properties.

我们还看到了如何定制一个实体及其属性的隐含和物理名称。

You can view the source code for this tutorial over on Github.

你可以在Github上查看本教程的源代码over