doma-codegen-pluginを触ってみる
概要
doma-codegen-plugin
とはデータベースのテーブル定義からEntityを生成してくれる素敵なgradleプラグイン。
今回はこのプラグインを動かしてどんなコードができるのか確認してみます。
便利なサンプルリポジトリ
doma-codegen-plugin入りのKotlin向けのDOMAサンプルリポジトリが既にあるので、それを使っていきます。
サンプルでDBまわりの設定とテーブル定義のスクリプトも完備。
あとはビルドするだけです。
まずはお試し
細かくドキュメントを見ていく前にせっかく動くサンプルがあるので、確認をしてみる。
とりあえず生成してみよう
READMEに従って、まずはコードの生成をしてみる。
./gradlew domaCodeGenDevEntity
ビルド後変化があったファイル。
ちゃんと、Kotlinで生成されている。
既に存在するentityファイルが再生成された模様。
生成されたコードを見てみよう
2つあるテーブルのうちdepartmentから見てみる。
create table department( id int not null identity primary key, name varchar(20), version int not null );
生成されたコードはこちら。
@Entity(listener = DepartmentListener::class, metamodel = Metamodel()) @Table(name = "DEPARTMENT") class Department : AbstractDepartment() { /** */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "ID") var id: Int = -1 /** */ @Column(name = "NAME") var name: Name? = null /** */ @Version @Column(name = "VERSION") var version: Int = -1 }
Table名のアノテーションはもちろんのこと、VERSIONやIDもちゃんと設定されている。
DomaのDomain定義(Nameの型)も設定されている。
(どこで設定しているんだ…?)
domaCodeGen設定を見ていく
動作はわかったので、なぜこうなるのかを設定を見ながら確認していく。
config
pluginの方のREADMEを見ると、plugin自体の設定もbuild.gradle.ktsに記入するらしい。
GitHub - domaframework/doma-codegen-plugin: Generates Java, Kotlin, and SQL files from Database
今回のサンプルだとこの辺。
domaCodeGen { register("dev") { url.set(h2Url) user.set(h2User) password.set(h2Password) languageType.set(org.seasar.doma.gradle.codegen.desc.LanguageType.KOTLIN) entity { packageName.set("sample.entity") val mappingFile = layout.projectDirectory.file("$projectDir/codegen-name-mapping.properties") entityPropertyClassNamesFile.set(mappingFile) } } }
configの一覧はこの辺。
GitHub - domaframework/doma-codegen-plugin: Generates Java, Kotlin, and SQL files from Database
DBへの接続情報諸々。
実際にDB内の定義を見て生成しているらしい。
(つまり作成用のスクリプトがなくてもDB現物があればEntityが作れる・・・?)
url.set(h2Url) user.set(h2User) password.set(h2Password)
このlanguageTypeの設定でKotlin/Javaを切り替えている模様。
languageType.set(org.seasar.doma.gradle.codegen.desc.LanguageType.KOTLIN)
試しにJavaに変更して、再生成してみる。
languageType.set(org.seasar.doma.gradle.codegen.desc.LanguageType.JAVA)
entityの設定
domaCodeGenのentityブロックを見ていく。
entity { packageName.set("sample.entity") val mappingFile = layout.projectDirectory.file("$projectDir/codegen-name-mapping.properties") entityPropertyClassNamesFile.set(mappingFile) }
設定の一覧はこの辺。
GitHub - domaframework/doma-codegen-plugin: Generates Java, Kotlin, and SQL files from Database
生成先のパッケージ名の設定。
packageName.set("sample.entity")
ここでDomaのDomainの設定がされている様子。
val mappingFile = layout.projectDirectory.file("$projectDir/codegen-name-mapping.properties") entityPropertyClassNamesFile.set(mappingFile)
参照されている、codegen-name-mapping.properties
はこんな感じ。
gender=sample.domain.Gender name=sample.domain.Name
左辺と同じ名前なら、ここで設定されているClassがdomainと紐づけられる…ということだろうか。
試しにちょっとnameの方の定義を変えてみる。
gender=sample.domain.Gender name__=sample.domain.Name
生成されたコードの該当箇所がこちら。
@Column(name = "NAME") - var name: Name? = null + var name: String? = null
この通り、型がStringに変更された。
推測通りで間違いなさそう。
(逆に言うと同じDomainは同名にする必要があるのかな・・・?)
他にも設定を見る限りListenerや基底クラス生成が不要な場合、設定変更で対応できるっぽい。
触ってみた感想
DTO的なEntityの生成ツールは、いくつか種類があるけれどもDomaを使っている場合はこれ一択な気がします。
コード自体は毎回洗い替えというか、生成しなおした方がシンプルなのでDB上の定義以外のドメインロジックは別のEntityとして持った方が取り回しが良さそうです。