Hibernate命名策略详解

时间:2021-10-27 17:24:16

hibernate的命名策略,可以减少对数据库标识符命名的维护,进一步减少这部份命名的重复性代码量,以提高维护。

hibernate的命名方式,有两类,一类是显式命名,一类是隐式命名。

1)显式命名:在映射配置时,设置的数据库表名,列名等,就是进行显式命名。

2)隐式命名:显式命名一般不是必要的,所以可以选择当不设置名称,这时就交由hibernate进行隐式命名,另外隐式命名还包括那些不能进行显式命名的数据库标识符。接口ImplicitNamingStrategy,就是用于实现隐式命名。

3)过滤命名:接口PhysicalNamingStrategy,用于对显式命名或隐式命名进一步过滤处理。

示例:

TestTable1Impl.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@Entity
// 隐式命名表名
@Table
public class TestTable1Impl {
  //---------------------------------------------------------------
  // Field
  //---------------------------------------------------------------
  @Id
  @Column()
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long testId;
  @Column(length = 20)
  private String testName;
  @ManyToOne
  private TestTable2Impl testForeign;
  //---------------------------------------------------------------
  // Method
  //---------------------------------------------------------------
  public Long getId() {
    return testId;
  }
  public void setId(Long id) {
    this.testId = id;
  }
  public String getName(){
    return testName;
  }
  public void setName(String name){
    this.testName = name;
  }
  public TestTable2Impl getTestForeign() {
    return testForeign;
  }
  public void setTestForeign(TestTable2Impl testForeign) {
    this.testForeign = testForeign;
  }
}

TestTable2Impl.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Entity
// 显式命名表名
@Table(name = "TestTable2Impl")
public class TestTable2Impl {
  //---------------------------------------------------------------
  // Field
  //---------------------------------------------------------------
  @Id
  @Column()
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long testId;
  @Column(length = 20)
  private String testName;
  //---------------------------------------------------------------
  // Method
  //---------------------------------------------------------------
  public Long getId() {
    return testId;
  }
  public void setId(Long id) {
    this.testId = id;
  }
  public String getName(){
    return testName;
  }
  public void setName(String name){
    this.testName = name;
  }
}

