1. Введение
Spring Data JPA предлагает множество функций для использования JPA в приложении. Среди этих функций — стандартизация имен таблиц и столбцов как в запросах DDL, так и в запросах DML.
В этом кратком руководстве мы увидим, как настроить это соглашение об именах по умолчанию.
2. Соглашение об именах по умолчанию
Прежде всего, давайте посмотрим, каково соглашение об именовании Spring по умолчанию в отношении имен таблиц и столбцов.
Давайте представим, что у нас есть сущность Person :
@Entity
public class Person {
@Id
private Long id;
private String firstName;
private String lastName;
}
У нас есть несколько имен, которые нужно сопоставить с базой данных. Ну, Spring по умолчанию использует нижний регистр змеи , что означает, что он использует только строчные буквы и разделяет слова символом подчеркивания. Таким образом, запрос на создание таблицы для сущности Person
будет выглядеть так:
create table person (id bigint not null, first_name varchar(255), last_name varchar(255), primary key (id));
И запрос выбора, возвращающий все имена, будет таким:
select first_name from person;
Для этого Spring реализовал свою версию PhysicalNamingStrategy
Hibernate `` : SpringPhysicalNamingStrategy
.
3. Регистрозависимость RDMS
Прежде чем вдаваться в подробности того, как создать собственное соглашение об именах, давайте немного поговорим о том, как RDMS управляет регистром идентификаторов.
Следует рассмотреть два сценария: RDMS чувствительна к регистру или нет.
В первой ситуации RDMS будет строго сопоставлять идентификаторы с одинаковым регистром . Поэтому в нашем примере будет работать следующий запрос:
select first_name from person;
В то время как этот выдаст ошибку и даже не вернет результат:
select FIRST_NAME from PERSON;
С другой стороны, для RDMS, нечувствительной к регистру, сработали бы оба запроса.
Что бы мы сделали, чтобы заставить RDMS сопоставлять идентификаторы и в отношении их регистра? Мы можем использовать идентификаторы в кавычках (например, «человек»).
Используя кавычки вокруг наших идентификаторов, мы сообщаем базе данных, что она также должна соответствовать регистру при сравнении этих идентификаторов с именами таблиц и столбцов. Итак, по-прежнему используя наш пример, следующий запрос будет работать:
select "first_name" from "person";
В то время как этот не будет:
select "first_name" from "PERSON";
Но это в теории, потому что каждая RDMS управляет идентификаторами в кавычках по-своему, так что пробег варьируется .
4. Пользовательское соглашение об именах
Теперь давайте реализуем наше собственное соглашение об именах.
Представьте, что мы не можем использовать стратегию нижнего регистра змейки Spring, но нам нужно использовать верхний регистр змеи. Затем нам нужно будет предоставить реализацию PhysicalNamingStrategy
.
Поскольку мы собираемся придерживаться змеиного регистра, самый быстрый вариант — наследовать от SpringPhysicalNamingStrategy
и преобразовать идентификаторы в верхний регистр:
public class UpperCaseNamingStrategy extends SpringPhysicalNamingStrategy {
@Override
protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) {
return new Identifier(name.toUpperCase(), quoted);
}
}
Мы просто переопределяем метод getIdentifier()
, который отвечает за преобразование идентификаторов в нижний регистр в суперклассе. Здесь мы используем его для преобразования их в верхний регистр.
После того, как мы написали нашу реализацию, мы должны зарегистрировать ее, чтобы Hibernate знал, как ее использовать. Используя Spring, это делается путем установки свойства spring.jpa.hibernate.naming.physical-strategy
в нашем application.properties
:
spring.jpa.hibernate.naming.physical-strategy=com.foreach.namingstrategy.UpperCaseNamingStrategy
Теперь наши запросы используют идентификаторы в верхнем регистре:
create table PERSON (ID bigint not null, FIRST_NAME varchar(255), LAST_NAME varchar(255), primary key (ID));
select FIRST_NAME from PERSON;
Допустим, мы хотим использовать идентификаторы в кавычках, чтобы RDMS принудительно соответствовала регистру. Тогда нам пришлось бы использовать true
в качестве цитируемого
аргумента конструктора Identifier (
)
:
@Override
protected Identifier getIdentifier(String name, boolean quoted, JdbcEnvironment jdbcEnvironment) {
return new Identifier(name.toUpperCase(), true);
}
После чего наши запросы будут представлять идентификаторы в кавычках:
create table "PERSON" ("ID" bigint not null, "FIRST_NAME" varchar(255), "LAST_NAME" varchar(255), primary key ("ID"));
select "FIRST_NAME" from "PERSON";
5. Вывод
В этой короткой статье мы рассказали о возможностях реализации пользовательской стратегии именования с использованием Spring Data JPA и о том, как RDMS будет обрабатывать наши операторы DDL и DML в отношении своей внутренней конфигурации.
Как обычно, полный код этой статьи можно найти на GitHub .