概要
Domain(ドメイン)クラスの定義方法を示します。 ドメインとは、値のとり得る範囲(定義域)のことです。 Domaでは、テーブルのカラムの値を、ドメインと呼ばれるJavaオブジェクトで扱います。
ドメインクラスを利用することで、データベース上のカラムの型が同じあってもアプリケーション上意味が異なるものを別のJavaの型で表現できます。 これにより、意味を明確にしプログラミングミスを事前に防ぎやすくなります。 また、ドメインクラスに振る舞いを持たせることで、よりわかりやすいプログラミングが可能です。
ドメインクラスの作成と利用は任意です。
ドメインクラスを利用しなくてもIntegerやStringなど基本型のみでデータアクセスは可能です。
ドメイン定義
ドメインクラスは @Domainを注釈して示します。
@DomainのvalueType要素には、ドメインクラスで扱う基本型を指定します。この基本型が、データベースのカラムの型とのマッピングに使用されます。
accessorMethod要素には、valueType要素に指定した型を返すアクセッサメソッドの名前を指定します。デフォルト値はgetValueです。
以下の例では、 電話番号を表すドメインクラスを作成しています。
package example.domain;
import org.seasar.doma.Domain;
@Domain(valueType = String.class)
public class PhoneNumber {
private final String value;
public PhoneNumber(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public String getAreaCode() {
// ドメインに固有の振る舞いを記述できる。
...
}
}
@Domainが注釈されたクラスはトップレベルのクラスでなければいけません。
クラスには、valueType要素に指定した型と同じ型をもつ非privateなコンストラクタが必須です。
また、accessorMethod要素に指定した値と同じ名前のメソッドも必須です。
任意ですが、ドメインクラスは不変オブジェクトとして作成することを推奨します。
上記の例では、valueフィールドは一度設定されると二度と変更されません。
クラスには、任意のメソッドを持たせることができます。
列挙型を使用したドメイン定義
扱う値があらかじめ定まっている場合は、列挙型をドメインクラスとして扱えます。
列挙型をドメインクラスとして扱うには、 @EnumDomainを注釈して示します。
@EnumDomainのvalueType要素には、ドメインクラスで扱う基本型を指定します。この基本型が、データベースのカラムの型とのマッピングに使用されます。
factoryMethod要素には、valueType要素に指定した型をパラメータとして受け取り、対応する列挙型の値を返すstaticなファクトリメソッドの名前を指定します。
ファクトリメソッドは、データベースの値に対応する列挙型の値を返すメソッドです。
この要素のデフォルト値はofです。
accessorMethod要素には、valueType要素に指定した型を返すアクセッサメソッドの名前を指定します。
アクセッサメソッドは、列挙型の値に対応するデータベースの値を返すメソッドです。
この要素のデフォルト値はgetValueです。
以下の例では、 仕事の種別を表すドメインクラスを作成しています。
package example.domain;
import org.seasar.doma.EnumDomain;
@EnumDomain(valueType = String.class)
public enum JobType {
SALESMAN("10"),
MANAGER("20"),
ANALYST("30"),
PRESIDENT("40"),
CLERK("50");
private final String value;
private JobType(String value) {
this.value = value;
}
static JobType of(String value) {
for (JobType jobType : JobType.values()) {
if (jobType.value.equals(value)) {
return jobType;
}
}
throw new IllegalArgumentException(value);
}
String getValue() {
return value;
}
}
@EnumDomainが注釈された列挙型はトップレベルのクラスでなければいけません。
列挙型には、factoryMethod要素とaccessorMethod要素で指定された値と同じ名前のメソッドが必須です。
また、列挙型には、任意のメソッドを持たせることができます。
利用例
エンティティクラス
エンティティクラスのフィールドの型での利用例です。
@Entity
public class Employee {
@Id
Integer employeeId;
String employeeName;
PhoneNumber phoneNumber;
JobType jobType;
@Version
Integer versionNo();
...
}
Daoインタフェース
Daoインタフェースのメソッドのパラメータや戻り値での利用例です。
@Dao(config = AppConfig.class)
public interface EmployeeDao {
@Select
Employee selectByPhoneNumber(PhoneNumber phoneNumber);
@Select
List<PhoneNumber> selectAllPhoneNumber();
@Select
Employee selectByJobType(JobType jobType);
@Select
List<JobType> selectAllJobTypes();
}
