ドメインクラス

Domain(ドメイン)クラスの定義方法を示します。 ドメインとは、値のとり得る範囲(定義域)のことです。 Domaでは、テーブルのカラムの値を、ドメインと呼ばれるJavaオブジェクトで扱います。

ドメインクラスを利用することで、データベース上のカラムの型が同じあってもアプリケーション上意味が異なるものを別のJavaの型で表現できます。 これにより、意味を明確にしプログラミングミスを事前に防ぎやすくなります。 また、ドメインクラスに振る舞いを持たせることで、よりわかりやすいプログラミングが可能です。

ドメインクラスの作成と利用は任意です。 ドメインクラスを利用しなくてもIntegerStringなど基本型のみでデータアクセスは可能です。

ドメインクラスは @Domainを注釈して示します。

@DomainvalueType要素には、ドメインクラスで扱う基本型を指定します。この基本型が、データベースのカラムの型とのマッピングに使用されます。

accessorMethod要素には、valueType要素に指定した型を返すアクセッサメソッドの名前を指定します。デフォルト値は"getValue"です。

factoryMethod要素には、valueType要素に指定した型をパラメータとし受け取りドメインクラスの型を返すファクトリメソッドの名前を指定します。デフォルト値は"new"であり、これはコンストラクタにより生成することを示します。

@Domainが注釈されたクラスは以下の制約を満たす必要があります。

任意ですが、ドメインクラスは不変オブジェクトとして作成することを推奨します。 クラスには、任意のメソッドを持たせることができます。

列挙型は非privateなコンストラクタを定義できないため、列挙型に対してはファクトリメソッドを用いた方法を使用する必要があります。

@DomainfactoryMethod要素のデフォルトの値はnewであり、 非privateなコンストラクタでインスタンスを生成することを示します。そのため、コンストラクタで生成する場合はfactoryMethod要素を省略できます。

次の例では、 publicなコンストラクタを持つドメインクラスを作成しています。 このクラスは電話番号を表しています。

コンストラクタをprivateにし、ファクトリメソッドを使ってインスタンスを生成したい場合は、 staticな非privateなメソッドを定義し@DomainfactoryMethod要素にそのメソッドの名前を指定します。

次の例では、publicな ファクトリメソッドをもつドメインクラスを作成しています。 このクラスは電話番号を表しています。

次の例では、publicな ファクトリメソッドをもつ列挙型をドメインクラスとして作成しています。 この列挙型は仕事の種別を表しています。

ドメインクラスには任意の数の型パラメータを宣言できます。

次の例では、1つの型パラメータを持ち、さらにpublicなコンストラクタを持つドメインクラスを作成しています。 このクラスは識別子を表しています。

{ private final int value; public Identity(int value) { this.value = value; } public int getValue() { return value; } }]]>

型パラメータを持ったドメインクラスはファクトリメソッドで生成することも可能です。 この場合、ファクトリメソッドにはクラスの型変数宣言と同等の宣言が必要です。

{ private final int value; private Identity(int value) { this.value = value; } public int getValue() { return value; } public static Identity of(int value) { return new Identity(value); } }]]>

ソースコードに手を加えられないなどの理由で任意の型をドメインクラスとして扱いたい場合は、外部ドメイン定義が使えます。

外部ドメイン定義は、 DomainConverter の実装クラスに @ExternalDomain を注釈して示します。

DomainConverterの第1型パラメータにはドメインクラスとして扱いたい型、第2型パラメータには 基本型 を指定します。

@ExternalDomainが注釈されたDomainConverterの実装クラスは以下の制約を満たす必要があります。

例えば、次のようなPhoneNumberというクラスがあり、ソースコードに手を加えられないとします。

上記のPhoneNumberをドメインクラスとして扱うには、次のようなクラスを作成します。

{ public String fromDomainToValue(PhoneNumber domain) { return domain.getValue(); } public PhoneNumber fromValueToDomain(String value) { return new PhoneNumber(value); } }]]>

これで外部ドメイン定義は完成ですが、これだけではまだ利用できません。 外部ドメインの定義は注釈処理のオプションで指定する必要があります。

注釈処理のオプションで指定する前段階として、外部ドメイン定義を @DomainConverters で登録します。 @DomainConverters には複数の外部ドメイン定義を登録可能です。

そして、 @DomainConverters が注釈されたクラスの完全修飾名を注釈処理のオプションに指定します。 オプションのkeyは、「domain.converters」です。 オプションの指定の仕方については 注釈処理 を参照してください。

外部ドメイン定義では、任意の数の型パラメータを持ったクラスを扱えます。

次の例のような1つの型パラメータを持つクラスがあるとします。 このクラスは識別子を表しています。

{ private final int value; public Identity(int value) { this.value = value; } public int getValue() { return value; } }]]>

上記のIdentityをドメインクラスとして扱うには、次のようなクラスを作成します。 Identityの型パラメータにはワイルドカード(?)を指定しなければいけません。

, String> { public String fromDomainToValue(Identity domain) { return domain.getValue(); } @SuppressWarnings("rawtypes") public Identity fromValueToDomain(String value) { return new Identity(value); } }]]>

その他の設定方法については、型パラメータを使用しない場合と同様です。

ドメインクラスが型パラメータを持つ場合、型パラメータには具体的な型が必要です。 ワイルドカード(?)や型変数の指定はサポートされていません。

エンティティクラスのフィールドの型での利用例です。

employeeId; String employeeName; PhoneNumber phoneNumber; JobType jobType; @Version Integer versionNo(); ... }]]>

Daoインタフェースのメソッドのパラメータや戻り値での利用例です。

employeeId); @Select Employee selectByPhoneNumber(PhoneNumber phoneNumber); @Select List selectAllPhoneNumber(); @Select Employee selectByJobType(JobType jobType); @Select List selectAllJobTypes(); }]]>