About

ドキュメント

プロジェクト文書

Built by Maven

概要

Entity(エンティティ)は、データベースのテーブルやクエリの結果セットに対応します。

このページで説明するアノテーションはすべてorg.seasar.domaパッケージに属します。

エンティティ定義

エンティティクラスは @Entityが注釈された非privateなクラスとして定義します。 クラスはトップレベルのクラスでなければいけません(他のクラスやインタフェースにネストされていてはいけません)。 エンティティクラスは abstractであってはいけません。 エンティティクラスからは、フレームワークの内部で使用されるクラスがaptによりコンパイル時に自動生成されます。

@Entity
public class Employee {
    ...
}

エンティティがデータベースに対し挿入、更新、削除される直前に処理を実行したい場合、 listener 要素に org.seasar.doma.jdbc.entity.EntityListener の実装クラスを指定できます。

@Entity(listener = EntityListener.class)
public class Employee {
    ...
}
public class EmployeeEntityListener implements EntityListener<Employee> {
    @Override
    public void preDelete(Employee entity) {
        ...
    }
    @Override
    public void preInsert(Employee entity) {
        ...
    }
    @Override
    public void preUpdate(Employee entity) {
        ...
    }
}

EntityListenerの実装クラスはpublicなデフォルトコンストラクタ(引数なしのコンストラクタ)を持たねばいけません。

テーブル

エンティティに対応するテーブル情報を指定するには、 @Table を使用します。

name要素でテーブル名を指定できます。

@Entity
@Table(name = "EMP")
public class Employee {
    ...
}

catalog要素や schema要素 でカタログやスキーマを指定できます。

@Entity
@Table(catalog = "CATALOG", schema ="SCHEMA", name = "EMP")
public class Employee {
    ...
}

@Tableを使用しない、もしくは @Tablename要素を使用しない場合、 テーブル名は、org.seasar.doma.jdbc.NamingConventionの実装クラスにより解決されます。 NamingConventionの実装クラスは設定で決まります。

継承

任意のクラスを継承できます。

ただし、親クラスのフィールドが永続フィールドとみなされたりDomaのアノテーションが解釈されたりするのは、親クラスが@Entityで注釈されている場合だけです。

フィールド定義

フィールドの可視性を フィールドの可視性をpublicにして直接アクセスすることもできます。

永続的なフィールド

永続的なフィールドは、テーブルや結果セットのカラムに対応します。

フィールドの型は、基本型もしくは@Domainが注釈されたクラスでなければいけません。 フィールドの可視性は非privateでなければいけません。

@Entity
public class Employee {
    ...
    Integer employeeId;
}

カラム

プロパティに対応するカラム情報を指定するには、@Columnを使用します。

name要素でカラム名を指定できます。

@Column(name = "ENAME")
String employeeName;

insertable要素や updatable要素 で挿入や更新の対象とするかどうかを指定できます。

@Column(insertable = false, updatable = false)
String employeeName;

@Columnを使用しない、もしくは@Columnname要素を使用しない場合、 カラム名は、org.seasar.doma.jdbc.NamingConventionの実装クラスにより解決されます。 NamingConventionの実装クラスは設定で決まります。

識別子

識別子(主キー)であることを指定するには、@Idを使います。

@Id
Integer id;

複合主キーの場合は @Id を複数指定します。

@Id
Integer id;

@Id
Integer id2;

識別子を自動生成する場合は、@GeneratedValueを使用し、 生成方法をstrategy要素に指定します。 このアノテーションが注釈されるフィールドの型は数値のプリミティブ型、 もしくはNumberのサブタイプでなければいけません。

strategy 要素に指定できる方法は、次の3つです。

  • GenerationType.IDENTITY
  • GenerationType.SEQUENCE
  • GenerationType.TABLE
GenerationType.IDENTITY

データベースのIDENTITY自動生成機能を利用する方法です。RDBMSによってはサポートされていません。 フィールドに対応するカラムの定義でIDENTITY自動生成を有効にしておく必要があります。

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Integer id;

GenerationType.SEQUENCE

データベースのシーケンスを利用する方法です。RDBMSによってはサポートされていません。

