Doma2をGradle/Springプロジェクトに適用するのはかなり難しかった。dependenciesに追加するだけではダメだった。
なぜ、DB接続にDoma2を使うか?
これまで複数のSpringBoot案件に入ってきましたが、最も開発体験が良かったのはDoma2でした。
特徴 | メリット | デメリット | |
JPA・hibernate系 | SQLではなくエンティティを操作することでCRUDを実現。 | ・命名規約に沿ったメソッド名でSQL自動生成してくれる。 | ・SQLを書いた方が良いケースが必ず出てくる。 ・生成されるSQLをチューニングするのが面倒。 |
MyBatis | |||
Doma2 | SQLテンプレートを利用。 任意のDTOに結果が格納できる。 |
Doma2の基本情報
バージョン
コンパイル | 動作可能 | |
Doma(1) | Java6 | Java6,Java7,Java8 |
Doma2 | Java8 | Java8以降 |
Gradle/SpringBootからDoma2でデータベースに接続する方法
実案件では、テーブル数が多いためEntityの自動生成が必須になると思います。また、Entityクラスが配布されている事で、メンバの開発体験は大幅に高まります。
Gradle/SpringBoot で doma2-gen でエンティティを自動生成
flywayMigrateなどでDBに変更を加えたら、その都度Daoとエンティティの自動生成をやり直す必要がある。
Gradle/SpringBoot から Doma2でCRUD
<<Doma2をGradleに適用する場合、最も正確な情報はこちらです。>>
https://doma.readthedocs.io/en/2.20.0/build/#gradle
build.gradleに下記を追記して、必要ライブラリを読み込む。
dependencies {
implementation 'org.seasar.doma.boot:doma-spring-boot-starter:1.5.0'
}
compileJava {
options.compilerArgs = ['-Adoma.dao.subpackage=impl', '-Adoma.dao.suffix=Impl']
}
dependenciesを追加すると、@Dao や @SelectなどDAOに記述するアノテーションが使用できるようになっている。
compileJavaのoptions.compilerArgsを追加するだけでは、Daoの実装クラスを自動生成してくれなかった。
> Task :compileJava
警告:次のオプションはどのプロセッサでも認識されませんでした: '[doma.dao.suffix, doma.dao.subpackage]'
警告1個
今回はIntelliJでやろうとしているが、自動生成させるためにはEclipseのDoma Toolsプラグインに相当するものが必要らしい。
dependencies {
implementation 'org.seasar.doma.boot:doma-spring-boot-core:1.5.0'
implementation 'org.seasar.doma:doma:2.29.0'
}
processResources.destinationDir = compileJava.destinationDir
compileJava.dependsOn processResources
上記を追加してもダメだった。
このように設定することで、Annotation Processingが動き始めた。
dependencies {
implementation 'org.seasar.doma.boot:doma-spring-boot-starter:1.5.0'
annotationProcessor 'org.seasar.doma.boot:doma-spring-boot-core:1.5.0'
annotationProcessor 'org.seasar.doma:doma:2.29.0'
}
しかし、SQLファイルが想定の場所にないと怒られた。
D:\sample-project\sample-project-api\src\main\java\com\example\sampleprojectapi\dao\UsersDao.java:13: エラー: [DOMA4019] The file "META-INF/com/example/sampleprojectapi/dao/UsersDao/selectIds.sql" is not found in the classpath. The absolute path is "D:\sample-project\sample-project-api\build\classes\java\main\META-INF\com\example\sampleprojectapi\dao\UsersDao\selectIds.sql".
List<Long> selectIds();
^
sample-project-api\build\classes\java\main\META-INF\com\example\sampleprojectapi\dao\UsersDao\selectIds.sql
にあるべきファイルが、今は、
sample-project-api\build/resources/main/META-INF/com/example/sampleprojectapi/dao/UsersDao/selectIds.sql
に出力されている。
出力先を変えるか、DomaのProcessorが見る場所を変えるかする必要がありますね。
とりあえず、無理やりSQLファイル群の出力先を要求している場所に変えた。
sourceSets {
main {
// output.resourcesDir = file("$buildDir/classes/java/main") 下の方がいい
output.resourcesDir = compileJava.destinationDir
}
}
すると今度はAbstractDaoがないと怒られた。
D:\sample-project\sample-project-api\build\generated\sources\annotationProcessor\java\main\com\example\sampleprojectapi\dao\impl\UsersDaoImpl.java:6: エラー: シンボルを見つけられません
public class UsersDaoImpl extends org.seasar.doma.internal.jdbc.dao.AbstractDao implements com.example.sampleprojectapi.dao.UsersDao {
^
シンボル: クラス AbstractDao
場所: パッケージ org.seasar.doma.internal.jdbc.dao
最終的にdependenciesはこうすると動かせた。(これだけで良い)
dependencies {
annotationProcessor 'org.seasar.doma:doma:2.29.0' // Doma2 DaoImplの自動生成用
implementation 'org.seasar.doma:doma:2.29.0' // Doma2の基本アノテーションが使える
implementation 'org.seasar.doma.boot:doma-spring-boot-starter:1.5.0' // Doma2のSpring向けアノテーションが使える
}
annotationProcessor はAnnotation Processing中にだけ依存性追加するらしい。自動生成された実装クラスをコンパイルして動かすときにも、AbstractDaoを含むライブラリが必要なのかと考え、5行目を追加した。
動いたかが、現在こんな場所に自動生成されている。これを、Daoインターフェースと同じ場所に吐き出せるようにした。
https://doma.readthedocs.io/en/2.20.0/build/#intellij-idea にある「注釈処理で生成されたコードが出力されるディレクトリを Generated Sources Root に設定する」が必要な気がする。
Doma2の設定は難しかった
そしたらやっと動いてくれた。
Doma2動かすの難しすぎる!!!!
build.gradleのこと、Groovyのこともちょっとは理解してないと使い始められないかもです。
Annotation Processing とは?
Doma2の設定が難しく感じるのは、Annotation Processingという聞き慣れない用語が出てくるため。
これは、コンパイル時にアノテーションを処理する仕組みのこと。コンパイル時にアノテーションを読み取って、ソースを自動生成してくれる、Java 1.6 から使えるようになった仕組みです。
Domaでは@Daoをインターフェースでコーディングする。実装クラスはAnnotation Processingによってコンパイル時に生成される。生成された実装クラスが、実行時にAutowiredされるというわけだ。
IntelliJでDoma2開発するならDomaサポートプラグインを入れよう
@Daoのメソッドから、SQLへジャンプできるプラグインがあります。めちゃくちゃ便利なので絶対に入れましょう!
と思ったら、Ultimateエディションじゃないと入れられないみたいです。買おうかな・・・。(Ultimateエディションの人はDoma Supportプラグインのページへ。)
参考
https://springboot-domamaster-maintenance-sample.readthedocs.io/ja/latest/
IntelliJ IDEAのDomaサポートプラグイン・・・DAOからSQLファイルへの移動ができるようになる。