jOOQでMySQLのTINYINT(1)をBooleanにマップする方法
jOOQでMySQLのBooleanをジェネレートしたところ、型がBooleanにマッピングされていないことが発覚。
調べてみると、この問題の解決方法をjOOQの公式がブログにしてくれていました。(ただし、Java + Mavenのサンプルのみ)
この記事では、この問題の簡単な解説と公式のJava + Mavenの実装例を参考に、Kotlin + Gradleで実装し直したものを紹介します。
原因
原因は、MySQLの仕様でBooleanがTINYINT(1)として表現されていることでした。
その結果、TINYINT(1)をjOOQは正しく認識して型に変換するため、Booleanにならないことが問題でした。
また公式としてはTINYINT(1)を使用するユーザーがいる可能性を考慮して、デフォルトでTINYINT(1)をBooleanに変換する気はないようです。
そのため、自分でジェネレートの設定を上書きする必要があるという訳です。
解決策
実際の解決策としては、configurationsのForced typesで型変換の上書きします。
以下が今回のBooleanを上書きするための設定です。
jooq {
configurations {
create("main") {
jooqConfiguration.apply {
... // 省略
generator.apply {
name = "org.jooq.codegen.KotlinGenerator"
database.apply {
... // 省略
forcedTypes.addAll(
listOf(
ForcedType().apply {
name = "boolean"
includeTypes = "(?i:TINYINT\\(1\\))"
}
)
)
}
... // 省略
}
}
}
}
}
name
にはjooqGenerateしたい型、includeTypes
には実際にDBに存在する型を指定しておくことで型が上書きされます。
(今回のincludeTypes
にはJavaの正規表現を利用しています)
複数定義する場合はlistにForcedTypeを追加していけば良いです。
感想
Booleanは基本的な型だと思っていたので、最初は「なんでぇ?」となりましたが、意外と重要なことだったので誰かのお役に立てれば幸いです。
あと最近、MySQLからMariaDBに乗り換える機会があったのですが、MariaDBでも同様にTINYINT(1)でBooleanが表現されていたので、この実装が地味に役立っています!
Discussion