在 jooq 中访问 sql-数组项

Accessing sql-array item by in jooq

如何像在这个 sql-查询中那样访问 JOOQ 中的数组项?

SELECT (ARRAY_AGG(id))[1]
FROM entities;

类似的东西:

dsl().select(arrayAgg(ENTITIES.ID).get(1)).from(ENTITIES).fetch();

或者只访问第一项:

dsl().select(arrayAgg(ENTITIES.ID).head()).from(ENTITIES).fetch();

我知道字符串解决方案,但不好:

field("(ARRAY_AGG(id))[1]")

从 jOOQ 3.8 开始,开箱即用是不可能的。有一个数组元素访问的未决功能请求: https://github.com/jOOQ/jOOQ/issues/229

为什么 Java 不能提供此功能

其中一个问题是 API 此处的设计。您建议的 post-fix 方法不能 return 适当的类型。考虑这个 API 设计:

interface Field<T> {
    Field<???> get(int index); // What type to return here?
}

在 Java 中,不可能在每个方法级别上对 class 的泛型类型参数 <T> 施加任何额外的约束,如下面的假设使用类似 "partial method" 的代码(即仅在 Field<T> 的某些子类型上可用的方法,即 T 是数组的方法):

interface Field<T> {
    @If(T instanceof E[])
    Field<E> get(int index);
}

解决方法

但您可以编写自己的解决方法。例如:

@SuppressWarnings("unchecked")
public static <T> Field<T> elementAt(Field<T[]> arrayField, int index) {
    return DSL.field("{0}[{1}]", 
        (Class<T>) arrayField.getType().getComponentType(),
        arrayField, DSL.inline(index)
    );
}

您现在可以这样使用它了:

dsl().select(elementAt(arrayAgg(ENTITIES.ID), 1))
     .from(ENTITIES)
     .fetch();