【问题标题】:Accessing sql-array item by in jooq在 jooq 中访问 sql-array 项
【发布时间】:2017-01-16 08:13:43
【问题描述】:

如何像在这个 sql-query 中一样访问 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]")

【问题讨论】:

    标签: java sql arrays jooq


    【解决方案1】:

    从 jOOQ 3.8 开始,这是不可能的。数组元素访问有一个待处理的功能请求: https://github.com/jOOQ/jOOQ/issues/229

    为什么 Java 不能提供这个功能

    其中一个问题是这里的 API 设计。您建议的后修复方法无法返回适当的类型。考虑一下这个 API 设计:

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

    在 Java 中,不可能在每个方法级别上对类的泛型类型参数 &lt;T&gt; 施加任何额外的约束,如下面的假设代码中使用类似“部分方法”(即仅适用于Field&lt;T&gt; 的某些子类型,即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();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-09
      • 2021-11-24
      • 1970-01-01
      • 2014-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-09
      相关资源
      最近更新 更多