Created
July 27, 2024 03:38
-
-
Save nakamura-to/6435854055e4427185b97705afc821cd to your computer and use it in GitHub Desktop.
Komapperで複数エンティティに共通のプロパティを使ってクエリを組み立てる方法
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()) | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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