首页 > 解决方案 > jOOQ 3.15.1 新的 ad-hoc 转换 API 是否在 Kotlin 中工作?

问题描述

我正在尝试将jOOQ 3.15 的 New Multiset Operator Will Change How You Think About SQL的工作示例翻译成 Kotlin,但是我遇到了一些类型推断问题阻止我编译。

到目前为止:

    data class Actor(val firstName: String?, val lastName: String?)
    data class Film(val title: String?, val actors: List<Actor>, val 
    categories: List<String>)

    ...

    val future = dsl.select(
        FILM.TITLE,
        multiset(
            select(
                FILM_ACTOR.actor().FIRST_NAME,
                FILM_ACTOR.actor().LAST_NAME
            )
                .from(FILM_ACTOR)
                .where(FILM_ACTOR.FILM_ID.eq(FILM.FILM_ID))
        ).`as`("actors").convertFrom { it.map( mapping(::Actor) ) }, // <--[1]
        multiset(
            select(FILM_CATEGORY.category().NAME)
                .from(FILM_CATEGORY)
                .where(FILM_CATEGORY.FILM_ID.eq(FILM.FILM_ID))
        ).`as`("films").convertFrom { it.map { r -> r.getValue(0) } }
    )
        .from(FILM)
        .orderBy(FILM.TITLE)
        .fetchAsync()

    val result = future.await().map( mapping(::Film) ) // <--[2]

我遇到的问题在代码中的 [1] 和 [2] 中注明。

在 [1] 中,当获取构造函数引用时,它归结为 Kotlin 与 Java:

Type mismatch.
Required:  ((String?, String?) → Actor!)!
Found:     KFunction2<String, String, Actor>

......很接近,但没有雪茄。可能有一种我缺少的简单方法来适应它(除了手动调用构造函数)。

在 [2] 处,Kotlin 无法决定选择哪个重载mapping(...)

目前对我来说,为什么问题在每种情况下都不同是不透明的。

我能否获得一些指导,是否mapping(/*constructor reference*/): RecordManager<R,U>有望在 jOOQ 3.15.1 中与 Kotlin 一起使用?如果没有,我可以合理地做些什么来解决它?

标签: kotlinjooq

解决方案


关于问题 [1],有时不能选择使属性可为空:您的整个应用程序将被此可为空的属性污染。即使该列可能在数据库中被指定为 NOT NULL,jOOQ (3.15.1) 目前不提供非空记录字段(因为它们不能保证在例如外连接中是非空的)。

对于不可为空的属性,到目前为止我发现的最简单的解决方案是这个构造:

    multiset(
        select(
            FILM_ACTOR.actor().FIRST_NAME,
            FILM_ACTOR.actor().LAST_NAME
        )
    .from(FILM_ACTOR)
    .where(FILM_ACTOR.FILM_ID.eq(FILM.FILM_ID))
    ).`as`("actors").convertFrom(List::class.java) { it.map { s -> Actor(s.value1()!!, s.value2()!!) } },

推荐阅读