将 R2DBC 查询结果映射到具有数组 postgresql 类型的列的行

堆栈:Kotlin 2.1.21,Spring Boot 3.5.3,Spring Data R2DBC 3.5.1

我得到了以下代码

kotlin 复制代码
enum class TimeTypesEnum {
  FULL, PARTIAL;

  companion object {
    fun from(value: String): TimeTypesEnum =
      TimeTypesEnum.entries.firstOrNull { it.name.equals(value, ignoreCase = true) }
        ?: throw IllegalArgumentException("Invalid TimeType: $value")
  }
}
kotlin 复制代码
data class IncomesDto(
  // some unimportant types
  val typeIds: List<UUID>,
  val timeTypes: List<TimeTypesEnum>,
  // some unimportant types
)
ini 复制代码
@Repository
class IncomesRepository(private val databaseClient: DatabaseClient) {
  private val tableName: String = "table_name";

  fun findSmth(): Flux<IncomesDto> {
    val sql: String = """
      -- bunch of CTE's here
      SELECT
        -- unimportant fields
        -- it returns uuid[] not null, can be an empty array , so '{}'
        type_ids AS "typeIds",
        -- it returns varchar[] not null, can be an empty array , so '{}', values are only those from Kotlin emun and no other
        time_types AS "timeTypes",
        -- unimportant fields
      FROM
        ${this.tableName}
    """;

    return this.databaseClient.sql(sql).map { row, _ ->
      IncomesDto(
        -- unimportant mapping here
        apartmentTypeId = listOf<UUID>(),
        paymentTypes = listOf<TimeTypesEnum>(),
        -- unimportant mapping here
      )
    }.all();
  }
}

www.mytiesarongs.com 正如您所看到的,没有动态映射,只有静态分配,因为我无法使其工作。

于是我检查了 SQL,它完全符合我的要求。我检查了问题字段的不同值,它们确实有效,没有空值,只有 SQL 数组,只有有效值。

但我无法将它们映射到数据类。

在文档(API 参考、API 规范、JavaDoc、R2DBC 文档、Spring 文档)中找不到如何正确映射数组类型的说明。因此,当我尝试像处理数组一样处理数组时,我的代码无法编译,因为存在我无法解决的类型不匹配问题。当我尝试像处理字符串一样处理 PostgreSQL 数组时(最终的"{FULL}"在 PostgreSQL 中只是一个奇怪的字符串),我需要修剪字符串,遍历字符 4 次以删除"{"、"}",并使用 .from() 将按","拆分的值映射到枚举,但尝试时我收到了错误:

ini 复制代码
2025-06-24T10:58:50.272+05:00 ERROR 34727 --- [kt] [nio-8080-exec-3] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: java.lang.IllegalArgumentException: Dimensions mismatch: 0 expected, but 1 returned from DB] with root cause

这完全是有道理的,我做错了。

唯一可行的方法是在 SQL 中使用 ARRAY_TO_STRING(column, ','),然后在 Kotlin 中使用 .split(',').map(.from()),但它非常不自然,看起来像一个拐杖 + 它的开销。

将 PostgreSQL 数组类型映射到 Kotlin List<> 类型的最佳和正确方法是什么?

PS 不,我无法将其移动到 EntityRepository 并将数据类描述为实体,它不是域对象并且不属于任何表。

PSS 不要建议我使用 Jakarta 和/或 JPA 以及任何具有延迟加载/预加载等功能的东西。也不要使用 queryBuilders,我需要知道如何让它与 .map { } 一起工作,因为这是任务。

相关推荐
在西安放羊的牛油果2 天前
Connect 源码深度解析
前端·架构·代码规范
Freak嵌入式2 天前
小作坊 GitHub 协作闭环:fork-sync-dev-pr-merge 实战指南
python·github·远程工作·代码规范·micropython·协作
高志小鹏鹏3 天前
告别“修复 bug”:让别人一眼看懂你的 Commit
git·github·代码规范
来自远方的老作者4 天前
第7章 运算符-7.5 比较运算符
开发语言·数据结构·python·算法·代码规范·比较运算符
Patrick_Wilson4 天前
你的 MR 超过 500 行了吗?——大型代码合并请求拆分实战指南
前端·代码规范·前端工程化
Gale2World4 天前
【进阶范式】多智能体协同:Superpowers 与子代理驱动开发
人工智能·代码规范
数据学徒工8 天前
17-Decisions Report:计算列+筛选器全攻略
低代码·自动化·代码规范·敏捷流程·报告
梦梦代码精8 天前
智能体编排 + MCP + 知识库,开源可商用!
人工智能·神经网络·gitee·开源·github·代码规范
我是若尘10 天前
我的需求代码被主干 revert 了,接下来我该怎么操作?
前端·后端·代码规范
方安乐11 天前
ESLint代码规范(二)
前端·javascript·代码规范