Open techiall opened 5 years ago
骄傲的使用 谷歌翻译 原文链接 https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/domain/naming.html 不想看原文的话,最后我会说下的理解。
骄傲的使用 谷歌翻译
原文链接 https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/chapters/domain/naming.html
不想看原文的话,最后我会说下的理解。
对象模型到关系数据库的映射的一部分是将对象模型中的名称映射到相应的数据库名称。 Hibernate 将此视为两阶段过程:
@Column
@Table
ImplicitNamingStrategy
PhysicalNamingStrategy
之前 Hibernate 只定义了一个 org.hibernate.cfg.NamingStrategy 。这个单一的 NamingStrategy 现在已经拆成ImplicitNamingStrategy 和 PhysicalNamingStrategy。
org.hibernate.cfg.NamingStrategy
NamingStrategy
此外,NamingStrategy 通常不够灵活,无法正确应用给定的命名“规则”,因为 API 缺乏可供决定的信息,或者因为 API 实际上没有得到很好的定义。
API
由于这些限制,org.hibernate.cfg.NamingStrategy 已被弃用,然后被删除,转而使用 ImplicitNamingStrategy 和 PhysicalNamingStrategy 。
每种命名策略背后的想法是最小化数量,开发人员必须提供的重复信息,用于映射域模型。
JPA 定义了关于隐式逻辑名称确定的固有规则。如果 JPA 提供程序可移植性是一个主要问题,或者您真的喜欢 JPA 定义的隐式命名规则,请务必坚持使用 ImplicitNamingStrategyJpaCompliantImpl(默认值)
JPA
ImplicitNamingStrategyJpaCompliantImpl
此外,JPA 定义逻辑名称和物理名称之间没有分离。遵循 JPA 规范,逻辑名称是物理名称。如果 JPA 提供程序可移植性很重要,应用程序应该不要指定 PhysicalNamingStrategy 。
当实体没有显式命名它映射到的数据库表时,我们需要隐式确定该表名。或者,当某个特定属性没有显式命名它映射到的数据库列时,我们需要隐式确定该列名。当映射未提供显式名称时, org.hibernate.boot.model.naming.ImplicitNamingStrategy 用于确定逻辑名称。
org.hibernate.boot.model.naming.ImplicitNamingStrategy
Hibernate定义了多个 ImplicitNamingStrategy 实现。应用程序也可以免费插入自定义实现。
有多种方法可以指定要使用的 ImplicitNamingStrategy 。首先,应用程序可以使用 hibernate.implicit_naming_strategy 配置设置来指定实现,该设置接受:
hibernate.implicit_naming_strategy
org.hibernate.boot.model.name.ImplicitNamingStrategyJpaCompliantImpl
jpa
org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
JPA 2.0
org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl
org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
JPA 1.0
org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl
FQN
其次,应用程序和集成可以利用 org.hibernate.boot.MetadataBuilder#applyImplicitNamingStrategy 来指定要使用的 ImplicitNamingStrategy。有关引导的其他详细信息,请参阅 Bootstrap。
org.hibernate.boot.MetadataBuilder#applyImplicitNamingStrategy
Bootstrap
许多组织围绕数据库对象(表,列,外键等)的命名定义规则。 PhysicalNamingStrategy 的想法是帮助实现这样的命名规则,而不必通过显式名称将它们硬编码到映射中。
虽然 ImplicitNamingStrategy 的目的是确定名称为 accountNumber 的属性在未明确指定时映射到 accountNumber 的逻辑列名称,PhysicalNamingStrategy的目的是,例如,假设物理列名称应缩写为 acct_num 。
accountNumber
acct_num
确实,在这种情况下,acct_num 的解析可以在 ImplicitNamingStrategy 中处理。但重点是分离关注点。无论属性是否明确指定列名,或者我们是否隐式确定,都将应用 PhysicalNamingStrategy 。仅当未给出显式名称时,才会应用ImplicitNamingStrategy 。所以它取决于需求和意图。
默认实现是简单地使用逻辑名称作为物理名称。但是,应用程序和集成可以定义此 PhysicalNamingStrategy 合同的自定义实现。以下是一个名为 Acme Corp 的虚构公司的 PhysicalNamingStrategy 示例,其命名标准是:
Acme Corp
示例1. PhysicalNamingStrategy 实现示例
/* * Hibernate, Relational Persistence for Idiomatic Java * * License: GNU Lesser General Public License (LGPL), version 2.1 or later. * See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>. */ package org.hibernate.userguide.naming; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.TreeMap; 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; /** * An example PhysicalNamingStrategy that implements database object naming standards * for our fictitious company Acme Corp. * <p/> * In general Acme Corp prefers underscore-delimited words rather than camel casing. * <p/> * Additionally standards call for the replacement of certain words with abbreviations. * * @author Steve Ebersole */ public class AcmeCorpPhysicalNamingStrategy implements PhysicalNamingStrategy { private static final Map<String,String> ABBREVIATIONS = buildAbbreviationMap(); @Override public Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment jdbcEnvironment) { // Acme naming standards do not apply to catalog names return name; } @Override public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment jdbcEnvironment) { // Acme naming standards do not apply to schema names return name; } @Override public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) { final List<String> parts = splitAndReplace( name.getText() ); return jdbcEnvironment.getIdentifierHelper().toIdentifier( join( parts ), name.isQuoted() ); } @Override public Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment jdbcEnvironment) { final LinkedList<String> parts = splitAndReplace( name.getText() ); // Acme Corp says all sequences should end with _seq if ( !"seq".equalsIgnoreCase( parts.getLast() ) ) { parts.add( "seq" ); } return jdbcEnvironment.getIdentifierHelper().toIdentifier( join( parts ), name.isQuoted() ); } @Override public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment jdbcEnvironment) { final List<String> parts = splitAndReplace( name.getText() ); return jdbcEnvironment.getIdentifierHelper().toIdentifier( join( parts ), name.isQuoted() ); } private static Map<String, String> buildAbbreviationMap() { TreeMap<String,String> abbreviationMap = new TreeMap<> ( String.CASE_INSENSITIVE_ORDER ); abbreviationMap.put( "account", "acct" ); abbreviationMap.put( "number", "num" ); return abbreviationMap; } private LinkedList<String> splitAndReplace(String name) { LinkedList<String> result = new LinkedList<>(); for ( String part : StringUtils.splitByCharacterTypeCamelCase( name ) ) { if ( part == null || part.trim().isEmpty() ) { // skip null and space continue; } part = applyAbbreviationReplacement( part ); result.add( part.toLowerCase( Locale.ROOT ) ); } return result; } private String applyAbbreviationReplacement(String word) { if ( ABBREVIATIONS.containsKey( word ) ) { return ABBREVIATIONS.get( word ); } return word; } private String join(List<String> 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(); } }
有多种方法可以指定要使用的 PhysicalNamingStrategy。首先,应用程序可以使用 hibernate.physical_naming_strategy 配置设置指定实现,该设置接受:
hibernate.physical_naming_strategy
org.hibernate.boot.model.naming.PhysicalNamingStrategy
其次,应用程序和集成可以利用 org.hibernate.boot.MetadataBuilder#applyPhysicalNamingStrategy。有关引导的其他详细信息,请参阅Bootstrap。
org.hibernate.boot.MetadataBuilder#applyPhysicalNamingStrategy
首先也就是 Hibernate 中的 NamingStrategy 已经被 ImplicitNamingStrategy 和 PhysicalNamingStrategy取代。
PhysicalNamingStrategyStandardImpl
SpringPhysicalNamingStrategy
几个属性的例子可以参考这个链接 https://stackoverflow.com/questions/41267416/hibernate-5-naming-strategy-examples
在 Spring Boot 中的 application.yml 建议做如下配置。
spring: jpa: hibernate: naming: physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl
hibernate 命名策略
对象模型到关系数据库的映射的一部分是将对象模型中的名称映射到相应的数据库名称。 Hibernate 将此视为两阶段过程:
@Column
或@Table
),也可以由 Hibernate 通过ImplicitNamingStrategy
隐式确定。PhysicalNamingStrategy
定义的物理名称。过去的命名策略
之前 Hibernate 只定义了一个
org.hibernate.cfg.NamingStrategy
。这个单一的NamingStrategy
现在已经拆成ImplicitNamingStrategy
和PhysicalNamingStrategy
。此外,
NamingStrategy
通常不够灵活,无法正确应用给定的命名“规则”,因为API
缺乏可供决定的信息,或者因为API
实际上没有得到很好的定义。由于这些限制,
org.hibernate.cfg.NamingStrategy
已被弃用,然后被删除,转而使用ImplicitNamingStrategy
和PhysicalNamingStrategy
。每种命名策略背后的想法是最小化数量,开发人员必须提供的重复信息,用于映射域模型。
JPA 兼容性
JPA
定义了关于隐式逻辑名称确定的固有规则。如果JPA
提供程序可移植性是一个主要问题,或者您真的喜欢JPA
定义的隐式命名规则,请务必坚持使用ImplicitNamingStrategyJpaCompliantImpl
(默认值)此外,
JPA
定义逻辑名称和物理名称之间没有分离。遵循JPA
规范,逻辑名称是物理名称。如果JPA
提供程序可移植性很重要,应用程序应该不要指定PhysicalNamingStrategy
。ImplicitNamingStrategy
当实体没有显式命名它映射到的数据库表时,我们需要隐式确定该表名。或者,当某个特定属性没有显式命名它映射到的数据库列时,我们需要隐式确定该列名。当映射未提供显式名称时,
org.hibernate.boot.model.naming.ImplicitNamingStrategy
用于确定逻辑名称。Hibernate定义了多个
ImplicitNamingStrategy
实现。应用程序也可以免费插入自定义实现。有多种方法可以指定要使用的
ImplicitNamingStrategy
。首先,应用程序可以使用hibernate.implicit_naming_strategy
配置设置来指定实现,该设置接受:org.hibernate.boot.model.name.ImplicitNamingStrategyJpaCompliantImpl
jpa
的别名org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
符合JPA 2.0
标准的命名策略org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl
符合原始的 Hibernate 命名策略org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
符合为JPA 1.0
开发的旧版命名策略,遗憾的是,在很多方面,隐式命名规则都不清楚org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl
主要遵循ImplicitNamingStrategyJpaCompliantImpl
规则,除了它使用完整的复合路径,而不仅仅是结束属性部分org.hibernate.boot.model.naming.ImplicitNamingStrategy
类的引用org.hibernate.boot.model.naming.ImplicitNamingStrategy
的类的FQN
其次,应用程序和集成可以利用
org.hibernate.boot.MetadataBuilder#applyImplicitNamingStrategy
来指定要使用的ImplicitNamingStrategy
。有关引导的其他详细信息,请参阅Bootstrap
。PhysicalNamingStrategy
许多组织围绕数据库对象(表,列,外键等)的命名定义规则。
PhysicalNamingStrategy
的想法是帮助实现这样的命名规则,而不必通过显式名称将它们硬编码到映射中。虽然
ImplicitNamingStrategy
的目的是确定名称为accountNumber
的属性在未明确指定时映射到accountNumber
的逻辑列名称,PhysicalNamingStrategy
的目的是,例如,假设物理列名称应缩写为acct_num
。确实,在这种情况下,
acct_num
的解析可以在ImplicitNamingStrategy
中处理。但重点是分离关注点。无论属性是否明确指定列名,或者我们是否隐式确定,都将应用PhysicalNamingStrategy
。仅当未给出显式名称时,才会应用ImplicitNamingStrategy
。所以它取决于需求和意图。默认实现是简单地使用逻辑名称作为物理名称。但是,应用程序和集成可以定义此
PhysicalNamingStrategy
合同的自定义实现。以下是一个名为Acme Corp
的虚构公司的PhysicalNamingStrategy
示例,其命名标准是:示例1. PhysicalNamingStrategy 实现示例
有多种方法可以指定要使用的
PhysicalNamingStrategy
。首先,应用程序可以使用hibernate.physical_naming_strategy
配置设置指定实现,该设置接受:org.hibernate.boot.model.naming.PhysicalNamingStrategy
类的引用org.hibernate.boot.model.naming.PhysicalNamingStrategy
类的FQN其次,应用程序和集成可以利用
org.hibernate.boot.MetadataBuilder#applyPhysicalNamingStrategy
。有关引导的其他详细信息,请参阅Bootstrap。个人总结
首先也就是 Hibernate 中的
NamingStrategy
已经被ImplicitNamingStrategy
和PhysicalNamingStrategy
取代。PhysicalNamingStrategy 有两个属性
PhysicalNamingStrategyStandardImpl
不做修改,直接映射SpringPhysicalNamingStrategy
首字母小写,大写字母变为下划线加小写ImplicitNamingStrategy 有四个属性
org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl
符合JPA 2.0
标准的命名策略org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyHbmImpl
符合原始的 Hibernate 命名策略org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
符合为JPA 1.0
开发的旧版命名策略,遗憾的是,在很多方面,隐式命名规则都不清楚org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl
主要遵循ImplicitNamingStrategyJpaCompliantImpl
规则,除了它使用完整的复合路径,而不仅仅是结束属性部分几个属性的例子可以参考这个链接 https://stackoverflow.com/questions/41267416/hibernate-5-naming-strategy-examples
配置
在 Spring Boot 中的 application.yml 建议做如下配置。