Skip to content

Instantly share code, notes, and snippets.

@nakamura-to
Created July 27, 2024 03:38
Show Gist options
  • Save nakamura-to/6435854055e4427185b97705afc821cd to your computer and use it in GitHub Desktop.
Save nakamura-to/6435854055e4427185b97705afc821cd to your computer and use it in GitHub Desktop.
Komapperで複数エンティティに共通のプロパティを使ってクエリを組み立てる方法
package org.komapper.quickstart
import org.komapper.core.dsl.Meta
import org.komapper.core.dsl.QueryDsl
import org.komapper.core.dsl.expression.WhereDeclaration
import org.komapper.core.dsl.scope.WhereScope
import org.komapper.jdbc.JdbcDatabase
import java.time.LocalDateTime
fun main() {
val database = JdbcDatabase("jdbc:h2:mem:quickstart;DB_CLOSE_DELAY=-1")
database.withTransaction {
val p = Meta.person
val a = Meta.address
database.runQuery {
QueryDsl.create(p, a)
}
// Personのクエリ
val query1 = QueryDsl.from(p).where {
// BiTemporalMetamodelに共通のWHERE句を生成する拡張関数を利用
biTemporal(p.asBiTemporal(), 1, LocalDateTime.now())
p.name eq "Alice"
}
// Addressのクエリ
val query2 = QueryDsl.from(a).where {
// BiTemporalMetamodelに共通のWHERE句を生成する拡張関数を利用
biTemporal(a.asBiTemporal(), "Tokyo", LocalDateTime.now())
a.city eq "Tokyo"
}
// select t0_.id, t0_.name, t0_.age, t0_.valid_from, t0_.valid_to from person as t0_ where t0_.id = ? and t0_.valid_from <= ? and t0_.valid_to > ? and t0_.name = ?
database.runQuery(query1)
// select t0_.id, t0_.city, t0_.valid_from, t0_.valid_to from address as t0_ where t0_.id = ? and t0_.valid_from <= ? and t0_.valid_to > ? and t0_.city = ?
database.runQuery(query2)
}
}
// BiTemporalMetamodelに共通のWHERE句を生成する拡張関数
fun <ID: Any> WhereScope.biTemporal(b: BiTemporalMetamodel<ID>, id : ID, date: LocalDateTime) {
val where: WhereDeclaration = {
b.id eq id
b.validFrom lessEq date
b.validTo greater date
}
this.apply(where)
}
package org.komapper.quickstart
import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.Test
import org.komapper.core.dsl.Meta
class BiTemporalMetamodelTest {
@Test
fun test() {
val p = Meta.person
val a = Meta.address
assertNotNull(p.asBiTemporal())
assertNotNull(a.asBiTemporal())
}
}
package org.komapper.quickstart
import org.komapper.annotation.KomapperAutoIncrement
import org.komapper.annotation.KomapperEntity
import org.komapper.annotation.KomapperId
import org.komapper.core.dsl.expression.PropertyExpression
import org.komapper.core.dsl.metamodel.EntityMetamodel
import java.time.LocalDateTime
@KomapperEntity
data class Person(
@KomapperId
@KomapperAutoIncrement
val id: Int = 0,
val name: String,
val age: Int,
val validFrom: LocalDateTime,
val validTo: LocalDateTime,
)
@KomapperEntity
data class Address(
@KomapperId
val id: String = "",
val city: String,
val validFrom: LocalDateTime,
val validTo: LocalDateTime,
)
// エンティティメタモデルの共通プロパティをまとめたインターフェース
interface BiTemporalMetamodel<ID : Any> {
val id: PropertyExpression<ID, ID>
val validFrom: PropertyExpression<LocalDateTime, LocalDateTime>
val validTo: PropertyExpression<LocalDateTime, LocalDateTime>
}
// エンティティメタモデルをBiTemporalMetamodelに変換する拡張関数
fun <ENTITY : Any, ID : Any, META : EntityMetamodel<ENTITY, ID, META>> asBiTemporal(metamodel: META): BiTemporalMetamodel<ID> {
val id = metamodel.idProperties().single()
val validFrom = metamodel.properties().single { it.name == "validFrom" }
val validTo = metamodel.properties().single { it.name == "validTo" }
id as PropertyExpression<ID, ID>
validFrom as PropertyExpression<LocalDateTime, LocalDateTime>
validTo as PropertyExpression<LocalDateTime, LocalDateTime>
return object : BiTemporalMetamodel<ID> {
override val id: PropertyExpression<ID, ID> = id
override val validFrom: PropertyExpression<LocalDateTime, LocalDateTime> = validFrom
override val validTo: PropertyExpression<LocalDateTime, LocalDateTime> = validTo
}
}
// PersonのエンティティメタモデルをBiTemporalMetamodelに変換する拡張関数
fun _Person.asBiTemporal() = asBiTemporal(this)
// AddressのエンティティメタモデルをBiTemporalMetamodelに変換する拡張関数
fun _Address.asBiTemporal() = asBiTemporal(this)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment