定義したもの
import org.jooq.Field import org.jooq.Record inline fun <reified T> Record.read(field: Field<*>): T = this[field, T::class.java]
使い方
以下のように使います。
import org.jooq.Field import org.jooq.Record // FOOテーブルに定義された文字列型のFieldを想定 val field: Field<String?> = FOO.STRING_FIELD // select結果などを保持するRecordを想定 val record: Record // 以下のように、要求された型に応じた読み出しができる val s1: String = record.read(field) val s2: String? = record.read(field) // エルビス演算子もよしなに判断してくれる val s3: String = record.read(field) ?: ""
嬉しさ
jOOQ
がデフォルトで想定している読み出し方法の内最もシンプルなものは、Record
に定義された<T> T get(Field<T> field)
を利用することです。
一方、KotlinGenerator
で生成されるコードではField
(TableField
)の型引数が常にnullable
となるため、non-null
な値として読み出す場合、一々!!
で強制アンラップを行う必要が有ります。
// 単純にgetを用いた例 val s: String = record[field1]!!
また、Record
から何かしらの変換を伴う読み出しを行う場合は<U> U get(Field<?> field, Class<? extends U> type)
を利用することになりますが、この関数はKClass
を受け付けません。
このため、Kotlin
から利用した際の見た目がよろしくありません。
// 変換を伴うgetを用いた例 import java.time.LocalDate val d: LocalDate = record[field2, LocalDate::class.java]
今回定義した関数を使えば、両方ともシンプルかつ画一的な書き方ができます。
また、読み出し先がnullable
になるような場合でも同様に書くことができます。
// 今回定義した関数を使った例 import java.time.LocalDate val s: String = record.read(field1) val d: LocalDate = record.read(field2) // 要求される値がnullableな場合も同様に書ける val s2: String? = record.read(field1)
クエリに対して期待される読み出し結果は基本的にマップ先の型に全て書かれているため、この関数を利用することで表現の重複を減らして機械的に書きやすくなります。
補足
関数の名前をread
にしているのは、get
にするとjOOQ
デフォルトの内容と名前が被ってしまうためです。