MyImplicitNamingStrategyImpl.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
public class MyImplicitNamingStrategyImpl extends ImplicitNamingStrategyJpaCompliantImpl implements ImplicitNamingStrategy {
  @Override
  public Identifier determinePrimaryTableName(ImplicitEntityNameSource source) {
    Identifier name = super.determinePrimaryTableName(source);
    Identifier result = toStandard(name, "Impl");
    System.out.println("ImplicitNamingStrategy / PrimaryTableName -> \n\t" + name + " => " + result);
    return result;
  }
  private Identifier toStandard(Identifier name, String... removeSuffixes){
    if(removeSuffixes == null)
      return name;
    if(name == null)
      return null;
    String text = name.getText();
    if(removeSuffixes != null){
      for(String suffix : removeSuffixes){
        if(text.endsWith(suffix))
          text = text.substring(0, text.length() - suffix.length());
      }
    }
    return new Identifier(text, name.isQuoted());
  }
  @Override
  public Identifier determineJoinTableName(ImplicitJoinTableNameSource source) {
    Identifier name = super.determineJoinTableName(source);
    System.out.println("ImplicitNamingStrategy / JoinTableName -> \n\t" + name);
    return name;
  }
  @Override
  public Identifier determineCollectionTableName(ImplicitCollectionTableNameSource source) {
    Identifier name = super.determineCollectionTableName(source);
    System.out.println("ImplicitNamingStrategy / CollectionTableName -> \n\t" + name);
    return name;
  }
  @Override
  public Identifier determineDiscriminatorColumnName(ImplicitDiscriminatorColumnNameSource source) {
    Identifier name = super.determineDiscriminatorColumnName(source);
    System.out.println("ImplicitNamingStrategy / DiscriminatorColumnName -> \n\t" + name);
    return name;
  }
  @Override
  public Identifier determineTenantIdColumnName(ImplicitTenantIdColumnNameSource source) {
    Identifier name = super.determineTenantIdColumnName(source);
    System.out.println("ImplicitNamingStrategy / TenantIdColumnName -> \n\t" + name);
    return name;
  }
  @Override
  public Identifier determineIdentifierColumnName(ImplicitIdentifierColumnNameSource source) {
    Identifier name = super.determineIdentifierColumnName(source);
    System.out.println("ImplicitNamingStrategy / IdentifierColumnName -> \n\t" + name);
    return name;
  }
  @Override
  public Identifier determineBasicColumnName(ImplicitBasicColumnNameSource source) {
    Identifier name = super.determineBasicColumnName(source);
    System.out.println("ImplicitNamingStrategy / BasicColumnName -> \n\t" + name);
    return name;
  }
  @Override
  public Identifier determineJoinColumnName(ImplicitJoinColumnNameSource source) {
    Identifier name = super.determineJoinColumnName(source);
    final String result;
    if ( source.getNature() == ImplicitJoinColumnNameSource.Nature.ELEMENT_COLLECTION || source.getAttributePath() == null ) {
      result = transformEntityName( source.getEntityNaming() );
    } else {
      result = transformAttributePath( source.getAttributePath() );
    }
    System.out.println("ImplicitNamingStrategy / JoinColumnName -> \n\t" + name + " => " + result);
    return toIdentifier( result, source.getBuildingContext() );
  }
  @Override
  public Identifier determinePrimaryKeyJoinColumnName(ImplicitPrimaryKeyJoinColumnNameSource source) {
    Identifier name = super.determinePrimaryKeyJoinColumnName(source);
    System.out.println("ImplicitNamingStrategy / PrimaryKeyJoinColumnName -> \n\t" + name);
    return name;
  }
  @Override
  public Identifier determineAnyDiscriminatorColumnName(ImplicitAnyDiscriminatorColumnNameSource source) {
    Identifier name = super.determineAnyDiscriminatorColumnName(source);
    System.out.println("ImplicitNamingStrategy / AnyDiscriminatorColumnName -> \n\t" + name);
    return name;
  }
  @Override
  public Identifier determineAnyKeyColumnName(ImplicitAnyKeyColumnNameSource source) {
    Identifier name = super.determineAnyKeyColumnName(source);
    System.out.println("ImplicitNamingStrategy / AnyKeyColumnName -> \n\t" + name);
    return name;
  }
  @Override
  public Identifier determineMapKeyColumnName(ImplicitMapKeyColumnNameSource source) {
    Identifier name = super.determineMapKeyColumnName(source);
    System.out.println("ImplicitNamingStrategy / MapKeyColumnName -> \n\t" + name);
    return name;
  }
  @Override
  public Identifier determineListIndexColumnName(ImplicitIndexColumnNameSource source) {
    Identifier name = super.determineListIndexColumnName(source);
    System.out.println("ImplicitNamingStrategy / ListIndexColumnName -> \n\t" + name);
    return name;
  }
  @Override
  public Identifier determineForeignKeyName(ImplicitForeignKeyNameSource source) {
    Identifier name = super.determineForeignKeyName(source);
    String result = null;
    String tableName = source.getTableName().getText();
    if(tableName.startsWith(TableNamingConfig.TABLE_PREFIX))
      tableName = tableName.substring(TableNamingConfig.TABLE_PREFIX.length());
    if(source.getColumnNames().size() == 1){
      result = TableNamingConfig.FOREIGN_KEY_PREFIX + tableName + "_" + source.getColumnNames().get(0).getText();
    } else {
      String columnName = source.getReferencedTableName().getText();
      if(columnName.startsWith(TableNamingConfig.TABLE_PREFIX))
        columnName = columnName.substring(TableNamingConfig.TABLE_PREFIX.length());
      result = TableNamingConfig.FOREIGN_KEY_PREFIX + tableName + "_" + columnName;
    }
    System.out.println("ImplicitNamingStrategy / ForeignKeyName -> \n\t" + name + " => " + result);
    return new Identifier(result, name.isQuoted());
  }
  @Override
  public Identifier determineUniqueKeyName(ImplicitUniqueKeyNameSource source) {
    Identifier name = super.determineUniqueKeyName(source);
    System.out.println("ImplicitNamingStrategy / UniqueKeyName -> \n\t" + name);
    return name;
  }
  @Override
  public Identifier determineIndexName(ImplicitIndexNameSource source) {
    Identifier name = super.determineIndexName(source);
    System.out.println("ImplicitNamingStrategy / IndexName -> \n\t" + name);
    return name;
  }
}

MyPhysicalNamingStrategyImpl.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public class MyPhysicalNamingStrategyImpl implements PhysicalNamingStrategy {
  @Override
  public Identifier toPhysicalCatalogName(Identifier name, JdbcEnvironment jdbcEnvironment) {
    System.out.println("PhysicalNamingStrategy / catalog -> \n\t" + name);
    return name;
  }
  @Override
  public Identifier toPhysicalSchemaName(Identifier name, JdbcEnvironment jdbcEnvironment) {
    System.out.println("PhysicalNamingStrategy / schema -> \n\t" + name);
    return name;
  }
  @Override
  public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) {
    Identifier result = toStandard(name, "tb_");
    System.out.println("PhysicalNamingStrategy / table -> \n\t" + name + " => " + result);
    return result;
  }
  @Override
  public Identifier toPhysicalSequenceName(Identifier name, JdbcEnvironment jdbcEnvironment) {
    System.out.println("PhysicalNamingStrategy / sequence -> \n\t" + name);
    return name;
  }
  @Override
  public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment jdbcEnvironment) {
    Identifier result = toStandard(name);
    System.out.println("PhysicalNamingStrategy / column -> \n\t" + name + " => " + result);
    return result;
  }
  private Identifier toStandard(Identifier name){
    return toStandard(name, null);
  }
  private Identifier toStandard(Identifier name, String prefix){
    if(name == null)
      return null;
    String text = name.getText();
    StringBuffer buffer = new StringBuffer();
    if(prefix != null)
      buffer.append(prefix);
    char[] chars = text.toCharArray();
    for(int i=0, len=chars.length; i<len; i++){
      char c1 = chars[i];
      if(c1 >= 'A' && c1 <= 'Z'){
        if(i > 0 && i + 1 < len){
          if(chars[i + 1] < 'A' || chars[i + 1] > 'Z')
            buffer.append('_');
        }
        c1 = (char) (c1 - 'A' + 'a');
      }
      buffer.append(c1);
    }
    return new Identifier(buffer.toString(), name.isQuoted());
  }
}

