About

ドキュメント

Javadocs

プロジェクト文書

Built by Maven

概要

Genタスクは、データベースに接続してメタデータを読み取り、その情報を基にエンティティクラス、エンティティリスナークラス、Daoインタフェース、SQLのコードを生成します。

Genタスクを利用するには、次のようにtaskdefタグとtypedefタグを使ってタスクとデータ型を定義する必要があります。

<taskdef name="gen" classname="org.seasar.doma.extension.gen.task.Gen" classpathref="classpath" loaderref="loader"/>
<typedef name="entityConfig" classname="org.seasar.doma.extension.gen.task.EntityConfig" loaderref="loader"/>
<typedef name="daoConfig" classname="org.seasar.doma.extension.gen.task.DaoConfig" loaderref="loader"/>
<typedef name="sqlConfig" classname="org.seasar.doma.extension.gen.task.SqlConfig" loaderref="loader"/>

taskdefのclasspathref属性には、Doma-Gen、FreeMarker、JDBCドライバのjarファイルが参照されるように設定してください(Doma本体のjarファイルは不要です)。

定義したタスクとデータ型は次のように使用します。

<target name="gen">
    <gen
        dialectName="${dialectName}"
        driverClassName="${driverClassName}"
        url="${url}"
        user="${user}"
        password="${password}">
        <entityConfig
            destdir="${javaDestDir}"
            packageName="${entityPackageName}"
        />
        <daoConfig
            destdir="${javaDestDir}"
            packageName="${daoPackageName}"
            configClassName="${configClassName}"
        />
        <sqlConfig
            destdir="${sqlDestDir}"
        />
    </gen>
</target>

生成されるコードは次のようになります。

エンティティクラスです。

@Entity(listener = AddressListener.class)
@Table(name = "ADDRESS")
public class Address {

    @Id
    @Column(name = "ADDRESS_ID")
    Integer addressId;

    @Column(name = "STREET")
    String street;

    @Version
    @Column(name = "VERSION")
    Integer version;
    ...
}

エンティティリスナークラスです。

public class AddressListener implements EntityListener<Address> {

    @Override
    public void preInsert(Address entity, PreInsertContext<Address> context) {
    }

    @Override
    public void preUpdate(Address entity, PreUpdateContext<Address> context) {
    }

    @Override
    public void preDelete(Address entity, PreDeleteContext<Address> context) {
    }

    @Override
    public void postInsert(Address entity, PostInsertContext<Address> context) {
    }

    @Override
    public void postUpdate(Address entity, PostUpdateContext<Address> context) {
    }

    @Override
    public void postDelete(Address entity, PostDeleteContext<Address> context) {
    }
}

Daoインタフェースです。

@Dao(config = AppConfig.class)
public interface AddressDao {

    @Select
    Address selectById(Integer addressId);

    @Select(ensureResult = true)
    Address selectByIdAndVersion(Integer addressId, Integer version);

    @Insert
    int insert(Address entity);

    @Update
    int update(Address entity);

    @Delete
    int delete(Address entity);
}

Daoデリゲートクラスです。

public class AddressDaoDelegate {

    private final Config config;

    private final AddressDao dao;

    public AddressDaoDelegate(Config config, AddressDao dao) {
        if (config == null) {
            throw new NullPointerException("config");
        }
        if (dao == null) {
            throw new NullPointerException("dao");
        }
        this.config = config;
        this.dao = dao;
    }

    public int insert(Address entity) {
        return -1;
    }

    public int update(Address entity) {
        return -1;
    }

    public int delete(Address entity) {
        return -1;
    }
}

識別子を条件として検索するSQLです。

select
    ADDRESS_ID,
    STREET,
    VERSION
from
    ADDRESS
where
    ADDRESS_ID = /* addressId */1

識別子とバージョンを条件として検索するSQLです。

select
    ADDRESS_ID,
    STREET,
    VERSION
from
    ADDRESS
where
    ADDRESS_ID = /* addressId */1
    and
    VERSION = /* version */1
    

パラメータ

トップレベルパラメータ

トップレベルパラメータの定義は次の通りです。

