0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

MyBatis Dynamic SQLでつまづいた~型が一致しません。~

Last updated at Posted at 2021-06-01

はじめに

手を動かして事象を理解しただけで、本質的に間違っている部分があれば、ご指摘いただけると幸いです。 :man-bowing:

環境

  • MyBatis
  • MyBatis Generator
  • Kotlin

起きたこと

以下のソースコードでなぜか怒られた。

SampleRepositoryImpl.kt(例)
SampleMapper.select {
    where(userIdFromDb, isEqualTo(userId))
    if(limit >= 1){limit(limit.toLong())}// ->この行が「型が一致しません。必要:Buildable<SelectModel> 検出:Unit」と言われる
}

※SampleMapper#selectはMyBatis Generatorが自動生成してくれるselectメソッド(MyBatis Dynamic SQL)です。
limitに変な値が来ても大丈夫なよう「limitが1以上ならSQLにLIMIT句を付けてほしい」だけで、
変な値だったらWHERE句だけにしてくれればいいのにな。。。という感想。(例のlimitは他の andoffset に読み替えていただけます)

事象理解

Kotlinならではの事象だと理解しました。端的に説明すると
if文判定した結果falseの場合、 if文の戻り値が無しKotlinで戻り値無しはUnit型扱いとなり型が不一致(KotlinQueryBuilderを期待している)
ということで、「if文の結果、空行になったとしても、if文を判定した以上、if文の戻り値(はないのでUnit)がselectに渡される」んだなあ、、と。

回避策

ただ回避するための策になったので、別案を募っております。

SampleRepositoryImpl.kt
SampleMapper.select {
    where(userIdFromDb, isEqualTo(userId))
    if(limit >= 1){limit(limit.toLong())} else {this}

this: KotlinQueryBuilder なので、「返すものがないならthisを返せばいいじゃない」という発想です。
ただこれ、if文が複数行続く場合「最後のやつにだけ付ければオーケー」という謎ルールになりスマートではないな、、と。

ひとまずbuildで怒られなくなりました、という話でした。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?