首页 > 解决方案 > R2DBC:如何在不需要所有参数的情况下为 sql 查询绑定数据类?

问题描述

我正在尝试为 sql 查询绑定我的数据类,但是当我没有使用数据类中的所有参数时出现错误。有没有办法在 sql 查询中检查哪些参数需要绑定,哪些不需要或允许绑定不使用的参数。错误如下所示:

Request error
 java.lang.IllegalArgumentException: Identifier 'deleted_at' is not a valid identifier. Should be of the pattern '\$([\d]+)'.
    at io.r2dbc.postgresql.ExtendedQueryPostgresqlStatement.getIndex(ExtendedQueryPostgresqlStatement.java:196)
Caused by: java.lang.IllegalArgumentException: Identifier 'deleted_at' is not a valid identifier. Should be of the pattern '\$([\d]+)'.
    at io.r2dbc.postgresql.ExtendedQueryPostgresqlStatement.getIndex(ExtendedQueryPostgresqlStatement.java:196)

这是我使用的代码:存储库:

      client
            .sql(
                """
                INSERT INTO app_user_settings (uuid, allows_to_process_transactions, app_user_id) VALUES (:uuid, :allows_to_process_transactions, :app_user_id)
                RETURNING *
                """.trimIndent()
            )
            .bind(AppUserSettingsWriteConverter(), appUserSettings)
            .map(AppUserSettingsReadConverter()::convert)
            .awaitOne()

自定义绑定方法:

fun <T> DatabaseClient.GenericExecuteSpec.bind(
    convertor: Converter<T, OutboundRow>,
    value: T
): DatabaseClient.GenericExecuteSpec {
    val outboundRow = convertor.convert(value!!)!!
    val t = outboundRow.toMap()
    var execution = this
    t.forEach { (t, u) ->
        execution = execution.bind(t.toString(), u)
    }
    return execution
}

写转换器:

class AppUserSettingsWriteConverter : Converter<AppUserSettings, OutboundRow> {
    override fun convert(source: AppUserSettings): OutboundRow {
        val outboundRow = OutboundRow()

        if (source.isSaved()) {
            outboundRow[SqlIdentifier.unquoted("id")] = Parameter.from(source.id)
        }
        outboundRow[SqlIdentifier.unquoted("uuid")] = Parameter.from(source.uuid)
        outboundRow[SqlIdentifier.unquoted("allows_to_process_transactions")] = Parameter.from(source.allowsToProcessTransactions)
        outboundRow[SqlIdentifier.unquoted("app_user_id")] = Parameter.from(source.appUserId)
        outboundRow[SqlIdentifier.unquoted("deleted_at")] = Parameter.fromOrEmpty(source.deletedAt, ZonedDateTime::class.java)

        return outboundRow
    }
}

我现在正在使用检查 deleted_at 是否为空,然后不绑定它,但如果有其他方法可以做到这一点,我会更喜欢。

标签: kotlinspring-data-r2dbcr2dbc-postgresql

解决方案


推荐阅读