【问题标题】:Jooq reactive fetching using r2dbc driverJooq 使用 r2dbc 驱动程序进行响应式获取
【发布时间】:2021-09-23 14:38:31
【问题描述】:

我的查询看起来像(使用 JOOQ v 3.15):

    override fun getCredentialsById(id: Long): Mono<UserCredentialsModel> {
    return Mono.from {
        dsl.select(
                USER_CREDENTIALS.ID,
                USER_CREDENTIALS.EMAIL,
                USER_CREDENTIALS.PHONE,
                USER_CREDENTIALS.LOGIN,
                USER_CREDENTIALS.PASSWORD)
            .from(USER_CREDENTIALS)
            .where(USER_CREDENTIALS.ID.eq(id))
            .and(USER_CREDENTIALS.IS_ACTIVE.eq(true))
            .fetchInto(UserCredentialsModel::class.java)
    }
}

JOOQ 配置:

@Bean
fun createContext(): DSLContext {
    return DSL.using(connection)
}

其中connectionio.r2dbc.spi.ConnectionFactory

我遇到了一个异常:

org.jooq.exception.DetachedException: Attempt to execute a blocking method (e.g. Query.execute() or ResultQuery.fetch()) when only an R2BDC ConnectionFactory was configured

我应该如何以响应式风格将我的查询结果提取到 Kotlin 数据类(或 Java JOOQ 的 POJO)中?

【问题讨论】:

标签: jooq r2dbc


【解决方案1】:

当以响应方式使用 jOOQ 时,您永远不应该调用任何阻塞方法,例如 ResultQuery.fetchOneInto(Class)。该方法只是ResultQuery.fetchOne() 然后Record.into(Class) 的一种方便方法。没有什么能阻止你自己打电话给Record.into(Class),无论是在阻塞世界还是在非阻塞世界。

所以,使用你常用的反应器库方法来映射流内容:

mono.map { r -> r.into(UserCredentialsModel::class.java) }

或者,在一个完整的例子中:

return Mono.from {
    dsl.select(
            USER_CREDENTIALS.ID,
            USER_CREDENTIALS.EMAIL,
            USER_CREDENTIALS.PHONE,
            USER_CREDENTIALS.LOGIN,
            USER_CREDENTIALS.PASSWORD)
        .from(USER_CREDENTIALS)
        .where(USER_CREDENTIALS.ID.eq(id))
        .and(USER_CREDENTIALS.IS_ACTIVE.eq(true))
} .map { r -> r.into(UserCredentialsModel::class.java) }

【讨论】:

    【解决方案2】:

    如果没有测试,我会说它应该是

    return Mono.from(
        dsl.select(
                USER_CREDENTIALS.ID,
                USER_CREDENTIALS.EMAIL,
                USER_CREDENTIALS.PHONE,
                USER_CREDENTIALS.LOGIN,
                USER_CREDENTIALS.PASSWORD)
            .from(USER_CREDENTIALS)
            .where(USER_CREDENTIALS.ID.eq(id))
            .and(USER_CREDENTIALS.IS_ACTIVE.eq(true)));
    

    【讨论】:

    • 如果我们想创建畅通的数据库调用,不确定是否应该使用显式block()调用
    • 哦,对不起。我以为你想返回 UserCredentialsModel
    【解决方案3】:

    你可以试试 .toMono().subscribe()

    dsl.select(
                USER_CREDENTIALS.ID,
                USER_CREDENTIALS.EMAIL,
                USER_CREDENTIALS.PHONE,
                USER_CREDENTIALS.LOGIN,
                USER_CREDENTIALS.PASSWORD)
            .from(USER_CREDENTIALS)
            .where(USER_CREDENTIALS.ID.eq(id))
            .and(USER_CREDENTIALS.IS_ACTIVE.eq(true))
            .fetchInto(UserCredentialsModel::class.java)
            .toMono().subscribe()
    

    【讨论】:

      猜你喜欢
      • 2021-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-20
      • 2021-01-01
      • 1970-01-01
      • 2016-08-24
      • 2020-08-24
      相关资源
      最近更新 更多