Entity(エンティティ)は、データベースのテーブルやクエリの結果セットに対応します。
このページで説明するアノテーションはすべてorg.seasar.doma
パッケージに属します。
エンティティクラスは @Entity
が注釈されたクラスとして定義します。
クラスはトップレベルのクラスでなければいけません(他のクラスやインタフェースにネストされていてはいけません)。
エンティティクラスは 非private
なデフォルトコンストラクタ(引数なしのコンストラクタ)を持たなければいけません。
エンティティがデータベースに対し挿入、更新、削除される直前/直後に処理を実行したい場合、
listener
要素に org.seasar.doma.jdbc.entity.EntityListener
の実装クラスを指定できます。
listener
要素に何も指定しない場合、エンティティクラスが他のエンティティクラスを継承しているかどうかで採用する設定が変わります。
org.seasar.doma.jdbc.entity.NullEntityListener
が使用されます)
EntityListener
は、preDelete
、preInsert
、preUpdate
、postDelete
、postInsert
、postUpdate
の6つのメソッドをもったインタフェースです。
@Delete
、または@BatchDelete
が注釈されたDaoメソッドでパラメータにエンティティが含まれる場合、削除処理の直前に呼び出されます。
ただし、使用するエンティティクラスにエンティティリスナーが指定されている必要があります。
@Insert
、または@BatchInsert
が注釈されたDaoメソッドでパラメータにエンティティが含まれる場合、挿入処理の直前に呼び出されます。
ただし、使用するエンティティクラスにエンティティリスナーが指定されている必要があります。
@Update
、または@BatchUpdate
が注釈されたDaoメソッドでパラメータにエンティティが含まれる場合、更新処理の直前に呼び出されます。
ただし、使用するエンティティクラスにエンティティリスナーが指定されている必要があります。
@Delete
、または@BatchDelete
が注釈されたDaoメソッドでパラメータにエンティティが含まれる場合、削除処理の直後に呼び出されます。
ただし、使用するエンティティクラスにエンティティリスナーが指定されている必要があります。
@Insert
、または@BatchInsert
が注釈されたDaoメソッドでパラメータにエンティティが含まれる場合、挿入処理の直後に呼び出されます。
ただし、使用するエンティティクラスにエンティティリスナーが指定されている必要があります。
@Update
、または@BatchUpdate
が注釈されたDaoメソッドでパラメータにエンティティが含まれる場合、更新処理の直後に呼び出されます。
ただし、使用するエンティティクラスにエンティティリスナーが指定されている必要があります。
EntityListener
は次のように実装できます。
EntityListener
の各メソッドの2番目のパラメータは挿入、更新、削除が行われた場合のコンテキスト情報です。
このコンテキスト情報には、エンティティのメタクラス、Daoのメソッド、Daoの設定が含まれます。
たとえば、Daoのメソッドに独自のアノテーションをつけておくと、そのアノテーションの有無を見て特定のプロパティを更新するといったことが可能です。
EntityListener
の実装クラスはpublicなデフォルトコンストラクタ(引数なしのコンストラクタ)を持たねばいけません。
エンティティに対応するテーブル名やプロパティに対応するカラム名を解決するためのネーミング規約を変更したい場合、
naming
要素に org.seasar.doma.jdbc.entity.NamingType
の列挙型を指定できます。
naming
要素に何も指定しない場合、エンティティクラスが他のエンティティクラスを継承しているかどうかで採用する設定が変わります。
org.seasar.doma.jdbc.entity.NamingType.NONE
が使用されます)
NamingType.SNAKE_UPPER_CASE
は、エンティティ名やプロパティ名をスネークケース(アンダースコア区切り)の大文字に変換します。この例の場合、テーブル名はEMPLOYEE_INFO
になります。
naming
要素に何も指定しない場合、デフォルトでは、テーブル名にはエンティティクラスの単純名、カラム名にはプロパティ名が使用されます。
ネーミング規約は、@Table
や@Colum
のname
要素が指定されない場合のみ使用されます。
@Table
や@Colum
のname
要素が指定された場合は、name
要素に指定した値が使用され、ネーミング規約は適用されません。
NamingType
には次の列挙定数があります。
列挙定数 | 説明 |
---|---|
NONE | 何も行いません。 |
SNAKE_UPPER_CASE | キャメルケースをスネークケース(アンダースコア区切り)の大文字に変換します。 |
SNAKE_LOWER_CASE | キャメルケースをスネークケース(アンダースコア区切り)の小文字に変換します。 |
UPPER_CASE | 大文字に変換します。 |
LOWER_CASE | 小文字に変換します。 |
エンティティに対応するテーブル情報を指定するには、 @Table
を使用します。
name
要素でテーブル名を指定できます。
catalog
要素や schema
要素 でカタログやスキーマを指定できます。
@Table
を使用しない、もしくは @Table
のname
要素を使用しない場合、
テーブル名は、ネーミング規約により解決されます。
任意のクラスを継承できます。
ただし、親クラスのフィールドが永続フィールドとみなされたりDomaのアノテーションが解釈されたりするのは、親クラスが@Entityで注釈されている場合だけです。
永続的なフィールドは、テーブルや結果セットのカラムに対応します。
プロパティに対応するカラム情報を指定するには、@Column
を使用します。
name
要素でカラム名を指定できます。
insertable
要素や updatable
要素 で挿入や更新の対象とするかどうかを指定できます。
@Column
を使用しない、もしくは@Column
の name
要素を使用しない場合、
カラム名は、ネーミング規約により解決されます。
識別子(主キー)であることを指定するには、@Id
を使います。
複合主キーの場合は @Id
を複数指定します。
識別子を自動生成する場合は、@GeneratedValue
を使用し、
生成方法をstrategy
要素に指定します。
このアノテーションが注釈されるフィールドの型は数値のプリミティブ型、
もしくはNumber
のサブタイプでなければいけません。
strategy
要素に指定できる方法は、次の3つです。
GenerationType.IDENTITY
GenerationType.SEQUENCE
GenerationType.TABLE
GenerationType.IDENTITY
データベースのIDENTITY自動生成機能を利用する方法です。RDBMSによってはサポートされていません。 フィールドに対応するカラムの定義でIDENTITY自動生成を有効にしておく必要があります。
GenerationType.SEQUENCE
データベースのシーケンスを利用する方法です。RDBMSによってはサポートされていません。
GenerationType.SEQUENCE
を使用するには、
@SequenceGenerator
を併記します。
@SequenceGenerator
では、シーケンスの名前、割り当てサイズ、初期値等を設定できます。
データベースにあらかじめシーケンスを定義しておく必要がありますが、その定義は@SequenceGenerator
の定義とあわせておく必要があります。
GenerationType.TABLE
生成される識別子をテーブルで管理する方法です。すべてのRDBMSで利用できます。
GenerationType.TABLE
を使用するには、
@TableGenerator
を併記します。
@TableGenerator
では、テーブル名、割り当てサイズ、初期値等を設定できます。
データベースにあらかじめテーブルを定義しておく必要がありますが、その定義は@TableGenerator
の定義とあわせておく必要があります。
デフォルトでは、「ID_GENERATOR」という名前のテーブルに、文字列型の「PK」と数値型の「VALUE」という2つのカラムが定義されているものとして動作します(「PK」カラムが主キーです)。
「PK」カラムにはエンティティクラスごとの一意な名前、「VALUE」カラムには識別子の値が格納されます。
テーブルには、エンティティクラスごとのレコードをあらかじめ登録しておく必要があります。
@TableGenerator
のpkColumnValue
要素には、
識別子を管理するテーブル(デフォルトでは、「ID_GENERATOR」という名前のテーブル)の主キーの値を指定します。
楽観的排他制御用のバージョンは@Version
を注釈して示します。
フィールドの型は数値のプリミティブ型
もしくはNumber
のサブタイプでなければいけません。
非永続的なフィールドは、テーブルや結果セットのカラムに対応しません。
@Transient
を注釈して示します。
フィールドの型や可視性に制限はありません。
取得時の状態とは、エンティティがDaoから取得されときの全プロパティの値です。 取得時の状態を保持しておくことで、Daoインタフェースの@Updateが注釈されたメソッドを介して更新処理を実行する際、 UPDATE文のSET句に変更したフィールドのみを含めるようにすることが可能です。 取得時の状態を管理するフィールドは、テーブルや結果セットのカラムに対応しません。
@OriginalStates
を注釈して示します。
フィールドの型はフィールドが属するエンティティクラスと同じ型でなければいけません。
@OriginalStates
が注釈されたフィールドはアプリケーションで初期化したりアクセスしたりしてはいけません。
@OriginalStates
が注釈されたフィールドを持つエンティティの利用法は次のとおりです。
この例では、UPDATE文のSET句にAGEカラムだけが含まれます。
メソッドの定義に制限はありません。
フィールドの可視性をprotected
やパッケージプライベートにしてpublicなメソッド経由でアクセスすることも、
メソッドを一切使用せずpublic
フィールドに直接アクセスすることもどちらもサポートされています。
インスタンス化して使用します。
エンティティはテーブルに1対1で対応させなければいけないわけではありません。
たとえば、EMPLOYEE
テーブルとDEPARTMENT
テーブルを結合した結果もエンティティにマッピングできます。
そのエンティティクラスをEmpDeptDto
とした場合のエンティティクラスの定義とDaoインタフェースの定義は次のとおりです。