🦜

Kotlin製ORMのexposedでCASE WHENを利用する

2023/10/12に公開

What's exposed ?

Kotlin 製の ORM(Object-Relational Mapping)ライブラリです。

wiki が提供されていますが結構情報が貧弱で、サブクエリを使った JOIN の方法なども書かれていないため、ハマりポイントになっています。

https://github.com/JetBrains/Exposed/wiki

サブクエリを使った JOIN についてはこちらの記事をご参照ください。

https://zenn.dev/bs_kansai/articles/48da45d52db79e

メンバー募集中!

サーバーサイド Kotlin コミュニティを作りました、ぜひご参加ください!!

https://serverside-kt.connpass.com/

想定する SQL

select
    EMPLOYEE_ID,
    case
        when ENROLLMENT_STATUS = '0' THEN '在籍中'
        when ENROLLMENT_STATUS = '1' THEN '休職中'
        when ENROLLMENT_STATUS = '2' THEN '退職済'
from EMPLOYEE
where departmentId = '1';

使用するテーブルの Object 定義

EmployeeTable.kt
import org.jetbrains.exposed.sql.Table
import org.jetbrains.exposed.sql.javatime.datetime

object EmployeeTable : Table("EMPLOYEE") {
    val employeeId = varchar("EMPLOYEE_ID", 10) //社員ID
    val departmentId = varchar("DEPARTMENT_ID", 10) //部署ID
    val enrollmentStatus = varchar("ENROLLMENT_STATUS", 2) //在籍状況 0:在籍中 1:休職中 2:退職済
}

実装

EmployeeDataAccessor.kt
val caseEnrollmentStatus = Expression.build {
    case()
        .when(EmployeeTable.enrollmentStatus eq '0', stringLiteral("在籍中"))
        .when(EmployeeTable.enrollmentStatus eq '1', stringLiteral("休職中"))
        .when(EmployeeTable.enrollmentStatus eq '2', stringLiteral("退職済"))
        .Else(
            stringLiteral("その他")
        )
}

EmployeeTable.slice(
    EmployeeTable.employeeId,
    caseEnrollmentStatus
).select{ EmployeeTable.departmentId eq '1' }
.toList()
.map{
    println(it[caseEnrollmentStatus])
}

以前紹介したカスタム関数でNVLを作る場合と同じく、リテラルをTHENの値として渡す場合には型Literalという関数を使ってあげるとよしなにやってくれます。

おわりに

case when も公式のドキュメントには書き方が載ってないので、なんとかしてほしいもんです。

メンバー募集中!

サーバーサイド Kotlin コミュニティを作りました、ぜひご参加ください!!

https://serverside-kt.connpass.com/

また関西在住のソフトウェア開発者を中心に、関西エンジニアコミュニティを一緒に盛り上げてくださる方を募集しています。

よろしければ Conpass からメンバー登録よろしくお願いいたします。

https://blessingsoftware.connpass.com/

Discussion