如何解决Spring R2DBC:如何替换已弃用的 DatabaseClient.as(...) 并处理 jsonb 字段的自定义类型/转换器
迁移到 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",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.as(…) 使用 R2dbcEntityTemplate,但我的查询太复杂,代码会太臃肿。还有一个问题 https://github.com/spring-projects/spring-framework/issues/26021 。我希望有一些解决方法。
解决方法
以下代码将数据转换为实体:
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()
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。