You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Spring Data R2DBC中正确映射PostgreSQL数组类型到Kotlin List<>

如何在Spring Data R2DBC中正确映射PostgreSQL数组类型到Kotlin List<>

我完全懂你现在的困扰——静态赋值根本解决不了问题,用ARRAY_TO_STRING又感觉像个临时凑出来的小技巧,还多了不必要的开销。其实Spring Data R2DBC本身就支持PostgreSQL的数组类型映射,咱们直接用原生的方式来搞定,一步到位:

核心思路:用Row的getArray方法读取数组

PostgreSQL的数组类型在R2DBC里是可以直接通过Row对象的getArray方法读取的,咱们只需要把读取到的数组转换成Kotlin的List就行,不需要绕弯子。

1. 映射UUID数组(uuid[])到List<UUID>

对于你查询里的type_ids字段(uuid[]类型),直接用row.getArray指定类型为UUID::class.java,然后转成List即可,同时处理数据库返回空数组{}的情况:

val typeIds = row.getArray("typeIds", UUID::class.java)?.toList() ?: emptyList()

2. 映射字符串数组(varchar[])到List<TimeTypesEnum>

对于time_types字段(varchar[]类型),先读取成String数组,再遍历每个元素用你枚举里的from方法转换,同样处理空数组:

val timeTypes = row.getArray("timeTypes", String::class.java)
    ?.map { TimeTypesEnum.from(it) }
    ?: emptyList()

完整的映射代码示例

把这些逻辑放到你原来的map块里,替换掉静态赋值的部分,整个findSmth方法就变成这样:

fun findSmth(): Flux<IncomesDto> {
    val sql: String = """
        -- 你的CTE和查询语句保持不变
        SELECT
            -- 其他字段
            type_ids AS "typeIds",
            time_types AS "timeTypes",
            -- 其他字段
        FROM ${this.tableName}
    """.trimIndent()

    return this.databaseClient.sql(sql).map { row, _ ->
        val typeIds = row.getArray("typeIds", UUID::class.java)?.toList() ?: emptyList()
        val timeTypes = row.getArray("timeTypes", String::class.java)
            ?.map { TimeTypesEnum.from(it) }
            ?: emptyList()

        IncomesDto(
            // 其他字段映射
            typeIds = typeIds,
            timeTypes = timeTypes,
            // 其他字段映射
        )
    }.all()
}

为什么之前会报“Dimensions mismatch”错误?

你之前尝试把数组当成字符串读取时,R2DBC的底层驱动已经识别出这个字段是数组类型,而不是普通字符串,强行按字符串读取就会触发维度不匹配的异常——因为数据库返回的是一维数组,而你试图把它当成0维度的字符串来处理,自然就报错了。

额外注意事项

  • 确保你用的是最新版本的r2dbc-postgresql驱动,旧版本对数组类型的支持可能不够完善;
  • 你的枚举from方法已经处理了大小写忽略,所以直接用map转换就没问题,不需要额外处理字符串格式。

这样处理既符合Spring Data R2DBC的设计,又没有额外的SQL转换开销,完全是原生的正确映射方式。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 11:04:30