如何在 Jooq 中使用 unionAll 来合并两个不同记录的两个选择,但记录对应于具有相同列和类型的表

问题描述 投票:0回答:1

我有两条记录对应于两个不同的表(recordA、tableA、recordB 和 tableB)。 TableA 和TableB 具有相同的列名和相同的类型。然后我如何使用 Jooq 进行选择并将结果映射到不同的记录?

我尝试过这种方法:

fun findEntitiesByGroupId(groupId: UUID): ResultData {
    val entityAQuery = DSL.using(configuration)
        .selectFrom(ENTITY_A)
        .where(ENTITY_A.GROUP_ID.eq(groupId))
    val entityBQuery = DSL.using(configuration)
        .selectFrom(ENTITY_B)
        .where(ENTITY_B.GROUP_ID.eq(groupId))

    val entityA = mutableListOf<EventHistory>()
    val entityB = mutableListOf<EventHistory>()

    entityAQuery.unionAll(entityBQuery).forEach {
        when (it) {
            is EntityARecord -> entityA.add(mapEntityA(it))
            is EntityBRecord -> entityB.add(mapEntityB(it))
            else -> throw AssertionError("Invalid entity type")
        }
    }
    return ResultData(entityA, entityB)
}

我在

unionAll
方法中遇到编译错误:

Type mismatch.
Required:
Select<out EntityARecord!>!
Found:
SelectConditionStep<EntityBRecord!>

我没有找到任何关于此联合场景的 Jooq 文档,仅适用于我们具有相同记录类型的情况。

kotlin jooq jooq-codegen
1个回答
0
投票

jOOQ 不可能自动将源自

UNION
或类似 SQL 运算符的行映射到“正确的”映射器。我已经写了一篇关于这个主题的完整博客文章来详细说明为什么这是不可能的:

简而言之,jOOQ 无法自动知道哪条记录属于哪个

UNION ALL
子查询。因此,jOOQ 将只考虑第一个
UNION ALL
子查询的行类型(以及关联的转换器/映射器)。

但是,您可以向您的工会添加一个鉴别器列,并据此自行做出决定,例如:

SELECT a.*, 'a' AS discriminator
FROM a
UNION ALL
SELECT b.*, 'b' AS discriminator
FROM b

然后,例如:

.forEach {
    when (it["discriminator"]) {
        "a" -> entityA.add(mapEntityA(it))
        "b" -> entityB.add(mapEntityB(it))
        else -> throw AssertionError("Invalid entity type")
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.