当前位置: 首页 > 知识库问答 >
问题:

Spring R2DBC:如何替换不推荐使用的DatabaseClient。作为(…)并处理jsonb字段的自定义类型/转换器

马弘和
2023-03-14

迁移到Spring Boot 2.4后,我遇到了对象映射问题。到目前为止,我使用的是Spring Boot 2.3(与Kotlin一起使用)。

对于示例数据库查询

    override fun findMyEntities(searchParams: SearchParams): Flux<MyEntity> =
        databaseClient
            .sql("SELECT *  FROM my_entities ........................... OFFSET :offset LIMIT :limit")
            .bind("searchPhrase", searchParams.searchPhrase)
            .bind("limit", searchParams.pageSize)
            .bind("offset", searchParams.offset)
            .map(::mapRow)
            .all()

    private fun mapRow(row: Row) = MyEntity(
        id = row.get("id", UUID::class.java)!!,
        name = row.get("name", String::class.java)!!,
        description = row.get("description", String::class.java)!!,
        creation = row.get("creation", UserActionMetadata::class.java)!!,
    )

我收到错误:

Suppressed: java.lang.IllegalArgumentException: Cannot decode value of type com.mypackage.model.UserActionMetadata
        at io.r2dbc.postgresql.codec.DefaultCodecs.decode(DefaultCodecs.java:153)
        at io.r2dbc.postgresql.PostgresqlRow.decode(PostgresqlRow.java:90)
        at io.r2dbc.postgresql.PostgresqlRow.get(PostgresqlRow.java:77)
        at com.mypackage.repository.MyRepotistory.mapRow(MyRepotistory.kt:59)

在版本升级之前,上述功能如下:

.execute("SELECT * FROM ...")
.`as`(MyEntity::class.java)
.fetch()
.all()

发生错误的地方,数据库中的创建字段是JSONB类型。为此,我有定制的读写转换器(在扩展AbstractR2dbcConfiguration的配置类中)。

import org.springframework.data.convert.ReadingConverter
import org.springframework.data.convert.WritingConverter

@Configuration
class DatabaseConfig(private val r2dbcProperties: R2dbcProperties, private val objectMapper: ObjectMapper) :
    AbstractR2dbcConfiguration() {

    @WritingConverter
    inner class UserActionMetadataToJsonConverter : Converter<UserActionMetadata, Json> {
        override fun convert(source: UserActionMetadata): Json {
            return Json.of(objectMapper.writeValueAsString(source))
        }
    }

    @ReadingConverter
    inner class JsonToUserActionMetadataConverter : Converter<Json, UserActionMetadata> {
        override fun convert(source: Json): UserActionMetadata {
            return objectMapper.readValue(source.asString())
        }
    }

知道如何成功迁移到Spring Boot 2.4吗?

我看到了Spring R2DBC DatabaseClient的建议。作为(…)使用R2dbcEntityTemplate,但我的查询太复杂,代码也会太臃肿。还有一个问题https://github.com/spring-projects/spring-framework/issues/26021 . 我希望有一些解决办法。

共有1个答案

孙经艺
2023-03-14

以下代码将数据转换为实体:

import org.springframework.r2dbc.core.DatabaseClient
import org.springframework.data.r2dbc.convert.MappingR2dbcConverter

class MyRepository(
    private val databaseClient: DatabaseClient,
    private val converter: MappingR2dbcConverter
) {
   fun fetchMyEntity() = databaseClient
       .sql("...")
       .map { row, metadata -> converter.read(MyEntity::class.java, row, metadata) }
       .all()
}
 类似资料:
  • 问题内容: 我已经继承了代码 @已弃用,并显示为“ 没有RequestConfig的类文档,我不知道应该使用哪种方法来替换and 。 问题答案: 您正在将apache HttpClient 4.3库与apache HttpClient 4.2代码一起使用。 请注意,在您的情况下,getParams()和ConnRoutePNames不是唯一不推荐使用的方法。DefaultHttpClient类本身

  • 我的错误日志中出现了以下错误:woocommerce_product_tax_class从3.0.0版开始就不推荐使用了!改用woocommerce_product_get_tax_class。 我有以下功能来显示不同的用户角色不同的税务类。我可以直接将“woocommerce_product_tax_class”更改为“woocommerce_product_get_tax_class”吗?

  • 问题内容: 我正在尝试以下查询: (+1.0仅用于强制转换浮动。我的实际查询要复杂得多,此查询只是问题的测试用例。) 我得到了错误: 如果我添加显式强制转换: 错误变为: 我知道大多数jsonb值不能转换为浮点数,但是在这种情况下,我知道纬度都是JSON编号。 是否有一个将jsonb值强制转换为浮点数(或为不可广播的返回NULL)的函数? 问题答案: 要从中获得价值,有两种操作。第一个将返回。第二

  • 我有一个类型 现在我想做这样的事情。 如何将我的 转换为基元类型? 它给我的错误是: 将“Rating”类型转换为“number”类型可能是错误的,因为这两种类型都没有充分重叠。如果这是有意的,首先将表达式转换为“未知” 我已经经历过了,但我想要的是它的反面 编辑: tsconfig.json tsc版本:3.2.1

  • 问题内容: 我的Java代码中有一些不推荐使用的方法,如果有人可以在这里指导我,我将不胜感激。我有一个私有的Date变量: 在我的方法中,我声明了: 其他方法(例如和)也已弃用。 我知道我必须使用。如何在这里使用新代码?所有的setHours,getMinutes等都用上划线显示。 问题答案: 如果我正确理解了您的问题,这应该可以: 如果没有,您可以向我们显示要替换日期代码的完整方法吗? 编辑:这

  • 问题内容: 我发现这段代码的工作方式是,我可以以编程方式创建richfaces下拉菜单。但是不推荐使用某些代码。谁能告诉我要放什么而不是不赞成使用的电话? 谢谢 不推荐使用的代码行是: 问题答案: javadocs明确指出: 不推荐使用 。通过调用getExpressionFactory()然后 ExpressionFactory.createMethodExpression(javax.el.E