doma2を使ってみる (4) - Domain -

2015-03-22T00:00:00+09:00 Java doma

ドキュメント: http://doma.readthedocs.org/ja/latest/domain

要はJavaオブジェクト的なのをデータベース上で表現できるようにする、逆も然りみたいな感じ?。まぁコンバーターみたいな所なんじゃないかと。正式な所は公式ドキュメントに書いてるので(ry

Sample.java (Entity)

package sample.entity;

import org.seasar.doma.Entity;
import org.seasar.doma.GeneratedValue;
import org.seasar.doma.GenerationType;
import org.seasar.doma.Id;
import org.seasar.doma.jdbc.entity.NamingType;

import sample.domain.Name;

@Entity(naming = NamingType.LOWER_CASE)
public class Sample {

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

    private Name name;

    public Name getName() {
        return name;
    }

    public void setName(Name name) {
        this.name = name;
    }
}

っていうようにsample.domain.NameっていうのをEntityで持つ場合にこれをDBに格納したりDBから取り出す場合にどうするかって所なんですが、そのオブジェクトに@Domainアノテーションで定義すれば良いとのこと

Name.java

package sample.domain;

import org.seasar.doma.Domain;

/*
ofでインスタンスファクトリーメソッドを指定しない場合には
非privateなコンストラクタが必要になり無い場合はコンパイルエラーになる
*/
@Domain(valueType = String.class, factoryMethod="of")
public class Name {

    private final String value;

    private Name(String value) {
        this.value = value;
    }

    // @DomainのaccessorMethodで変更可能?
    public String getValue() {
        return value;
    }

    // ofを指定しているので必要
    public static Name of(String value) {
        return new Name(value);
    }
}

まぁこんだけでEntityとかで使うフィールドとかの型をDBに格納するような場合には@Domainで定義しておけば良いみたいな感じ

まぁこれが公式ドキュメントでいう内部ドメインっていう所なので、外部ドメインもやってみるのでこのクラスの@Domainアノテーションをコメントしておく

NameConverter.java

@ExternalDomainアノテーションを付与するのとDomainConverterを実装したクラスを定義する

package sample.domain;

import org.seasar.doma.ExternalDomain;
import org.seasar.doma.jdbc.domain.DomainConverter;

// DomainConverterを実装しないとコンパイルエラー
@ExternalDomain
public class NameConverter implements DomainConverter<Name, String> {

    public String fromDomainToValue(Name domain) {
        return domain.getValue();
    }

    public Name fromValueToDomain(String value) {
        return value == null ? null : Name.of(value);
    }
}

NameConverterProvider.java

DomainConverterを処理するのに必要なのを登録する必要がある模様

package sample.domain;

import org.seasar.doma.DomainConverters;

@DomainConverters({ NameConverter.class })
public class NameConverterProvider {
}

これだけ作るだけじゃダメで、gradleとかでビルドする際にオプションを指定する必要があるので

apply plugin: "java"

processResources.destinationDir = compileJava.destinationDir
compileJava.dependsOn processResources

// 追加
compileJava.options.compilerArgs = [
    '-Adoma.domain.converters=sample.domain.NameConverterProvider'
]

repositories {
    mavenCentral()
}

dependencies {
    runtime "mysql:mysql-connector-java:+"
    runtime "org.springframework:spring-jdbc:+"
    runtime "org.aspectj:aspectjweaver:+"
    runtime "log4j:log4j:+"

    compile "org.seasar.doma:doma:2.1.0"
    compile "org.springframework:spring-beans:+"
    compile "org.springframework:spring-context:+"
    compile "org.springframework:spring-tx:+"

    testCompile "org.springframework:spring-test:+"
    testCompile "junit:junit:+"
    testCompile "org.hamcrest:hamcrest-all:+"
}

複数ある場合にはカンマ区切りで指定すれば良いっぽい。詳しくはhttp://doma.readthedocs.org/ja/latest/annotation-processing

react-router Springでアノテーションがついてるメソッドにアスペクトする方法