概要
S2JDBC-Genでは、Gen-Ddl タスクを実行することで、エンティティ定義からDDLを出力できます。 ここでは、DDLの生成に大きく関わるエンティティクラスの定義方法を説明します。
Gen-Ddl タスク生成できるDDLの種類には限りがあります。 ストアドプロシージャー、トリガー、ビューなどのDDLを扱うには、Migrate タスクの任意のSQLの実行 を参照してください。
S2JDBC実行時に関するエンティティ定義についてはエンティティ を参照してください。
テーブル定義
テーブルの定義はTableアノテーションを用いて行います。
カタログ名、スキーマ名、テーブル名は、Gen-Ddl タスクで生成されるDDLファイルやダンプファイルの名前に使用されます。 したがって、カタログ名、スキーマ名、テーブル名にファイルシステムで扱えない文字を含めないでください。
カタログ名
catalog要素を使用することで、カタログ名を指定できます。
@Table(catalog = "CATALOG") public class Employee { .... }
上記の定義からは次のDDLが生成されます。
create table CATALOG.EMPLOYEE ...;
スキーマ名
schema要素を使用することで、スキーマ名を指定できます。
@Table(schema = "SCHEMA") public class Employee { .... }
上記の定義からは次のDDLが生成されます。
create table SCHEMA.EMPLOYEE ...;
テーブル名
name要素を使用することで、テーブル名を指定できます。
@Table(name = "EMP") public class Employee { .... }
上記の定義からは次のDDLが生成されます。
create table EMP ...;
指定しない場合、テーブル名はエンティティ名と同じになります。
ただし、エンティティ名が、
AaaBbb
のようなキャメル記法の場合、テーブル名は、
AAA_BBB
のように
'_'
区切りだとみなされます。
このルールは、
convention.dicon
で指定されている
org.seasar.framework.convention.impl.PersistenceNamingConventionImpl
の
fromEntityNameToTableName()
の実装を変えることで、カスタマイズできます。
複合一意キー
uniqueConstraints要素を使用することで、複合一意キー制約を指定できます。 (columnNames要素に指定する値を1つにすれば、単一の一意キー制約になります。)
@Table(uniqueConstraints = { @UniqueConstraint(columnNames = { "FIRST_NAME", "LAST_NAME" }) }) public class Employee { .... }
alter table EMPLOYEE add constraint EMPLOYEE_UK1 unique (FIRST_NAME, LAST_NAME);
カラム定義
カラムの定義はColumnアノテーションを用いて行います。
カラム名
name要素を使用することで、カラム名を指定できます。
@Column(name = "ENAME") public String employeeName;
上記の定義からは次のDDLが生成されます。
create table ... ( ... ENAME varchar(255), ... );
指定しない場合、カラム名はフィールド名と同じになります。
ただし、フィールド名が、
aaaBbb
のようなキャメル記法の場合、カラム名は、
AAA_BBB
のように
'_'
区切りだとみなされます。
このルールは、
convention.dicon
で指定されている
org.seasar.framework.convention.impl.PersistenceNamingConventionImpl
の
fromPropertyNameToColumnName()
の実装を変えることで、カスタマイズすることができます。
デフォルトでは、プロパティ名とフィールド名は同じになりますが、
convention.dicon
で指定されている
org.seasar.framework.convention.impl.PersistenceNamingConventionImpl
の
fromFieldNameToPropertyName()
の実装を変えることで、カスタマイズすることができます。
一意キー
一意キー制約を指定するにはunique要素を使用します。
@Column(unique = true) public String employeeName;
上記の定義からは次のDDLが生成されます。
create table ... ( ... EMPLOYEE_NAME varchar(100), ... );
alter table EMPLOYEE add constraint EMPLOYEE_UK1 unique (EMPLOYEE_NAME);
NOT NULL制約
NOT NULL制約を指定するにはnullable要素を使用します。
@Column(nullable = false) public String employeeName;
上記の定義からは次のDDLが生成されます。
create table ... ( ... EMPLOYEE_NAME varchar(100) not null, ... );
データ型
カラムのデータ型は長さのデフォルト値や2JDBC-Genのダイアレクトに従って自動で決定されます。 長さ、精度、スケールを指定する場合やデータ型を明記する場合は、Columnアノテーションを使用します。
@Column(length = 20) public String employeeName; @Column(precision = 10, scale = 2) public BigDecimal salary;
上記の定義により、EMPLOYEE_NAMEカラムは長さ20の文字列型、 SALARYカラムは精度が10、スケールが2の数値型として定義されます。 Columnアノテーションを指定しない場合や、length、precision、scaleを指定しない場合のそれぞれのデフォルト値は次の表のとおりです。
要素 | 説明 | デフォルト値 |
---|---|---|
length | 長さ。文字列型やバイナリ型に使用される。 | 255 |
precision | 精度。数値型に使用される。 | 19 |
scale | スケール。数値型に使用される。 | 2 |
以下に、エンティティクラスのプロパティの型と代表的なデータベースのカラムの型の対応表を示します。 $l、$p、$sには、Columnアノテーションで指定するlength、precision、scaleの値が設定されます。 (この表は、エンティティからDDLを生成する際の対応表です。データベースからエンティティを生成する際の対応表ではありません。)
Javaの型 | Oracle Database | SQL Server 2005 | DB2 | PostgreSQL | MySQL |
---|---|---|---|---|---|
boolean/Boolean | number(1,0) | bit | smallint | bool | boolean |
short/Short | number($p,0) | smallint | smallint | smallint | smallint |
char/Character | char(1) | char(1) | char(1) | char(1) | char(1) |
int/Integer | number($p,0) | int | integer | integer/serial | int |
long/Long | number($p,0) | bigint | bigint | bigint/bigserial | bigint |
float/Float | float | float | real | float4 | float($p,$s) |
double/Double | double precision | double | double | float8 | double($p,$s) |
BigInteger | number($p,0) | bigint | bigint | bigint/bigserial | bigint |
BigDecimal | number($p,$s) | decimal($p,$s) | decimal($p,$s) | decimal($p,$s) | decimal($p,$s) |
String | varchar2($l) | varchar($l) | varchar($l) | varchar($l) | varchar($l) |
@LobつきString | clob | varchar(max) | clob($l) | text | tinytext/text/mediumtext/longtext |
byte[] | raw | varbinary($l) | varchar($l) for bit data | bytea | binary($l) |
@Lobつきbyte[] | blob | varbinary(max) | blob($l) | oid | tinyblob/blob/mediumblob/longblob |
Serializable | raw | varbinary($l) | varchar($l) for bit data | bytea | binary($l) |
@LobつきSerializable | blob | varbinary(max) | blob($l) | oid | tinyblob/blob/mediumblob/longblob |
java.sql.Time | date | datetime | time | time | time |
java.sql.Date | date | datetime | date | date | date |
java.sql.Timestamp | timestamp | datetime | timestamp | timestamp | timestamp |
@Temporal(TeporalType.TIME)つきjava.util.Date, @Temporal(TeporalType.TIME)つきCalendar |
date | datetime | time | time | time |
@Temporal(TeporalType.DATE)つきjava.util.Date, @Temporal(TeporalType.DATE)つきCalendar |
date | datetime | date | date | date |
@Temporal(TeporalType.TIMESTAMP)つきjava.util.Date, @Temporal(TeporalType.TIMESTAMP)つきCalendar |
date | datetime | timestamp | timestamp | timestamp |
Enum型, @Enumerated(EnumType.ORDINAL)つきEnum型 | number($p,0) | int | integer | integer | int |
@Enumerated(EnumType.STRING)つきEnum型 | varchar2($l) | varchar($l) | varchar($l) | varchar($l) | int/varchar($l) |
ここで示されたもの以外のデータ型にマッピングしたい場合は、ColumnアノテーションのcolumnDefinition要素を使用します。
@Column(columnDefinition ="nvarchar(100)") public String employeeName;
columnDefinition要素を使用した場合は、指定した値がそのままテーブル作成のDDLに組み込まれます。 そのため、length、precision、scale要素の値は、参照されません。
上記の定義からは次のDDLが生成されます。
create table ... ( ... EMPLOYEE_NAME nvarchar(100), ... );
デフォルト値
デフォルト値を指定するにはcolumnDefinition要素を使用します。
@Column(columnDefinition ="default 'unknown'") public String employeeName;
上記の定義からは次のDDLが生成されます。
create table ... ( ... EMPLOYEE_NAME varchar(255) default 'unknown', ... );
columnDefinition要素にデータ型を指定する場合は、その値の後ろに指定します。
@Column(columnDefinition ="nvarchar(100) default n'unknown'") public String employeeName;
上記の定義からは次のDDLが生成されます。
create table ... ( ... EMPLOYEE_NAME nvarchar(100) default n'unknown', ... );
CHECK制約
CHECK制約を指定するにはcolumnDefinition要素を使用します。
@Column(columnDefinition ="check ...") public String employeeName;
上記の定義からは次のDDLが生成されます。
create table ... ( ... EMPLOYEE_NAME varchar(255) check ..., ... );
columnDefinition要素にデータ型を指定する場合は、その値の後ろに指定します。
@Column(columnDefinition ="nvarchar(100) check ...") public String employeeName;
上記の定義からは次のDDLが生成されます。
create table ... ( ... EMPLOYEE_NAME nvarchar(100) check ..., ... );
主キー定義
主キーの定義はIdアノテーションを用いて行います。
@Entity public class Employee { @Id public Integer id; ... }
上記の定義からは次のDDLが生成されます。
create table Employee ( ID integer not null, ... constraint EMPLOYEE_PK primary key(ID) );
複合主キーの場合はIdアノテーションを複数用います。
@Entity public class Employee { @Id public Integer id1; @Id public Integer id2; ... }
上記の定義からは次のDDLが生成されます。
create table Employee ( ID1 integer not null, ID2 integer not null, ... constraint EMPLOYEE_PK primary key(ID1, ID2) );
主キーのプロパティに指定された@Columnのunique要素やnullabl要素の値は使用されません。
主キーの自動生成に関する定義
主キーの自動生成に関する定義はGeneratedValueアノテーションを用いて行います。
データベース固有の自動生成を利用する定義
データベース固有の自動生成を利用するには、GeneratedValueのstrategy要素にGenerationType.IDENTITYを指定します。 データベースがデータベース固有の自動生成をサポートしている場合にのみ使用できます。
@Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) public Integer id; ... }
MySQLでは、上記の定義からは次のDDLが生成されます。
create table EMPLOYEE ( ID int not null auto_increment, ... );
テーブルを利用する定義
テーブルを利用するには、GeneratedValueのstrategy要素にGenerationType.TABLEを指定します。
@Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.TABLE) public Integer id; ... }
Oracleでは、上記の定義からは次のDDLが生成されます。このDDLは、EMPLOYEEテーブルに関するDDLとは別に生成されます。
create table ID_GENERATOR ( PK varchar2(255) not null, VALUE number(19, 0) not null, constraint ID_GENERATOR_PK primary key(PK) );
TableGeneratorアノテーションを使ってテーブル名やカラム名をカスタマイズできます。
@Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.TABLE, generator = "EMPLOYEE_GEN") @TableGenerator( name = "EMPLOYEE_GEN", table = "ID_GEN", pkColumnName = "GEN_NAME", valueColumnName = "GEN_VALUE") public Integer id; ... }
Oracleでは、上記の定義からは次のDDLが生成されます。
create table ID_GEN ( GEN_NAME varchar2(255) not null, GEN_VALUE number(19, 0) not null, constraint ID_GENERATOR_PK primary key(PK) );
シーケンスを利用する定義
シーケンスを利用するには、GeneratedValueのstrategy要素にGenerationType.SEQUENCEを指定します。 データベースがシーケンスをサポートしている場合にのみ使用できます。
@Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.SEQUENCE) public Integer id; ... }
Oracleでは、上記の定義からは次のDDLが生成されます。
create sequence EMPLOYEE_ID increment by 50 start with 1;
SequenceGeneratorアノテーションを使ってシーケンス名や初期値や割り当てサイズをカスタマイズできます。
@Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.TABLE, generator = "EMPLOYEE_GEN") @SequenceGenerator( name = "EMPLOYEE_GEN", sequenceName = "EMPLOYEE_SEQ" initialValue = 100 allocationSize = 10) public Integer id; ... }
Oracleでは、上記の定義からは次のDDLが生成されます。
create sequence EMPLOYEE_SEQ increment by 10 start with 100;
外部キー定義
生成の制御
外部キーの定義は関連プロパティに対応して生成されますが、定義方法は、外部キー制約の自動生成を有効にしているか無効にしているかで異なります。
全てのエンティティに対する有効/無効はGen-Ddlタスク のautoGenerateForeignKey属性で制御します。 デフォルトでは有効です。 無効にするには、外部キー制約の自動生成を無効化する を参照してください。
個々の関連プロパティごとに外部キー制約の生成を制御するには、org.seasar.extension.jdbc.annotation.ReferentialConstraint
アノテーションのenable
要素を利用します。
自動生成が有効な場合
自動生成が有効な場合、関連の所有側のプロパティに対応するカラムはすべて外部キーとみなされます。
@Entity public class Employee { @Id public Integer id; public Integer departmentId; public Integer addressId; @ManyToOne public Department department; @OneToOne public Address address; }
上記の定義からは、departmentプロパティに対応するDEPARTMENT_IDカラムと addressプロパティに対応するADDRESS_IDカラムがそれぞれ外部キーとみなされ次のDDLが生成されます。
alter table EMPLOYEE add constraint EMPLOYEE_FK1 foreign key (DEPARTMENT_ID) references DEPARTMENT (ID); alter table EMPLOYEE add constraint EMPLOYEE_FK2 foreign key (ADDRESS_ID) references ADDRESS (ID);
複合外部キー制約を生成するにはJoinColumnsアノテーションを使用します。
@Entity public class Employee { @Id public Integer id; public Integer departmentId1; public Integer departmentId2; @ManyToOne @JoinColumns( { @JoinColumn(name = "DEPARTMENT_ID1", referencedColumnName = "ID1"), @JoinColumn(name = "DEPARTMENT_ID2", referencedColumnName = "ID2") }) public Department department; }
上記の定義からは次のDDLが生成されます。
alter table EMPLOYEE add constraint EMPLOYEE_FK1 foreign key (DEPARTMENT_ID1, DEPARTMENT_ID2) references DEPARTMENT (ID1, ID2);
関連プロパティに@ReferentialConstraintを指定しenable要素をfalseに指定することで、特定の外部キー制約の生成を抑制できます。
@Entity public class Employee { @Id public Integer id; public Integer departmentId; public Integer addressId; @ManyToOne public Department department; @ReferentialConstraint(enable = false) @OneToOne public Address address; }
addressプロパティに指定された@ReferentialConstraint(enable = false)
に注目してください。
上記の定義では、DEPARTMENT_IDだけが外部キーとなりADDRESS_IDは外部キーになりません。
したがって、生成されるDDLは次のものになります。
alter table EMPLOYEE add constraint EMPLOYEE_FK1 foreign key (DEPARTMENT_ID) references DEPARTMENT (ID);
同様に複合外部キー制約の生成も抑制できます。
@Entity public class Employee { @Id public Integer id; public Integer departmentId1; public Integer departmentId2; @ReferentialConstraint(enable = false) @ManyToOne @JoinColumns( { @JoinColumn(name = "DEPARTMENT_ID1", referencedColumnName = "ID1"), @JoinColumn(name = "DEPARTMENT_ID2", referencedColumnName = "ID2") }) public Department department; }
この例では、departmentプロパティに指定された@ReferentialConstraint(enable = false)
により、外部キー制約のDDLは生成されません。
自動生成が無効な場合
自動生成が無効な場合、@ReferentialConstraint
を明示的に指定しない限り、外部キー制約の生成は行われません。
@Entity public class Employee { @Id public Integer id; public Integer departmentId; public Integer addressId; @ManyToOne public Department department; @ReferentialConstraint @OneToOne public Address address; }
addressプロパティに指定された@ReferentialConstraint
に注目してください。
(@ReferentialConstraint
は、@ReferentialConstraint(enable = true)
と記述することもできます。)
上記の定義では、ADDRESS_IDだけが外部キーとなりDEPARTMENT_IDは外部キーになりません。
次のDDLが生成されます。
alter table EMPLOYEE add constraint EMPLOYEE_FK1 foreign key (ADDRESS_ID) references ADDRESS (ID);
@ReferentialConstraint
を使って複合外部キー制約の生成を指定することも可能です。
@Entity public class Employee { @Id public Integer id; public Integer departmentId1; public Integer departmentId2; @ReferentialConstraint @ManyToOne @JoinColumns( { @JoinColumn(name = "DEPARTMENT_ID1", referencedColumnName = "ID1"), @JoinColumn(name = "DEPARTMENT_ID2", referencedColumnName = "ID2") }) public Department department; }
上記の定義からは次のDDLが生成されます。
alter table EMPLOYEE add constraint EMPLOYEE_FK1 foreign key (DEPARTMENT_ID1, DEPARTMENT_ID2) references DEPARTMENT (ID1, ID2);
参照動作
ReferentialConstraintアノテーションのonDelete要素やonUpdate要素に
参照動作を表す列挙型org.seasar.extension.jdbc.annotation.ReferentialActionType
を指定できます。
ReferentialActionType
は、SQL99で定められた5つの参照動作を定義します。
データベースによっては、すべての参照動作がサポートされていないことに注意してください。
@Entity public class Employee { @Id public Integer id; public Integer departmentId; public Integer addressId; @ReferentialConstraint(onDelete = ReferentialActionType.CASCADE, onUpdate = ReferentialActionType.RESTRICT) @ManyToOne public Department department; @OneToOne public Address address; }
departmentプロパティに指定された@ReferentialConstraint
に注目してください。
上記の定義からは、次のDDLが生成されます。
alter table EMPLOYEE add constraint EMPLOYEE_FK1 foreign key (DEPARTMENT_ID) references DEPARTMENT (ID) on delete cascade on update restrict;
コメント定義
JavaDocコメントをデータベースのテーブルやカラムに対するコメントとして使用できます。 サポートしているデータベースは、Oracle、DB2、PostgreSQL、MySQL、H2です。 この機能を利用するには、エンティティのJavaDocコメントをテーブル作成用のDDLファイルに反映させる例 を参照してください。
クラスのJavaDocコメントがテーブル、フィールドのJavaDocコメントがカラムに対するコメントになります。
/** * 従業員 */ @Entity public class Employee { /** 主キー */ @Id public Integer id; /** 従業員名 */ public Integer employeeName; }
Oracleでは、上記の定義からは次のDDLが生成されます。
comment on table EMPLOYEE is '従業員'; comment on column EMPLOYEE.ID is '主キー'; comment on column EMPLOYEE.EMPLOYEE_NAME is '従業員名';