如何使用 JOOQ 和 PostgreSQL return JSON 对象数组而不是行集合

How to return an array of JSON objects rather the a collection of rows using JOOQ & PostgreSQL

阅读了 this post 的建议,有时使用 JSON 运算符直接从数据库 return JSON 是一个很好的权衡;我正在使用 PostgreSQL 和 JOOQ 探索这个想法。

我可以使用以下模式编写 SQL 查询 returning JSON 对象数组而不是行:

select jsonb_pretty(array_to_json(array_agg(row_to_json(r)))::jsonb)
from (
  select [subquery]
) as r;

然而,我未能在 JOOQ 中翻译此模式。

如能提供有关如何使用 JOOQ 翻译行集合(字段为“常规”SQL 类型或已映射为 json(b))的任何帮助,我们将不胜感激。

SQL 服务器 FOR JSON 语义

这正是 SQL 服务器 FOR JSON 子句所做的,jOOQ 支持它,它也可以在其他方言上为您效仿:

ctx.select(T.A, T.B)
   .from(T)
   .forJSON().path()
   .fetch();

PostgreSQL 原生功能

如果您更喜欢直接使用本机函数,您现在必须使用 plain SQL templating,因为 jOOQ 尚不支持其中一些函数,包括:

编写一个专门执行此操作的实用程序似乎非常简单:

public static ResultQuery<Record1<JSONB>> json(Select<?> subquery) {
    return ctx
        .select(field(
            "jsonb_pretty(array_to_json(array_agg(row_to_json(r)))::jsonb)", 
            JSONB.class
         ))
        .from(subquery.asTable("r"))
}

现在,您可以以所需的形式执行任何查询:

JSONB result = ctx.fetchValue(json(select(T.A, T.B).from(T)));

PG 数组和 JSON 数组之间的转换

性能说明。您似乎经常在数据类型之间进行转换。具体来说,我建议您避免聚合 PostgreSQL 数组并将其转换为 JSON 数组,而是直接使用 JSONB_AGG()。我没有测试过这个,但在我看来额外的数据结构似乎是不必要的。