属性 説明 デフォルト値 必須
dialectName 接続するRDBMSの方言名です。次のうちのどれかを指定できます。"h2"、"hsqldb"、"mysql"、"postgres"、"oracle"、"db2"、"mssql2008"、"mssql"。この名前に対応するクラスは、Genタスクを実行するクラスパスに通されている必要があります。 - genDialectClassNameが指定されていない場合YES
genDialectClassName 接続するRDBMSの方言クラス名です。org.seasar.doma.extension.gen.dialect.GenDialectの実装クラスでなければいけません。dialectNameの指定により利用できる組み込みの方言クラス以外を利用する場合に指定します。指定するクラスは、Genタスクを実行するクラスパスに通されている必要があります。 - dialectNameが指定されていない場合YES
driverClassName JDBCドライバクラス名です。java.sql.Driverの実装クラスでなければいけません。 - YES
url JDBC接続URLです。 - YES
user JDBC接続ユーザーです。 - YES
password JDBC接続パスワードです。 - YES
schemaName 対象とするテーブルが所属するスキーマ名です。指定しない場合、JDBC接続ユーザーでアクセス可能な全スキーマが対象になります。 - NO
tableNamePattern 対象とするテーブル名の正規表現です。大文字小文字の違いは考慮されません。 ".*" NO
ignoredTableNamePattern 対象としないテーブル名の正規表現です。大文字小文字の違いは考慮されません。 ".*\$.*" NO
tableTypes 対象とするテーブルの型です。複数の値を空白またはカンマで区切って指定できます。たとえば、テーブルに加えビューを対象にしたい場合、"TABLE, VIEW"と指定します。この値は、java.sql.DatabaseMetaDataクラスのgetTablesメソッドの最後のパラメータに渡されます。 "TABLE" NO
versionColumnNamePattern エンティティのプロパティに@Versionを付与するカラム名の正規表現です。大文字小文字の違いは考慮されません。 "VERSION([_]?NO)?" NO
templateEncoding テンプレートファイルのエンコーディングです。 "UTF-8" NO
templatePrimaryDir テンプレートファイルを検索する際の優先ディレクトリです。独自テンプレートファイルを使用する場合に指定します。 - NO
globalFactoryClassName このタスクで使用されるインスタンスを生成するファクトリの完全修飾名です。org.seasar.doma.extension.gen.GlobalFactoryの実装クラスでなければいけません。このタスクの振る舞いをカスタマイズする場合に指定します。 "org.seasar.doma.extension.gen.GlobalFactory" NO

ネストした要素として指定されるパラメータ

EntityConfig

エンティティクラスの生成に関する設定を表すデータ型です。

このデータ型を使用するとエンティティクラスとエンティティリスナークラスを生成できます。エンティティクラスとエンティティリスナーは同じパッケージに生成されます。

EntityConfigのパラメータ定義は次のとおりです。

属性 説明 デフォルト値 必須
generate "true"の場合、エンティティクラスとエンティティリスナーのJavaコードを生成します。 "true" NO
destDir Javaファイルの出力先ディレクトリです。 "src" NO
encoding Javaファイルのエンコーディングです。 "UTF-8" NO
overwrite "true"の場合、エンティティクラスのJavaコードを上書きします。 "true" NO
overwriteListener "true"の場合、エンティティリスナークラスのJavaコードを上書きします。 "false" NO
packageName エンティティクラスのパッケージ名です。 "example.entity" NO
superclassName エンティティクラスのスーパークラスの完全修飾名です。生成されるエンティティクラスはここに指定したスーパークラスを継承します。指定するクラスは、Genタスクを実行するクラスパスに通されている必要があります。 - NO
listenerSuperclassName エンティティリスナーのスーパークラスの完全修飾名です。生成されるエンティティリスナークラスはここに指定したスーパークラスを継承します。ここに指定するクラスは1つの型パラメータを受け取ります。 - NO
namingType ネーミング規約です。"none"、 "snake_upper_case"、 "snake_lower_case"、"upper_case"、"lower_case"のいずれかの値を指定できます。@Entityのnaming要素に使用されます。 - NO
entityPropertyClassNamesFile エンティティプロパティのクラス名を解決するためのファイルです。形式は、キーをエンティティプロパティ名の正規表現、値をクラスの完全修飾名とするプロパティファイル形式です。 - NO
generationType 識別子を生成する方法です。"identity"、 "sequence"、 "table"のいずれかの値を指定できます。使用するRDBMSがサポートしていない場合、"identity"や"sequence"を指定するとエラーが発生します。この指定は、エンティティに対応するテーブルが単一の主キーを持つ場合にのみ有効です。複数の主キーがある場合、この指定は無視されます。@GeneratedValueのstrategy要素に使用されます。 - NO
initialValue 識別子の初期値です。generationTypeに"sequence"もしくは"table"を指定した場合にのみ有効です。@SequenceGeneratorや@TableGeneratorのinitialValue要素に指定されます。 - NO
allocationSize 識別子の割り当てサイズです。generationTypeに"sequence"もしくは"table"を指定した場合にのみ有効です。@SequenceGeneratorや@TableGeneratorのallocationSize要素に指定されます。 - NO
useAccessor "true"の場合、エンティティクラスにアクセサメソッドを付与します。"false"の場合、エンティティのプロパティはpublicフィールドになります。 "true" NO
useListener "true"の場合、エンティティリスナークラスのJavaコードを生成し、@Entityのlistener要素にエンティティリスナークラスを指定します。"false"の場合、エンティティリスナークラスのJavaコードは生成されません。 "true" NO
useUtilDate "true"の場合、エンティティクラスのプロパティの日付、時刻、タイムスタンプ型にjava.util.Dateを使用します。"false"の場合、日付、時刻、タイムスタンプ型にjava.sql.Date、java.sql.Time、java.sql.Timestampを使用します。 "false" NO
showDbComment "true"の場合、データベースに対するコメントをエンティティのJavadocコメントに適用します。テーブルへのコメントはクラスのJavadocコメントに反映され、カラムへのコメントはプロパティのJavadocコメントに反映されます。 "true" NO
showCatalogName "true"の場合、@Tableのcatalog属性にカタログ名を明記します。 "false" NO
showSchemaName "true"の場合、@Tableのschema属性にスキーマ名を明記します。 "false" NO
showTableName "true"の場合、@Tableのname属性にテーブル名を明記します。 "true" NO
showColumnName "true"の場合、@Columnのname属性にカラム名を明記します。 "true" NO
originalStatesPropertyName ここに指定した名前のプロパティに、@OriginalStatesを注釈します。テーブルのカラムから作られる永続的なプロパティと名前が重複しないように注意してください。指定しない場合、@OriginalStatesは使用されません。 - NO

