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:
プロパティを「create-drop」に設定すると、アプリケーションを起動するたびに新しいデータベースが生成され、統合テストに役立ちますが、必要ない場合があります.一方、この値を更新するために設定した場合、データベースが存在しない場合、Hibernateは自動的にデータベースを作成し、現在のドメインモデルに一致するすべてのテーブルを更新します.
デフォルトでは、HibernateはJavaクラスに似たテーブルとフィールドを作成し、Java開発者の観点から要求に合っています.次の例を考えます.
例2:A simple persistent class
古い命名規則
データベースの慣例的な約束には十分な理由がありますが、DBAは常に保守的です.開発者はどうすればいいのでしょうか.
簡単な解決策は名前の特徴を使用することです:
例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:
ネーミングポリシーインタフェースは実際には簡単ですが、多くの点で制限されています.まず、呼び出しメソッドのパラメータがどのテーブルに属しているかは、特定の時間ではわかりません.
これにより、たとえば、データベースの約束で要求されたように、テーブル内の各カラム名にテーブル接頭辞を付ける必要がある場合に制限されます.classToTable()メソッドで
変数メンバーは、この制限を解決するために現在のテーブルを格納します.指定されたテーブルの場合、このメソッドはpropertyToColunmName()メソッドの後に呼び出されます.たとえば、
例9は、テーブルに3文字の接頭辞を作成し、テーブル名およびテーブル内のすべてのカラム名の前に追加します.
例9:
例10:
データベースを変更または更新する必要がある場合、データベース管理者は職責上慎重で、実行するSQLスクリプトを見る可能性があります.HibernateはSchemaExportツールを使用することができます.
SQLスクリプトを表示します.このツールを使用して、完了するモードを通常のSQLスクリプトに生成します.
もちろん、このような操作は構築プロセスの一部としてはしたくありません.Mavenを使用する場合は、Hibernate 3-maven-pluginを使用してデータベース・アーキテクチャを自動的に生成します.重要な部分は、例13に示すように、dropとexportをfalseに設定することで、データベース資料が更新されていないことに相当します.
例13:
まとめ
DBAの命名慣例は残されており、彼らと一緒に仕事をする場合は、これらの慣例を考慮する必要があります.幸いなことに、これはあなたがHibernateの自動生成を放棄するという意味ではありません.
データベースアーキテクチャは、SQLスクリプトを自分で書く必要もありません.結合したネーミング戦略で、あなたはウィンウィンを獲得します.
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スクリプトを自分で書く必要もありません.結合したネーミング戦略で、あなたはウィンウィンを獲得します.