Edited at
KotlinDay 15

Kotlinでdata classでMyBatisをつかう

Kotlin Advent Calendar15日目の記事です。昨日はsckmさんScratchファイルを使って気軽に実行可能なコードを保存するでした!Scratchいいですね!月曜から使っていきたいと思います。

今日はKotlin + O/R MapperのMyBatisで、SQLクエリの結果をマッピングするモデルクラスをdata classにする方法について簡単にご紹介します。

KotlinのO/R MapperといえばExposedが有名ですが、SQLを直接書きたいためMyBatisを使っています。

モデルクラスなのでぜひぜひdata classにしたいですよね!

ですが、data classはイミュータブルで、コンストラクタの引数にすべてのプロパティの値を渡す必要があるため、そのままではMyBatisのモデルクラスとしては使えません。MyBatisはリフレクションを使ってモデルクラスをインスタンス化するため、引数なしのコンストラクタが必要なためです。

そこでNo-arg compiler pluginです。No-args compiler pluginは、引数なしのコンストラクタを合成してくれるプラグインです。Java/Kotinからはそのコンストラクタは使えませんが、リフレクションにより引数なしのコンストラクタが使えるようになります。アプリケーションコードからは普通のdata classとして使えるので安全です。

build.gradle

buildscript {

dependencies {
classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version"
}
}

apply plugin: "kotlin-noarg"

Grade Plugin DSLで

plugins {

id "org.jetbrains.kotlin.plugin.noarg" version "1.3.11"
}

して

annotation class Data

のようにアノテーションを定義して、そのアノテーションをbuild.gradleに追記します。

noArg {

annotation("com.my.annotation.Data")
}

そして定義したアノテーションをモデルクラスにつけるだけです。

import com.my.annotation.Data

@Data
data class User(
val id: Int? = null,
val name: String
)

ちなみにこのクラスのインスタンスを作り、insertするとDBで採番されたidがdata classに入ります。

val user = User(name = "foo")

insert(user)
user.id != null // true, DBで採番されたidが入る!

イミュータブルとは、という気持ちにもなりますが、スーパー便利です。

以上です!Kotlin最高!この知見は同期のスーパーエンジニアが教えてくれました。ここで感謝の意を表します。