hibernate生成データベースのネーミングルールを拡張


Java開発者にとって、Hibernate 3 annotationsはドメイン階層を示すのに非常に良い方法を提供しています.必要なデータベース・アーキテクチャをHibernateで自動的に生成することができ、SQLスクリプトが完全に含まれています.しかし、現実の世界に戻ると、データベース管理者が使用する曖昧な命名慣行も考慮する必要があります.この文書では、Java Power Toolsの著者John Ferguson Smartが、Hibernateによってデータベース・アーキテクチャを自動的に生成し、データベース管理を容易にする方法を説明します.
Hibernate 3アノテーションには強力な永続的なデータベース管理方法があります.これらのアノテーションを使用すると、XMLマッピングファイルに気を使う必要はありません.デフォルトに設定し、システムによって完了することができ、メンテナンスが必要なコードを大幅に削減することができます.Hibernateは強力なデータベース・アーキテクチャの自動生成ツールを提供しているので、Hibernateはデータベース・アーキテクチャの生成と更新を自動的に行うことができ、不思議なSQLスクリプトを心配する必要はありません.
ステップ1:データベース・アーキテクチャの更新
データベース・アーキテクチャをHibernateで自動的に更新するのは簡単です.Hibernateを設定するだけです.hbm2ddl.例1のようにauto:
例1:
<hibernate-configuration>
   <session-factory>       
      <property name="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</property>
      <property name="hibernate.hbm2ddl.auto">create-drop</property>
      ...
      <!-- Persistent classes -->
      <mapping class="com.mycompany.myapp.domain.Client"/>
      <mapping class="com.mycompany.myapp.domain.Order"/>
      ...
   </session-factory>   
</hibernate-configuration>

プロパティを「create-drop」に設定すると、アプリケーションを起動するたびに新しいデータベースが生成され、統合テストに役立ちますが、必要ない場合があります.一方、この値を更新するために設定した場合、データベースが存在しない場合、Hibernateは自動的にデータベースを作成し、現在のドメインモデルに一致するすべてのテーブルを更新します.
デフォルトでは、HibernateはJavaクラスに似たテーブルとフィールドを作成し、Java開発者の観点から要求に合っています.次の例を考えます.
例2:A simple persistent class
@Entity
public class Client implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String firstName;
    private String lastName;
    ...
}
    ,Hibernate        SQL  ,       3。
  3:
create table Client (
        id bigint generated by default as identity (start with 1),
        firstName varchar(255),
        lastName varchar(255),
        ...
        primary key (id)
    );

