Kotlin サポート

Doma は Kotlin を実験的にサポートしています。

Kotlin利用のベストプラクティス

クラスの定義やビルドに関する事柄について推奨する方法を記載します。

エンティティクラス

  • Data Classで定義する
  • イミュータブルで定義する( @Entityimmutable 要素に true を設定する)
  • コンストラクタは1つだけ定義する
  • コンストラクタ以外でプロパティを定義しない
  • コンストラクタで定義するプロパティには val を使用する
  • 継承は使わない
@Entity(immutable = true)
data class Person(
      @Id
      @GeneratedValue(strategy = org.seasar.doma.GenerationType.IDENTITY)
      val id: Int? = null,
      val name: Name,
      val address: Address)

ドメインクラス

  • Data Classで定義する
  • コンストラクタは1つだけ定義する
  • コンストラクタで定義するプロパティの名前は value にする
  • コンストラクタで定義するプロパティには val を使用する
@Domain(valueType = String::class)
data class Name(val value: String)

エンベッダブルクラス

  • Data Classで定義する
  • コンストラクタは1つだけ定義する
  • コンストラクタ以外でプロパティを定義しない
  • コンストラクタで定義するプロパティには val を使用する
  • 継承は使わない
@Embeddable
data class Address(val city: String, val street: String)

Daoインタフェース

  • SQLファイルとマッピングする場合は @ParameterName を使ってメソッドのパラメータに名前をつける
  • 更新処理の戻り値の型は org.seasar.doma.jdbc.Resultorg.seasar.doma.jdbc.BatchResult を使う
@Dao(config = AppConfig::class)
interface PersonDao {
  @Select
  fun selectById(@ParameterName("id") id: Int): Person
  @Insert
  fun insert(person: Person): Result<Person>
}
val dao: PersonDao = ...
val person = Person(name = Name("Jhon"), address = Address(city = "Tokyo", street = "Yaesu"))
val (newPerson, count) = dao.insert(person)

katpによるビルド

Kotlin で記述されたクラスやインタフェースに対して注釈処理をするには kapt を実行する必要があります。 2016年5月現在、Kotlin 1.0.2のkaptは機能が不足しておりかつ動作が不安定です。また、ドキュメントがありません。 Daoインタフェースで @ParameterName を用いて明示的に名前をつけることを推奨するのも kapt の不具合に由来します。 不安定な挙動を避けるため、Gradleでビルドする際、常に clean build を実行することを推奨します。

./gradlew clean build

Eclispeを利用する場合設定を適切に行えばJavaの注釈処理は自動で行われますが、kapt(Kotlinの注釈処理)はGradleを実行しない限り行われないことに注意してください。

JavaとKotlinの混在

kaptの不具合を避けるため、Domaに関するコードの全てもしくは一部をJavaで書くことは検討に値します。 特に、DaoについてはJavaで書いても良いかもしれません。 JavaとKotlinで記述量にほとんど差がなく、 @ParameterName を使う必要性を避けられるためです。 Domaの利用において、JavaとKotlinの混在は特に問題ありません。

サンプルプロジェクト

サンプルコードについては下記のプロジェクトを参照ください。