LoginSignup
2
0

More than 5 years have passed since last update.

Doma-Genで生成するentityをカスタマイズする。 (entityの内容を変更。)

Last updated at Posted at 2018-08-03

doma-genで生成されるentityの内容をカスタマイズした時に調べた内容をまとめました。自分の場合は、型の変更とアノテーションの要素を追加をしましたが、基本的にはfreemarkerの変更で完結するので、他の場合でも応用が利くと思います。

まず簡単に言ってしまうと、以下をすれば編集は完了します。
①genのパラメータにtemplatePrimaryDir="xxx"を追加。
②entity.ftl を変更。

「①genのパラメータにtemplatePrimaryDir="xxx"を追加。」

templatePrimaryDirとは公式ドキュメントを参照すると「テンプレートファイルを検索する際の優先ディレクトリです。独自テンプレートファイルを使用する場合に指定します。」と書かれています。
指定は適当に決めてください。動作検証時に自分は、仮の設定としてアプリケーションルート「.」と指定しました。
例) src/main/resources/doma/template
http://doma.seasar.org/extension/doma_gen_gen_task.html

「②entity.ftl」

entity.ftlとはentityを生成するtemplateファイルです。このファイルを編集すればentityの生成内容を変更できます。

(1)entity.ftlを入手する。

entity.ftlはdoma-gen-2.13.0.jarの中にあります。解凍してファイルを取得してください。
※同バージョンのソースを入手できれば、そちらでも良いと思います。
▼ファイルの場所
org/seasar/doma/doma-gen/2.13.0/org/seasar/doma/extension/gen/template/entity.ftl

(2)entity.ftlを「templatePrimaryDir」に指定したディレクトリに配置する。

(3)entity.ftlを編集する。

※編集後のファイル

entity.ftl
<#-- このテンプレートに対応するデータモデルのクラスは org.seasar.doma.extension.gen.EntityDesc です -->

<#-- (1)カスタマイズfunction定義 -->
<#function convertDataType dataType>
    <#local result = dataType?replace("Byte", "Integer")>
    <#local result = result?replace("int", "Integer")>
    <#local result = result?replace("Short", "Integer")>
    <#return result>
</#function>
<#function addElement columnName>
    <#if columnName == "create_time">
    <#return ", insertable=false">
    <#elseif columnName == "updated_datetime">
    <#return ", insertable=false, updatable=false">
    </#if>
    <#return "">
</#function>
<#-- (1)カスタマイズfunction定義 -->

<#import "/lib.ftl" as lib>
<#if lib.copyright??>
${lib.copyright}
</#if>
<#if packageName??>
package ${packageName};
</#if>

<#list importNames as importName>
import ${importName};
</#list>

/**
<#if showDbComment && comment??>
 * ${comment}
</#if>
<#if lib.author??>
 * @author ${lib.author}
</#if>
 */
@Entity<#if useListener || namingType != "NONE">(</#if><#if useListener>listener = ${listenerClassSimpleName}.class</#if><#if namingType != "NONE"><#if useListener>, </#if>naming = ${namingType.referenceName}</#if><#if useListener || namingType != "NONE">)</#if>
<#if showCatalogName && catalogName?? || showSchemaName && schemaName?? || showTableName && tableName??>
@Table(<#if showCatalogName && catalogName??>catalog = "${catalogName}"</#if><#if showSchemaName && schemaName??><#if showCatalogName && catalogName??>, </#if>schema = "${schemaName}"</#if><#if showTableName><#if showCatalogName && catalogName?? || showSchemaName && schemaName??>, </#if>name = "${tableName}"</#if>)
</#if>
public class <#if entityPrefix??>${entityPrefix}</#if>${simpleName}<#if entitySuffix??>${entitySuffix}</#if><#if superclassSimpleName??> extends ${superclassSimpleName}</#if> {
<#list ownEntityPropertyDescs as property>

  <#if showDbComment && property.comment??>
    /** ${property.comment} */
  <#else>
    /** */
  </#if>
  <#if property.id>
    @Id
    <#if property.generationType??>
    @GeneratedValue(strategy = ${property.generationType.referenceName})
      <#if property.generationType == "SEQUENCE">
    @SequenceGenerator(sequence = "${tableName}_${property.columnName}"<#if property.initialValue??>, initialValue = ${property.initialValue}</#if><#if property.allocationSize??>, allocationSize = ${property.allocationSize}</#if>)
      <#elseif property.generationType == "TABLE">
    @TableGenerator(pkColumnValue = "${tableName}_${property.columnName}"<#if property.initialValue??>, initialValue = ${property.initialValue}</#if><#if property.allocationSize??>, allocationSize = ${property.allocationSize}</#if>)
      </#if>
    </#if>
  </#if>
  <#if property.version>
    @Version
  </#if>
  <#if property.showColumnName && property.columnName??>
    <#-- (2)アノテーションに要素追加 -->
    @Column(name = "${property.columnName}"${addElement(property.columnName)})
  </#if>
    <#-- (3)変数の型変換 -->
    <#if !useAccessor>public </#if>${convertDataType(property.propertyClassSimpleName)} ${property.name};
</#list>
<#if originalStatesPropertyName??>

    /** */
    @OriginalStates
    <#if entityPrefix??>${entityPrefix}</#if>${simpleName}<#if entitySuffix??>${entitySuffix}</#if> ${originalStatesPropertyName};
</#if>
<#if useAccessor>
  <#list ownEntityPropertyDescs as property>

    /**
     * Returns the ${property.name}.
     *
     * @return the ${property.name}
     */
    <#-- (4)戻り値の型変換 -->
    public ${convertDataType(property.propertyClassSimpleName)} get${property.name?cap_first}() {
        return ${property.name};
    }

    /**
     * Sets the ${property.name}.
     *
     * @param ${property.name} the ${property.name}
     */
    <#-- (5)引数の型変換 -->
    public void set${property.name?cap_first}(${convertDataType(property.propertyClassSimpleName)} ${property.name}) {
        this.${property.name} = ${property.name};
    }
  </#list>
</#if>
}

編集内容の説明をします。

コメント:(1)カスタマイズfunction定義 の箇所
とコメントを打っている箇所は
A)引数で受けた型文字列を変換するconvertDataTypeメソッドです。
※変換仕様
Byte→Integer
int→Integer
Short→Integer

B)引数で受けたカラム名文字列がcreate_time or update_timeの場合にアノテーションに追加する文字列を返すaddElementメソッドです。
※仕様
create_timeの場合、", insertable=false" を返す。
update_timeの場合、", insertable=false, updatable=false" を返す。
それ以外は""を返す。

コメント:(2)アノテーションに要素追加 の箇所
@Columnの記載箇所でaddElementメソッドに呼び、アノテーションの要素をカスタマイズしています。

コメント:(3)変数の型変換 の箇所
とコメントを打っている箇所は
フィールド変数の記載箇所でconvertDataTypeを呼び、型をカスタマイズしています。

コメント:(4)戻り値の型変換 の箇所
とコメントを打っている箇所は
getterメソッドの記載箇所でconvertDataTypeを呼び、戻り値の型をカスタマイズしています。

コメント:(5)引数の型変換 の箇所
とコメントを打っている箇所は
setterメソッドの記載箇所でconvertDataTypeを呼び、引数の型をカスタマイズしています。

以上です。
freemarkerの構文さえ分かれば、entity生成をカスタマイズできるので
ぜひ試していただければと思います。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0