DaoConfig

Daoインタフェースの生成に関する設定を表すデータ型です。

このデータ型を使用するとエンティティごとに1つのDaoインタフェースとDaoデリゲートクラスを生成できます。

DaoConfigのパラメータ定義は次のとおりです。

属性 説明 デフォルト値 必須
overwrite "true"の場合、DaoインタフェースのJavaコードを上書きします。 "false" NO
overwriteDelegate "true"の場合、DaoデリゲートクラスのJavaコードを上書きします。 "false" NO
destDir Javaファイルの出力先ディレクトリです。 "src" NO
encoding Javaファイルのエンコーディングです。 "UTF-8" NO
generate "true"の場合、DaoインタフェースのJavaコードを生成します。 "true" NO
packageName Daoインタフェースのパッケージ名です。 "example.dao" NO
suffix Daoインタフェース名のサフィックスです。Daoインタフェースの名前はエンティティクラス名に、この値をサフィックスしたものになります。 "Dao" NO
configClassName 設定クラスの完全修飾名です。@Daoのconfig要素に使用されます。 - NO
useDelegate "true"の場合、DaoデリゲートクラスのJavaコードを生成します。"false"の場合、生成しません。 "false" NO

SqlConfig

SQLファイルの生成に関する設定を表すデータ型です。

このデータ型を使用するとエンティティごとにデフォルトで2つのSQLファイルを生成できます。 生成されるSQLは次のものです。

  • 条件に識別子を指定して検索するSQL
  • 条件に識別子とバージョンを指定して検索するSQL

ただし、エンティティが識別子を持たない場合、SQLファイルは生成されません。 また、エンティティがバージョンを持たない場合は、条件にバージョンを指定するSQLは生成されません。

テンプレートを用意することで、独自のSQLファイルを生成できます。詳細は、独自のSQLファイルを生成するを参照してください。

SqlConfigのパラメータ定義は次のとおりです。

属性 説明 デフォルト値 必須
generate "true"の場合、SQLファイルを生成します。 "true" NO
destDir SQLファイルの出力先ディレクトリです。ファイルは、ファイル名の形式に則って出力されます。ここに指定したディレクトリを基点にMETA-INF以下のディレクトリが作成されます。 src NO
overwrite "true"の場合、SQLファイルを上書きします。 "true" NO

使用例

エンティティクラスに共通のスーパークラスを指定する

EntityConfigのsuperclassName属性に、エンティティクラスに共通のスーパークラスの名前を指定できます。 たとえば、エンティティに対応するすべてのテーブルにCREATE_TIMESTAMPとUPDATE_TIMESTAMPというカラムが定義されている場合、 次のようなクラスを作成し、すべてのエンティティのスーパークラスに指定できます。

