Custom Naming Convention with Spring Data JPA – 使用Spring Data JPA的自定义命名规则

最后修改: 2020年 4月 13日

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

1. Introduction

1.绪论

Spring Data JPA offers many features to use JPA in an application. Among those features, there’s the standardization of table and column names in both DDL and DML queries.

Spring Data JPA提供了许多在应用程序中使用JPA的功能。在这些功能中,在DDL和DML查询中都有表和列名称的标准化。

In this short tutorial, we’re going to see how to configure this default naming convention.

在这个简短的教程中,我们将看到如何配置这个默认的命名惯例。

2. Default Naming Convention

2.默认的命名规则

First of all, let’s see what Spring’s default naming convention regarding table and column names.

首先,让我们看看Spring关于表和列名的默认命名规则是什么。

Let’s imagine we have a Person entity:

让我们想象一下,我们有一个Person实体。

@Entity
public class Person {
    @Id
    private Long id;
    private String firstName;
    private String lastName;
}

We have a few names here that have to be mapped to the database. Well, Spring uses lower snake case by default, which means it uses only lower case letters and separates words with underscores. Therefore, the table creation query for the Person entity would be:

我们这里有几个名字必须要映射到数据库中。好吧,Spring默认使用小写蛇形字母,这意味着它只使用小写字母,并用下划线来分隔单词。因此,Person实体的表创建查询将是。

create table person (id bigint not null, first_name varchar(255), last_name varchar(255), primary key (id));

And a selection query returning all first names would be:

而一个返回所有名字的选择查询将是。

select first_name from person;

To do that, Spring implemented its version of the Hibernate’s PhysicalNamingStrategy: SpringPhysicalNamingStrategy.

为了做到这一点,Spring实现了它的Hibernate的PhysicalNamingStrategy版本。SpringPhysicalNamingStrategy.

3. RDMS Case-Sensitivity

3.RDMS的大小写敏感性

Before going into the details of how to create our custom naming convention, let’s talk a bit about how the RDMS is managing the case of the identifiers.

在讨论如何创建我们的自定义命名规则的细节之前,让我们先谈谈RDMS是如何管理标识符的情况。

There are two scenarios to consider: the RDMS is case-sensitive, or it is not.

有两种情况需要考虑:RDMS是大小写敏感的,或者不是。

In the first situation, the RDMS will strictly match identifiers that have the same case. Therefore, in our example, the following query would work:

在第一种情况下,RDMS将严格匹配具有相同大小写的标识符。因此,在我们的例子中,下面的查询会有效。

select first_name from person;

While this one will throw an error and not even return a result:

而这个将抛出一个错误,甚至不返回一个结果。

select FIRST_NAME from PERSON;

On the other hand, for an RDMS that is case-insensitive, both queries would have worked.

另一方面,对于不区分大小写的RDMS来说,这两个查询都会成功。

What would we do to force the RDMS to match identifiers regarding their case as well? We can use quoted identifiers (for example, “person”).

我们要怎么做才能迫使RDMS对标识符的大小写也进行匹配?我们可以使用带引号的标识符(例如,”人”)。

By using quotes around our identifiers, we tell the database it should also match the case when comparing those identifiers with table and column names. So, still using our example, the following query would work:

通过在标识符周围使用引号,我们告诉数据库在比较这些标识符与表和列名时也应该匹配大小写。因此,仍然使用我们的例子,下面的查询将工作。

select "first_name" from "person";

While this one wouldn’t:

虽然这个人不会。

select "first_name" from "PERSON";

That’s in theory though, because each RDMS manages quoted identifiers in its own way, so mileage varies.

不过这只是在理论上,因为每个RDMS都以自己的方式管理引号标识符,所以里程数不一样

4. Custom Naming Convention

4.自定义命名公约

Now, let’s implement our own naming convention.

现在,让我们来实现我们自己的命名规则。

Imagine we can’t use the Spring lower snake case strategy, but we need to use upper snake case. Then, we’d need to provide an implementation of PhysicalNamingStrategy.

想象一下,我们不能使用Spring的小写蛇形码策略,但我们需要使用大写蛇形码。那么,我们就需要提供一个PhysicalNamingStrategy的实现。

As we’re going to keep to snake case, the fastest option is to inherit from the SpringPhysicalNamingStrategy and turn identifiers to upper case:

由于我们要保持蛇形大小写,最快的选择是继承SpringPhysicalNamingStrategy,将标识符变成大写。

public class UpperCaseNamingStrategy extends SpringPhysicalNamingStrategy {
    @Override
    protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) {
        return new Identifier(name.toUpperCase(), quoted);
    }
}

We’re just overriding the getIdentifier() method, which is in charge of turning the identifiers to lower case in the super-class. Here we’re using it to convert them to upper case.

我们只是覆盖了getIdentifier()方法,该方法负责将超类中的标识符变成小写。在这里,我们用它来将它们转换为大写。

Once we’ve written our implementation, we must register it so that Hibernate knows to use it. Using Spring, this is done by setting the spring.jpa.hibernate.naming.physical-strategy property in our application.properties:

一旦我们写好了我们的实现,我们必须注册它,以便Hibernate知道要使用它。使用Spring,我们可以在application.properties中设置spring.jpa.hibernate.naming.physical-strategy属性来完成。

spring.jpa.hibernate.naming.physical-strategy=com.baeldung.namingstrategy.UpperCaseNamingStrategy

Now, our queries are using upper case identifiers:

现在,我们的查询是使用大写的标识符。

create table PERSON (ID bigint not null, FIRST_NAME varchar(255), LAST_NAME varchar(255), primary key (ID));

select FIRST_NAME from PERSON;

Let’s say that we want to use quoted identifiers so that the RDMS is forced to match the case. Then we would have to use true as the quoted argument of the Identifier() constructor:

假设我们想使用带引号的标识符,这样RDMS就会被迫匹配大小写。那么我们就必须使用true作为Identifier()构造函数的quoted参数

@Override
protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) {
    return new Identifier(name.toUpperCase(), true);
}

After what our queries would present quoted identifiers:

之后,我们的查询会呈现出引号标识符。

create table "PERSON" ("ID" bigint not null, "FIRST_NAME" varchar(255), "LAST_NAME" varchar(255), primary key ("ID"));

select "FIRST_NAME" from "PERSON";

5. Conclusion

5.总结

In this short article, we talked about the possibilities of implementing a custom naming strategy using Spring Data JPA and how the RDMS will handle our DDL and DML statements regarding its internal configuration.

在这篇短文中,我们谈到了使用Spring Data JPA实现自定义命名策略的可能性以及RDMS将如何处理我们关于其内部配置的DDL和DML语句。

As usual, the full code for this article can be found over on GitHub.

像往常一样,本文的完整代码可以在GitHub上找到超过