TableNamingConfig.java

?
1
2
3
4
public class TableNamingConfig {
  public static final String TABLE_PREFIX = "tb_";
  public static final String FOREIGN_KEY_PREFIX = "fk_";
}

spring.xml

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans.xsd    http://www.springframework.org/schema/context    http://www.springframework.org/schema/context/spring-context-4.1.xsd">
  <!-- 配置数据源 -->
  <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test?useSSL=false"></property>
    <property name="user" value="root"></property>
    <property name="password" value="123456"></property>
  </bean>
  <bean id="physicalNamingStrategy" class="test.MyPhysicalNamingStrategyImpl"></bean>
  <bean id="implicitNamingStrategy" class="test.MyImplicitNamingStrategyImpl"></bean>
  <bean id="sessionFactory"    class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan">
      <list>
        <!-- 可以加多个包 -->
        <value>test</value>
      </list>
    </property>
    <property name="hibernateProperties">
      <props>
        <prop key="hibernate.hbm2ddl.auto">create-drop</prop>
        <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
        <prop key="hibernate.show_sql">true</prop>
        <prop key="hibernate.format_sql">true</prop>
        <prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
      </props>
    </property>
    <property name="physicalNamingStrategy" ref="physicalNamingStrategy"></property>
    <property name="implicitNamingStrategy" ref="implicitNamingStrategy"></property>
  </bean>
</beans>

Test.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
public class Test {
  public static void main(String[] params){
    // 命名策略
    new Test().test();
    /*
      PhysicalNamingStrategy / catalog ->
        null
      PhysicalNamingStrategy / catalog ->
        null
      PhysicalNamingStrategy / column ->
        DTYPE => dtype
      ImplicitNamingStrategy / PrimaryTableName ->
        TestTable1Impl => TestTable1
      PhysicalNamingStrategy / table ->
        TestTable1 => tb_test_table1
      ImplicitNamingStrategy / BasicColumnName ->
        testId
      PhysicalNamingStrategy / column ->
        testId => test_id
      ImplicitNamingStrategy / BasicColumnName ->
        testId
      ImplicitNamingStrategy / BasicColumnName ->
        testForeign
      PhysicalNamingStrategy / column ->
        testForeign => test_foreign
      ImplicitNamingStrategy / BasicColumnName ->
        testName
      PhysicalNamingStrategy / column ->
        testName => test_name
      ImplicitNamingStrategy / BasicColumnName ->
        testName
      PhysicalNamingStrategy / column ->
        DTYPE => dtype
      PhysicalNamingStrategy / table ->
        TestTable2Impl => tb_test_table2_impl
      ImplicitNamingStrategy / BasicColumnName ->
        testId
      PhysicalNamingStrategy / column ->
        testId => test_id
      ImplicitNamingStrategy / BasicColumnName ->
        testId
      ImplicitNamingStrategy / BasicColumnName ->
        testName
      PhysicalNamingStrategy / column ->
        testName => test_name
      ImplicitNamingStrategy / BasicColumnName ->
        testName
      ImplicitNamingStrategy / JoinColumnName ->
        testForeign_testId => testForeign
      PhysicalNamingStrategy / column ->
        testForeign => test_foreign
      ImplicitNamingStrategy / ForeignKeyName ->
        FKlnurug7wfle1u6fc5oulnrx94 => fk_test_table1_test_foreign
      Hibernate:
        alter table tb_test_table1
          drop
          foreign key fk_test_table1_test_foreign
      Hibernate:
        drop table if exists tb_test_table1
      Hibernate:
        drop table if exists tb_test_table2_impl
      Hibernate:
        create table tb_test_table1 (
          test_id bigint not null auto_increment,
          test_name varchar(20),
          test_foreign bigint,
          primary key (test_id)
        )
      Hibernate:
        create table tb_test_table2_impl (
          test_id bigint not null auto_increment,
          test_name varchar(20),
          primary key (test_id)
        )
      Hibernate:
        alter table tb_test_table1
          add constraint fk_test_table1_test_foreign
          foreign key (test_foreign)
          references tb_test_table2_impl (test_id)
      Hibernate:
        alter table tb_test_table1
          drop
          foreign key fk_test_table1_test_foreign
      Hibernate:
        drop table if exists tb_test_table1
      Hibernate:
        drop table if exists tb_test_table2_impl
     */
  }
  public void test(){
    ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml", this.getClass());
    SessionFactory factory = null;
    try {
      factory = (SessionFactory) context.getBean("sessionFactory");
    } finally {
      if(factory != null){
        factory.close();
        factory = null;
      }
    }
  }
}

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持服务器之家!

原文链接:http://www.cnblogs.com/hvicen/p/6345559.html