@Entity
public abstract class Common {
    Date createTimestamp;
    Date updateTimestamp;
    ...
}

スーパークラス名をsuperclassName属性に指定します。

<gen
    dialectName="${dialectName}"
    driverClassName="${driverClassName}"
    url="${url}"
    user="${user}"
    password="${password}">
    <entityConfig
        superclassName="example.Common"
        ...
    />
<gen/>

タスクを実行するとexample.Commonを継承した次のようなクラスが生成されます。

@Entity
public class Employee extends Common {
    @Id
    Integer id;
    String name;
    ...
}

エンティティリスナーに共通のスーパークラスを指定する

EntityConfigのlistenerSuperclassName属性に、エンティティリスナーに共通のスーパークラスの名前を指定できます。 通常、EntityConfigのsuperclassName属性と合わせて使用します。 たとえば、次のようにエンティティクラスに共通のスーパークラスとそのクラスを型パラメータとして受け取るエンティティリスナーの2つを用意します。

@Entity
public abstract class Common {
    Date createTimestamp;
    Date updateTimestamp;
    ...
}
public class CommonListener<T extends Common> implements EntityListener<T> {
    public void preInsert(T entity, PreInsertContext<T> context) {...}
    public void preUpdate(T entity, PreUpdateContext<T> context) {...}
    public void preDelete(T entity, PreDeleteContext<T> context) {...}
    public void postInsert(T entity, PostInsertContext<T> context) {...}
    public void postUpdate(T entity, PostUpdateContext<T> context) {...}
    public void postDelete(T entity, PostDeleteContext<T> context) {...}
}

これらのクラス名をsuperclassName属性とlistenerSuperclassName属性に指定します。

<gen
    dialectName="${dialectName}"
    driverClassName="${driverClassName}"
    url="${url}"
    user="${user}"
    password="${password}">
    <entityConfig
        superclassName="example.Common"
        listenerSuperclassName="example.CommonListener"
        ...
    />
<gen/>

タスクを実行するとexample.CommonListenerを継承した次のようなクラスが生成されます。

public class EmployeeListener extends CommonListener<Employee> {
}

エンティティプロパティのクラス名を指定する

ドメインクラスを使用する場合など、特定のエンティティプロパティに対しクラス名を指定したいことがあります。

クラス名の指定は、プロパティファイルで行います。 キーは、エンティティプロパティの完全修飾名を正規表現で表したもの、値はマッピングしたいクラスの完全修飾名です。 エンティティプロパティの完全修飾名とは、「エンティティクラスの完全修飾名」と「エンティティプロパティ名」を「@」で連結したものです。 たとえば、EmployeeエンティティクラスのエンティティプロパティemployeeNameの完全修飾名は、「example.entity.Employee@employeeName」です。 Employeeエンティティクラスの中でエンティティプロパティ名が「Name」で終わるものを「example.domain.Name」クラスにマッピングさせるには、次のように記述します。

example.entity.Employee@.*Name$=example.domain.Name

プロパティ名の部分を正規表現で示しています。正規表現はプロパティ名に対してのみ使用できます(@より左のクラス名は必ず完全修飾名でなければいけません)。

生成されるエンティティクラスでは、次のようにemployeeNameプロパティの型が「example.domain.Name」になります。

import example.domain.Name;

@Entity
public class Employee extends Common {
    @Id
    Integer id;
    Name employeeName;
    ...
}

Employeeエンティティクラスに限らず、すべてのエンティティクラスを対象にエンティティプロパティ名が「Name」で終わるものを「example.domain.Name」クラスにマッピングさせたい場合は次のように記述します。

.*Name$=example.domain.Name

プロパティファイルは、エンティティプロパティごとに上から順番に評価され、正規表現がマッチした時点で評価を終えます。 どの行にもマッチしない場合、クラス名はデフォルトのクラス名になります。

プロパティファイルはentityPropertyClassNamesFile属性に指定できます。(ここではプロパティファイルの名前をentityPropertyClassNames.propertiesとします。)

<gen
    dialectName="${dialectName}"
    driverClassName="${driverClassName}"
    url="${url}"
    user="${user}"
    password="${password}">
    <entityConfig
        entityPropertyClassNamesFile="entityPropertyClassNames.properties"
        ...
    />
<gen/>

独自のテンプレートファイルを使用する

