こんにちは。虎の穴ラボ所属のH.Kです。
虎の穴ラボではKotlinを使っているのですが、SQLをソース上にあまり書きたくないエンジニアもいて、"Doma2なら"と思い、このたび環境構築しました。
現在Spring InitializrにてKotlin、Gradleでひな形プロジェクトを作成すると、Gradle Kotlin DSLを使用したプロジェクトとなります。
Gradle Kotlin DSL(build.gradle.kts)での構築方法について言及が少なかったため、備忘録も兼ねて手順を公開します!
そもそもDoma2とは
Java(Kotlin対応)のORMです。
公式リファレンスはこちらです。
特徴としては以下のようなものになります。(公式リファレンスより引用)
・注釈処理を使用して コンパイル時 にコードの生成やコードの検証を行う
・データベース上のカラムの値を振る舞いを持った Java オブジェクトにマッピングできる
・2-way SQL と呼ばれる SQL テンプレートを利用できる
・Java 8 のjava.time.LocalDate
やjava.util.Optional
やjava.util.stream.Stream
を利用できる
・JRE 以外のライブラリへの依存が一切ない
2-way SQLのため発行されるクエリがわかりやすくプログラムを実行しなくてもどのようなSQLが発行されるか確認できます。
またKotlinのソースとSQLがファイルとして分離されるため、見通しの良いソースを書くことができます。
作業環境
- macOS
- IntelliJ
この記事で作成するプロジェクトの構成
- Kotlin
- Spring Boot
- Gradle(Gradle Kotlin DSL)
- Doma2
- Java8
- H2DB
ひな形プロジェクトの作成
Spring InitializrにてKotlin、Gradleのひな形プロジェクトを作成します。
- Project:Gradle Project
- Language:Kotlin
- Spring Boot:2.1.7
- Project Metadata:お好みで(今回はoptionsにてPackaging:War、Java:8を選択)
今回、依存関係は以下を追加します。
DBのDriver関係は構築したい環境に合わせて変更してください。
- Spring Web Starter(RESTで画面表示する用)
- H2 Database(サクッとDB接続を確認する用)
ここまで設定したらGenerate the projectでひな形プロジェクトを作成します。
作成したひな形プロジェクトを解凍し、intelliJで開きます。
IntelliJの設定追加
Annotation Processingの設定を行います。
Preferences>Build, Excution, Deployment>Compiler>Annotation Processors
- Enable annotation processingをチェックする
- Store generated sources relative toをModule content rootに設定する
build.gradle.ktsの設定
公式サンプルプロジェクトのbuild.gradleの記載に合わせbuild.gradle.ktsを修正していきます。 github.com
最終的なbuild.gradle.kts
最終的には以下のようになります。(記載が完了したら依存関係をImportしてください。)
build.gradle.kts
build.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { id("org.springframework.boot") version "2.1.7.RELEASE" id("io.spring.dependency-management") version "1.0.7.RELEASE" war kotlin("jvm") version "1.2.71" kotlin("plugin.spring") version "1.2.71" id("org.jetbrains.kotlin.kapt") version "1.2.71" } group = "com.example" version = "0.0.1-SNAPSHOT" java.sourceCompatibility = JavaVersion.VERSION_1_8 configurations { compileOnly { extendsFrom(configurations.annotationProcessor.get()) } } repositories { mavenCentral() maven("https://oss.sonatype.org/content/repositories/snapshots/") } dependencies { implementation("org.springframework.boot:spring-boot-starter-web") implementation("com.fasterxml.jackson.module:jackson-module-kotlin") implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") providedRuntime("org.springframework.boot:spring-boot-starter-tomcat") testImplementation("org.springframework.boot:spring-boot-starter-test") compile("com.h2database:h2:1.4.191") compile("org.seasar.doma.boot:doma-spring-boot-starter:1.1.1") kapt("org.seasar.doma:doma:2.24.0") implementation("org.seasar.doma:doma:2.24.0") } val compileKotlin: KotlinCompile by tasks kapt { arguments { arg("doma.resources.dir", compileKotlin.destinationDir) } } tasks.register("copyDomaResources",Sync::class){ from("src/main/resources") into(compileKotlin.destinationDir) include("doma.compile.config") include("META-INF/**/*.sql") include("META-INF/**/*.script") } tasks.withType<KotlinCompile> { dependsOn(tasks.getByName("copyDomaResources")) kotlinOptions { freeCompilerArgs = listOf("-Xjsr305=strict") jvmTarget = "1.8" } }
部分ごとに少し細かく見ていきます。
1.pluginsにkaptを追加
kaptとはDoma2で使用するPluggable Annotation Processing API (アノテーションを使ってソースコードを生成する仕組み)をKotlinで行うためのツールです。
pluginsにkaptを追加します。
plugins{ . . . id("org.jetbrains.kotlin.kapt") version "1.2.71" }
Annotation Processingの設定を取得します。
configurations {
compileOnly {
extendsFrom(configurations.annotationProcessor.get())
}
}
2.Doma2の依存関係を追加
Doma2をリポジトリーから取得する設定を追加します。
まずrepositoriesにスナップショットのリポジトリーを追加します。
repositories {
mavenCentral()
maven("https://oss.sonatype.org/content/repositories/snapshots/")
}
次にdependenciesにimplementationとkaptにdomaの依存関係を示します。
dependencies { . . . compile("org.seasar.doma.boot:doma-spring-boot-starter:1.1.1") kapt("org.seasar.doma:doma:2.24.0") implementation("org.seasar.doma:doma:2.24.0") }
3.コンパイル時のタスクを設定
まずSQLファイル等をコピーするタスクを作成します。
val compileKotlin: KotlinCompile by tasks kapt { arguments { arg("doma.resources.dir", compileKotlin.destinationDir) } } tasks.register("copyDomaResources",Sync::class){ from("src/main/resources") into(compileKotlin.destinationDir) include("doma.compile.config") include("META-INF/**/*.sql") include("META-INF/**/*.script") }
Kotlinのコンパイルタスクに作成したタスクを依存させます。
tasks.withType<KotlinCompile> { dependsOn(tasks.getByName("copyDomaResources")) kotlinOptions { freeCompilerArgs = listOf("-Xjsr305=strict") jvmTarget = "1.8" } }
DB設定
Gradleの設定が完了したので、DBの設定になります。
H2DBの接続設定
H2DBの接続設定を行います。
実際に使用するDBの設定に合わせて適宜変更してください。
application.properties
spring.datasource.url= jdbc:h2:mem:test; spring.datasource.driverClassName= org.h2.Driver spring.datasource.username= sa spring.datasource.password= spring.h2.console.enabled= true
環境確認用ソースの実装
DBからデータを取得して画面に表示する簡単な処理を作ってみます。
最終的なプロジェクトの構成はこのようになります。
Entityの作成
DBのテーブルに対応するEntityを作成します。
DemoTable.kt
package com.example.doma.domademo.entity import org.seasar.doma.Entity import org.seasar.doma.Id @Entity(immutable = true) data class DemoTable(@Id val id: Int,val name: String)
Dao(インターフェイス)の作成
Daoインターフェイスを作成します。
Doma2ではDao実装クラスの作成は不要です(インターフェイスから自動で作成されるため)
DIコンテナの管理対象とするためDaoクラスには@ConfigAutowireable
を設定しています。
DemoTableDao.kt
package com.example.doma.domademo.dao import com.example.doma.domademo.entity.DemoTable import org.seasar.doma.Dao import org.seasar.doma.Insert import org.seasar.doma.Select import org.seasar.doma.boot.ConfigAutowireable import org.seasar.doma.jdbc.Result @Dao @ConfigAutowireable interface DemoTableDao { @Insert fun insert(entity : DemoTable):Result<DemoTable> @Select fun selectAll():List<DemoTable> }
RESTコントローラの作成
画面に表示して確認するためにDaoから取得した値をそのまま返却するコントローラを作成します。
DemoController.kt
package com.example.doma.domademo.controller import com.example.doma.domademo.dao.DemoTableDao import org.springframework.beans.factory.annotation.Autowired import org.springframework.web.bind.annotation.GetMapping import org.springframework.web.bind.annotation.RestController @RestController class DemoController { @Autowired lateinit var demoTableDao : DemoTableDao @GetMapping(value = "/") fun index() : String=demoTableDao.selectAll().toString() }
Daoに対応するSQLファイルの追加
DaoのselectAllメソッドに対応するSQLファイルを作成します。
今回、Daoはcom.example.doma.domademo.dao
に作成しているため、
SQLファイルはresouces/META-INF/com/example/doma/domademo/dao/DemoTableDao
に作成します。
selectAll.sql
select * from DEMO_TABLE;
確認用SQLの作成
起動時にH2DBに自動でテーブルを作成し、データを追加できるように以下のSQLファイルをresoucesに配置します。
schema.sql
CREATE TABLE IF NOT EXISTS demo_table ( id INTEGER NOT NULL , name VARCHAR(255) NOT NULL, PRIMARY KEY (id) );
data.sql
insert into demo_table(id,name) values(1,'test1'); insert into demo_table(id,name) values(2,'test2');
いざ実行!
gradleでclean
build
します。
そしてbootRun
!
http://localhost:8080/
にアクセスして以下のように表示されれば成功です!!
まとめ
今回はKotlin、Spring-boot、Doma2をGradle Kotlin DSLで環境構築してみました。
Gradle Kotlin DSLに関してはまだまだ日本語の情報が少ないように思えます。
Doma2の環境に関わらずGradle Kotlin DSL記載のサンプルとして役に立てばと考えています。
またDoma2は最初に説明した通り、Kotlin(Java)のソースとSQLがファイルとして分離されます。
メンテナンスしやすく、いいライブラリだと個人的には感じていますので、Kotlinと組み合わせて便利なツールを開発していきたいです。
P.S.
虎の穴では一緒に働く仲間を絶賛募集中です! この記事を読んで、興味を持っていただけた方はぜひ弊社の採用情報をご覧下さい。 yumenosora.co.jp
また、今月8/28には渋谷にて会社説明会を開催いたします。ご興味のある方は是非ご応募ください! yumenosora.connpass.com