jOOQ JSON 格式化为对象数组

Posted

技术标签:

【中文标题】jOOQ JSON 格式化为对象数组【英文标题】:jOOQ JSON formatting as array of objects 【发布时间】:2021-02-28 11:03:05 【问题描述】:

我有以下(简化的)jOOQ 查询:

val result = context.select(
  jsonObject(
    key("id").value(ITEM.ID),
    key("title").value(ITEM.NAAM),
    key("resources").value(
      jsonArrayAgg(ITEM_INHOUD.RESOURCE_ID).absentOnNull()
    )
  )
).from(ITEM).fetch()

现在我想要的输出是:

[
    
        "id": "0da04cc5-f70c-4fb3-b5c7-dc645d342631",
        "title": "Title1",
        "resources": [
            "8b0f6d5c-67fc-47ca-be77-d1735e7721ce",
            "ea0316db-1cfd-46d7-8260-5c1a4e65a0cd"
        ]
    ,
    
        "id": "0f7e67e6-5187-47e2-9f1d-dab08feba38b",
        "title": "Title2"
    
]

result.formtJSON() 给出以下输出:


    "fields": [
        
            "name": "json_object",
            "type": "JSON"
        
    ],
    "records": [
        [
            
                "id": "0da04cc5-f70c-4fb3-b5c7-dc645d342631",
                "title": "Title 1"
            
        ]
    ]

result.formatJSON(JSONFormat.DEFAULT_FOR_RECORDS) 禁用标头会得到我:

[
    [
        
            "id": "0da04cc5-f70c-4fb3-b5c7-dc645d342631",
            "title": "Title1",
            "resources": [
                "8b0f6d5c-67fc-47ca-be77-d1735e7721ce",
                "ea0316db-1cfd-46d7-8260-5c1a4e65a0cd"
            ]
        
    ],
    [
        
            "id": "0f7e67e6-5187-47e2-9f1d-dab08feba38b",
            "title": "Title2"
        
    ]
]

我不想要额外的数组。

使用result.formatJSON(JSONFormat().header(false).recordFormat(JSONFormat.RecordFormat.OBJECT)) 进一步自定义 JSONformatter 我得到:

[
    
        "json_object": 
            "id": "0da04cc5-f70c-4fb3-b5c7-dc645d342631",
            "title": "Title1",
            "resources": [
                "8b0f6d5c-67fc-47ca-be77-d1735e7721ce",
                "ea0316db-1cfd-46d7-8260-5c1a4e65a0cd"
            ]
        
    ,
    
        "json_object": 
            "id": "0f7e67e6-5187-47e2-9f1d-dab08feba38b",
            "title": "Title2"
        
    
]

我不想将对象包裹在 json_object 中。

有没有办法得到我想要的输出?

【问题讨论】:

【参考方案1】:

使用Result.formatJSON()

这显然是Result.formatJSON() 的 jOOQ 3.14.0 实现中的一个缺陷。在只有一列的特殊情况下,并且该列的类型为JSONJSONB,列名可能并不重要,因此其内容应该被展平为描述该行的对象。我为此创建了一个功能请求:https://github.com/jOOQ/jOOQ/issues/10953。它将在 jOOQ 3.15.0 和 3.14.4 中可用。您将能够做到这一点:

result.formatJSON(JSONFormat().header(false).wrapSingleColumnRecords(false));

RecordFormat 在这里无关紧要。这对RecordFormat.ARRAYRecordFormat.OBJECT 的工作方式相同

直接用 SQL 来做

当然,您始终可以通过将所有逻辑移至 SQL 来解决此问题。您可能通过省略JOINGROUP BY 来简化查询。我假设这与您想要的相同:

JSON result = context.select(
  jsonArrayAgg(jsonObject(
    key("id").value(ITEM.ID),
    key("title").value(ITEM.NAAM),
    key("resources").value(
      select(jsonArrayAgg(ITEM_INHOUD.RESOURCE_ID).absentOnNull())
      .from(ITEM_INHOUD)
      .where(ITEM_INHOUD.ITEM_ID.eq(ITEM.ID))
    )
  ))
).from(ITEM).fetchSingle().value1()

请注意,JSON_ARRAYAGG() 将空集聚合到 NULL,而不是空集 []。 If that's a problem, use COALESCE()

【讨论】:

以上是关于jOOQ JSON 格式化为对象数组的主要内容,如果未能解决你的问题,请参考以下文章

JSON 对象未正确格式化为 Javascript

无法将 JSON 数组反序列化为 C# 对象 [关闭]

使用 JSON.NET 一次序列化一组对象

将对象数组重新格式化为键数组

built_value 如何将 json 数组反序列化为对象数组?

如何将对象的json数组反序列化为字典[重复]