Genタスク

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

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

]]>

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

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

]]>

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

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

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

{ @Override public void preInsert(Address entity, PreInsertContext
context) { } @Override public void preUpdate(Address entity, PreUpdateContext
context) { } @Override public void preDelete(Address entity, PreDeleteContext
context) { } @Override public void postInsert(Address entity, PostInsertContext
context) { } @Override public void postUpdate(Address entity, PostUpdateContext
context) { } @Override public void postDelete(Address entity, PostDeleteContext
context) { } }]]>

Daoインタフェースです。

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

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

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

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

属性説明デフォルト値必須
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
driverClassNameJDBCドライバクラス名です。java.sql.Driverの実装クラスでなければいけません。-YES
urlJDBC接続URLです。-YES
userJDBC接続ユーザーです。-YES
passwordJDBC接続パスワードです。-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
destDirJavaファイルの出力先ディレクトリです。"src"NO
encodingJavaファイルのエンコーディングです。"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
destDirJavaファイルの出力先ディレクトリです。"src"NO
encodingJavaファイルのエンコーディングです。"UTF-8"NO
generate"true"の場合、DaoインタフェースのJavaコードを生成します。"true"NO
packageNameDaoインタフェースのパッケージ名です。"example.dao"NO
suffixDaoインタフェース名のサフィックスです。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
destDirSQLファイルの出力先ディレクトリです。ファイルは、ファイル名の形式に則って出力されます。ここに指定したディレクトリを基点にMETA-INF以下のディレクトリが作成されます。srcNO
overwrite"true"の場合、SQLファイルを上書きします。"true"NO

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

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

]]>

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

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

implements EntityListener { public void preInsert(T entity, PreInsertContext context) {...} public void preUpdate(T entity, PreUpdateContext context) {...} public void preDelete(T entity, PreDeleteContext context) {...} public void postInsert(T entity, PostInsertContext context) {...} public void postUpdate(T entity, PostUpdateContext context) {...} public void postDelete(T entity, PostDeleteContext context) {...} }]]>

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

]]>

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

{ }]]>

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

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

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

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

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

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

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

]]>

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を指定します。

]]>

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

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

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

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

${property.columnName}<#if property_has_next>, from ${entityDesc.tableName}]]>

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

]]>

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

lib.ftlというファイルを作成し、これをtemplatePrimaryDir属性に指定するディレクトリに配置します。 lib.ftlには次のようにcopyrightの定義をします。 /* * Copyright 2008-2009 ... * All rights reserved. */ ]]> mytemplate/lib.ftlと配置する場合、タスクの定義は次のようになります。

]]>

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

]]>