GenerationType.SEQUENCEを使用するには、 @SequenceGeneratorを併記します。 @SequenceGeneratorでは、シーケンスの名前、割り当てサイズ、初期値等を設定できます。 データベースにあらかじめシーケンスを定義しておく必要がありますが、その定義は@SequenceGeneratorの定義とあわせておく必要があります。

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@SequenceGenerator(sequence = "EMPLOYEE_SEQ")
Integer id;
GenerationType.TABLE

生成される識別子をテーブルで管理する方法です。すべてのRDBMSで利用できます。

GenerationType.TABLEを使用するには、 @TableGeneratorを併記します。 @TableGeneratorでは、テーブル名、割り当てサイズ、初期値等を設定できます。 データベースにあらかじめテーブルを定義しておく必要がありますが、その定義は@TableGeneratorの定義とあわせておく必要があります。 デフォルトでは、「ID_GENERATOR」という名前のテーブルに、文字列型の「PK」と数値型の「VALUE」という2つのカラムが定義されているものとして動作します(「PK」カラムが主キーです)。 「PK」カラムにはエンティティクラスごとの一意な名前、「VALUE」カラムには識別子の値が格納されます。 テーブルには、エンティティクラスごとのレコードをあらかじめ登録しておく必要があります。

@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@TableGenerator(pkColumnValue = "EMPLOYEE_ID")
Integer id;

@TableGeneratorpkColumnValue要素には、 識別子を管理するテーブル(デフォルトでは、「ID_GENERATOR」という名前のテーブル)の主キーの値を指定します。

バージョン

楽観的排他制御用のバージョンは@Versionを注釈して示します。

フィールドの型は数値のプリミティブ型 もしくはNumberのサブタイプでなければいけません。

@Version
Integer version;

非永続的なフィールド

非永続的なフィールドは、テーブルや結果セットのカラムに対応しません。

@Transientを注釈して示します。 フィールドの型や可視性に制限はありません。

@Transient
BigDecimal tempSalary;
@Transient
List<String> nameList;

変更されたフィールドを管理するフィールド

変更されたフィールドを管理するフィールドは、テーブルや結果セットのカラムに対応しません。 変更されたフィールドを管理することで、Daoインタフェースの@Updateが注釈されたメソッドを介して更新処理を実行する際、 UPDATE文のSET句に変更したフィールドのみを含めるようにすることが可能です。

@ChangedPropertiesを注釈して示します。 フィールドの型はjava.util.Set<String>でなければいけません。 フィールドの可視性は非privateでなければいけません。

@ChangedProperties
Set<String> chagendProperties = new HashSet<String>();

変更されたフィールドの名前を@ChangedPropertiesが注釈されたSetに追加するのはアプリケーション開発者の責任です。 フィールド名の追加は、永続的なフィールドに対応するsetterメソッドで行うのが適切です。

public void setEmployeeId(Integer employeeId) {
    chagendProperties.add("employeeId"); // フィールド名を@ChangedPropertiesが注釈されたSetに追加
    this.employeeId = employeeId;
}

メソッド定義

メソッドの定義に制限はありません。 フィールドの可視性をprotectedやパッケージプライベートにしてメソッド経由でアクセスすることも、 publicにして直接アクセスすることもどちらもサポートされています。 ただし、@ChangedPropertiesを利用する場合は、メソッド経由のアクセスをすべきです。

エンティティの利用方法

インスタンス化して使用します。

Employee employee = new Employee();
employee.setEmployeeId(1);
employee.setEmployeeName("SMITH");
employee.setSalary(new BigDecimal(1000);

エンティティはテーブルに1対1で対応させなければいけないわけではありません。 たとえば、EMPLOYEEテーブルとDEPARTMENTテーブルを結合した結果もエンティティにマッピングできます。 そのエンティティクラスをEmpDeptDtoした場合のエンティティクラスの定義とDaoインタフェースの定義は次のとおりです。

@Entity
public class EmpDeptDto {
    String employeeName;
    String departmentName;
}
@Dao
public interface EmployeeDao {
    @Select
    EmpDeptDto selectByDepartmentId(Integer departmentId);
}