Привет! Представляю вашему вниманию статью "Different Hibernate Naming Strategy" автора Dhiraj Ray.
В этой статье обсуждаются различные стратегии именования, предоставляемые hibernate, а также переход стратегии именования от hibernate.ejb.naming_strategy в hibernate 4 до hibernate.implicit_naming_strategy и hibernate.physical_naming_strategy в hibernate 5. А в конце мы будем изучать реализацию пользовательской стратегии именования и конфигурацию для запуска с помощью Spring Boot.
Стратегия именования Hibernate 4
Hibernate использует эту стратегию для сопоставления сущности и атрибута java с соответствующим именем реляционной базы данных и столбцов. В hibernate 4 использовалась стратегия именования hibernate.ejb.naming_strategy. Эта стратегия использует EJB3NamingStrategy, ImprovedNamingStrategy, DefaultComponentSafeNamingStrategy и DefaultNamingStrategy для сопоставления имен. EJB3NamingStrategy — используемая по умолчанию стратегия наименования, и она предоставляет имена полей и таблиц в стиле camelCase. В то время как именование столбца внешнего ключа использует нижнее подчеркивание (_) как разделение. Например, если у вас есть таблица с именем и таблица1 с именами столбцов id и name, то во второй таблице столбец внешнего ключа будет создан как table1_id, таким образом EJB3NamingStrategy реализует интерфейс NamingStrategy.
Стратегия именования Hibernate 5
После выпуска Hibernate 5 hibernate.ejb.naming_strategy больше не используется, поскольку контракт NamingStrategy часто не является достаточно гибким, чтобы правильно применять данное правило «именования». Вместо этого были введены две новые стратегии, обеспечивающие глубокую настройку стратегии именования, которые называются ImplicitNamingStrategy и PhysicalNamingStrategy. Для использования этих стратегий существуют два ключа, которые будут использоваться implicit_naming_strategy и physical_naming_strategy.Hibernate 5 предоставляет только одну реализацию PhysicalNamingStrategy — PhysicalNamingStrategyStandardImpl, но несколько реализаций ImplicitNamingStrategy.
ImplicitNamingStrategy используется, когда вы не указываете имя базы данных и столбца явно в определении сущности, поскольку PhysicalNamingStrategy может использоваться для явного определения правил сопоставления сущности и имени атрибута с именем базы данных и столбцов.
ImplicitNamingStrategy
ImplicitNamingStrategy используется, когда объект явно не указывает таблицу базы данных, к которой он привязан, или когда конкретный атрибут явно не указывает на столбец базы данных, с которым он сопоставлен. Мы можем указать, какую ImplicitNamingStrategy использовать с помощью конфигурации hibernate.implicit_naming_strategy, которая принимает default, jpa, legacy-hbm, legacy-jpa и component-path.
PhysicalNamingStrategy
Идея PhysicalNamingStrategy заключается в том, чтобы определять пользовательские правила именования без необходимости их хардкодинга в сопоставлении через явные имена. Ниже приведена реализация PhysicalNamingStrategy для определения имени таблицы и имени колонки.
package com.devglan;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
import org.apache.commons.lang3.StringUtils;
public class CustomPhysicalNamingStrategy implements PhysicalNamingStrategy {
@Override
public Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment jdbcEnvironment) {
return name;
}
@Override
public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment jdbcEnvironment) {
return name;
}
@Override
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) {
final List parts = splitAndReplace( name.getText() );
return jdbcEnvironment.getIdentifierHelper().toIdentifier(
join( parts ),
name.isQuoted()
);
}
@Override
public Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment jdbcEnvironment) {
return name;
}
@Override
public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment jdbcEnvironment) {
final List parts = splitAndReplace( name.getText() );
return jdbcEnvironment.getIdentifierHelper().toIdentifier(
join( parts ),
name.isQuoted()
);
}
private LinkedList splitAndReplace(String name) {
LinkedList result = new LinkedList<>();
for ( String part : StringUtils.splitByCharacterTypeCamelCase( name ) ) {
if ( part == null || part.trim().isEmpty() ) {
continue;
}
result.add( part.toUpperCase( Locale.ROOT ) );
}
return result;
}
private String join(List parts) {
boolean firstPass = true;
String separator = "";
StringBuilder joined = new StringBuilder();
for ( String part : parts ) {
joined.append( separator ).append( part );
if ( firstPass ) {
firstPass = false;
separator = "_";
}
}
return joined.toString();
}
}
Чтобы использовать эту настраиваемую стратегию в hibernate, выполните следующую конфигурацию:
jpaProperties.put("hibernate.physical_naming_strategy", "com.devglan.config.CustomPhysicalNamingStrategy");
Стратегия именования Hibernate в Spring Boot
Как мы уже говорили, hibernate предоставляет две разные стратегии именования, тогда как Spring Boot настраивает стратегию физического именования с помощью SpringPhysicalNamingStrategy, где все точки заменяются символами подчеркивания, а camelCase заменяется символами подчеркивания, и все имена таблиц генерируются в нижнем регистре. Например, объект USERDETAILS сопоставляется с таблицей user_details.
Если вы хотите использовать свою собственную стратегию именования, реализованную выше, вы можете сделать следующую конфигурацию в application.properties.
spring.jpa.hibernate.naming.physical-strategy=com.devglan.config.CustomPhysicalNamingStrategy);
Вывод
В этой статье вы узнали о различных стратегиях именования, предоставляемых Spring Boot и Hibernate, а также о способах реализации нашей собственной стратегии именования. Если у вас есть что-то, чем бы вы хотели дополнить статью или поделиться, смело делайте это в разделе комментариев.
Автор: DimaLes