古い命名規則
データベースの慣例的な約束には十分な理由がありますが、DBAは常に保守的です.開発者はどうすればいいのでしょうか.
簡単な解決策は名前の特徴を使用することです:@Entity、 @Column , , 4:例4:@Entity(name="T_CLIENT") public class Client implements Serializable { ... @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name="CLIENT_ID") private Long id; @Column(name="FIRST_NAME") private String firstName; @Column(name="LAST_NAME") private String lastName; ... } , , 。 , 。 ? , Hibernate 。 , Hibernate 。 ImprovedNamingStrategy , , SomeDomainEntity, some_domain_entity。 Hibernate 。 Spring, bean 。 5 Spring : 5: <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath:/hibernate.cfg.xml" /> <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" /> <property name="namingStrategy" ref="namingStrategy" /> </bean> <bean id="namingStrategy" class="org.hibernate.cfg.ImprovedNamingStrategy"/>このネーミングポリシーの下で、Hibernateは次の例6のようなスクリプトを生成します.
例6:
create table client (
id bigint generated by default as identity (start with 1),
first_name varchar(255),
last_name varchar(255),
...
primary key (id)
);
これでいいですが、あなたの問題を解決することはできません.データベースの命名規則も必要です.たとえば、各テーブルは「T_」からはじめに(例えばT_CLIENTがClientクラス)、
または、テーブル内の各フィールドは、テーブル内の特定の接頭辞(例えば、CLI_FIRST_NAMEおよびCLI_LAST_NAMEと書く)で開始することができる.これらの制約を自動的に生成するために、
あなたは自分の命名戦略を書いて実施します.
カスタムネーミングポリシーの実装
カスタムネーミングポリシーの最も簡単な方法は、ImprovedNamingStrategyクラスを拡張することです.このクラスはユーザーのデフォルトの状況を提供しているので、本当に必要な方法を実現するだけでいいです.
汎用スタイルタスクのテーブル名やカラム名のメソッドを無視することができます.たとえば、名前に大文字を付けることができます.このメソッドは、Hibernateがテーブルまたはカラム名を生成するときに呼び出されます.
このメソッドは、コメントで明示的に指定されたカラム名でも呼び出されます.ImprovedNamingStrategyクラスから継承されたaddUnderscores()メソッドは、役に立ちます.
例7に示すように、
例7:public class MyNamingStrategy extends ImprovedNamingStrategy implements NamingStrategy { @Override public String columnName(String columnName) { return addUnderscores(columnName).toUpperCase(); } @Override public String tableName(String tableName) { return addUnderscores(tableName).toUpperCase(); } } 8, “T_” , 。 8: @Override public String classToTableName(String className) { return "T_" + tableName(className); } @Override public String propertyToColumnName(String propertyName) { return addUnderscores(propertyName).toUpperCase(); }より複雑なネーミングポリシー
ネーミングポリシーインタフェースは実際には簡単ですが、多くの点で制限されています.まず、呼び出しメソッドのパラメータがどのテーブルに属しているかは、特定の時間ではわかりません.
これにより、たとえば、データベースの約束で要求されたように、テーブル内の各カラム名にテーブル接頭辞を付ける必要がある場合に制限されます.classToTable()メソッドで
変数メンバーは、この制限を解決するために現在のテーブルを格納します.指定されたテーブルの場合、このメソッドはpropertyToColunmName()メソッドの後に呼び出されます.たとえば、
例9は、テーブルに3文字の接頭辞を作成し、テーブル名およびテーブル内のすべてのカラム名の前に追加します.
例9:public class MyNamingStrategy extends ImprovedNamingStrategy implements NamingStrategy { private String currentTablePrefix; @Override public String classToTableName(String className) { currentTablePrefix = className.substring(0, 3).toUpperCase() + "_"$$ return "T" + currentTablePrefix + tableName(className); } @Override public String propertyToColumnName(String propertyName) { return currentTablePrefix + addUnderscores(propertyName).toUpperCase(); } @Override public String columnName(String columnName) { return addUnderscores(columnName).toUpperCase(); } @Override public String tableName(String tableName) { return addUnderscores(tableName).toUpperCase(); } }このネーミングポリシーを使用すると、Hibernateは例10のようなコードを生成します.
例10:create table TCLI_CLIENT ( CLI_ID bigint generated by default as identity (start with 1), CLI_FIRST_NAME varchar(255), CLI_LAST_NAME varchar(255), ... primary key (CLI_ID) ); , 。 ,Hibernate “ FKAB1273D65CCF7AB ” , DBA 。 , @ForeignKey , 11 : 11: @Entity public class Order { ... @JoinColumn(name = "CLIENT_ID") @ManyToOne(optional = false) @ForeignKey(name = "FK_CLIENT_ORDERS") private Client client; ... } , ( ), 。 , 12 SocialNerworker , 。 , @JoinTable,@ForeignKey 。 12: @Entity public class SocialNetworker { @ManyToMany @JoinTable(name = "TFRD_FRIEND", joinColumns = {@JoinColumn(name = "NETWORKER_ID") }, inverseJoinColumns = {@JoinColumn(name = "FRIEND_ID") } ) @ForeignKey(name = "FK_SNT_FRIENDS", inverseName="FK_FRD_FRIENDS") } private Set<SocialNetworker> friends = new HashSet<SocialNetworker>(); ... }SQLスクリプトの表示
データベースを変更または更新する必要がある場合、データベース管理者は職責上慎重で、実行するSQLスクリプトを見る可能性があります.HibernateはSchemaExportツールを使用することができます.
SQLスクリプトを表示します.このツールを使用して、完了するモードを通常のSQLスクリプトに生成します.
もちろん、このような操作は構築プロセスの一部としてはしたくありません.Mavenを使用する場合は、Hibernate 3-maven-pluginを使用してデータベース・アーキテクチャを自動的に生成します.重要な部分は、例13に示すように、dropとexportをfalseに設定することで、データベース資料が更新されていないことに相当します.
例13:<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>hibernate3-maven-plugin</artifactId> <version>2.1</version> <executions> <execution> <phase>process-classes</phase> <goals> <goal>hbm2ddl</goal> </goals> </execution> </executions> <configuration> <components> <component> <name>hbm2ddl</name> <implementation>annotationconfiguration</implementation> </component> <component> <name>hbmdoc</name> </component> </components> <componentProperties> <configurationfile>/target/classes/hibernate.cfg.xml</configurationfile> <outputfilename>schema.ddl</outputfilename> <namingstrategy>mycompany.myapp.IRDNamingStrategy</namingstrategy> <drop>false</drop> <create>true</create> <export>false</export> <format>true</format> </componentProperties> </configuration> </plugin>これでSQLスクリプトが生成され、DBAたちに見せることができます.
まとめ
DBAの命名慣例は残されており、彼らと一緒に仕事をする場合は、これらの慣例を考慮する必要があります.幸いなことに、これはあなたがHibernateの自動生成を放棄するという意味ではありません.
データベースアーキテクチャは、SQLスクリプトを自分で書く必要もありません.結合したネーミング戦略で、あなたはウィンウィンを獲得します.