Doma-Genのテンプレートは、配布ファイルのresources/templateディレクトリ以下にあります。 エンティティクラスのテンプレートはentity.ftl、エンティティリスナークラスのテンプレートはentityListener.ftl、Daoインタフェースのテンプレートはdao.ftl、DaoデリゲートクラスのテンプレートはdaoDelegate.ftlになります。 また、識別子を条件に検索するSQLのテンプレートはselectById.sql.ftl、識別子とバージョンを条件に検索するSQLのテンプレートはselectByIdAndVersion.sql.ftlです。 これをコピーして、修正を加えるのが良いでしょう。 テンプレートの記述方法についてはFreeMarkerのドキュメントを参照してください。

修正したテンプレートファイルは、ファイル名を変更せずにtemplateFilePrimaryDir属性に指定するディレクトリに配置します。 mytemplateディレクトリに配置する場合、templatePrimaryDir属性にmytemplateを指定します。

<gen
    dialectName="${dialectName}"
    driverClassName="${driverClassName}"
    url="${url}"
    user="${user}"
    password="${password}"
    templatePrimaryDir="mytemplate">
    <entityConfig
        ...
    />
<gen/>

それぞれのテンプレートは、特定のデータモデルを参照します。 テンプレートとデータモデルクラスの対応付けを以下に示します。

テンプレート データモデルクラス 生成物
entity.ftl org.seasar.doma.extension.gen.EntityDesc エンティティクラスのJavaファイル
entityListener.ftl org.seasar.doma.extension.gen.EntityListenerDesc エンティティリスナークラスのJavaファイル
dao.ftl org.seasar.doma.extension.gen.DaoDesc DaoインタフェースのJavaファイル
daoDelegate.ftl org.seasar.doma.extension.gen.DaoDelegateDesc DaoデリゲートクラスのJavaファイル
xxx.sql.ftl (xxxは任意の名称) org.seasar.doma.extension.gen.SqlDesc SQLファイル

独自のSQLファイルを生成する

テンプレートを用意することで、独自のSQLファイルを生成できます。 テンプレートファイルの名前は、「生成したいsqlファイル名」 + 「.ftl」としてください。

たとえば、全件検索を行うSQLファイルselectAll.sqlを生成するには、selectAll.sql.ftlという名前のテンプレートファイルを作成します。 テンプレートファイルには、以下のように記述します。 (テンプレートはデータモデルとしてorg.seasar.doma.extension.gen.SqlDescのインスタンスを参照します。)

select
<#list entityDesc.entityPropertyDescs as property>
  ${property.columnName}<#if property_has_next>,</#if>
</#list>
from
  ${entityDesc.tableName}

selectAll.sql.ftlは、templateFilePrimaryDir属性に指定するディレクトリに配置します。 mytemplateディレクトリに配置する場合、templatePrimaryDir属性にmytemplateを指定します。

<gen
    dialectName="${dialectName}"
    driverClassName="${driverClassName}"
    url="${url}"
    user="${user}"
    password="${password}"
    templatePrimaryDir="mytemplate">
    <sqlConfig
        ...
    />
<gen/>

このように、独自のSQLファイルを生成する場合、SQLファイルに対応するDaoメソッドについても生成するとよいでしょう。 Daoメソッドを生成するには、Daoインタフェースのテンプレートであるdao.ftlを修正し、templateFilePrimaryDir属性に指定するディレクトリに配置します。

生成するJavaファイルに共通のヘッダーとしてコピーライトを含める

lib.ftlというファイルを作成し、これをtemplatePrimaryDir属性に指定するディレクトリに配置します。 lib.ftlには次のようにcopyrightの定義をします。

<#assign copyright>
/*
 * Copyright 2008-2009 ...
 * All rights reserved.
 */
</#assign>
mytemplate/lib.ftlと配置する場合、タスクの定義は次のようになります。

<gen
    dialectName="${dialectName}"
    driverClassName="${driverClassName}"
    url="${url}"
    user="${user}"
    password="${password}"
    templatePrimaryDir="mytemplate">
    <entityConfig
        ...
    />
<gen/>

生成するJavaファイルにauthorを指定する

lib.ftlというファイルを作成し、これをtemplatePrimaryDir属性に指定するディレクトリに配置します。 lib.ftlには次のようにauthorの定義をします。

<#assign author="Nakamura">
mytemplate/lib.ftlと配置する場合、タスクの定義は次のようになります。

<gen
    dialectName="${dialectName}"
    driverClassName="${driverClassName}"
    url="${url}"
    user="${user}"
    password="${password}"
    templatePrimaryDir="mytemplate">
    <entityConfig
        ...
    />
<gen/>