如何在 jOOQ 中使用 formatJSON(JSONFormat) 正确格式化生成的 JSON 类型的常规结果?

Posted

技术标签:

【中文标题】如何在 jOOQ 中使用 formatJSON(JSONFormat) 正确格式化生成的 JSON 类型的常规结果?【英文标题】:How to properly format generated routine result of JSON type by using formatJSON(JSONFormat) in jOOQ? 【发布时间】:2020-10-25 14:29:14 【问题描述】:

在使用 jOOQ 代码生成器查询生成的例程时,我遇到了正确格式化 JSON 结果的问题。我正在尝试对 PL/pgSQL 中定义的 get_all_orders() 方法执行 SELECT 子句(在 this 问题中提到),它返回 json 类型的结果。这是我执行 jOOQ 查询的代码:

DSLContext create = DSL.using(connection, SQLDialect.POSTGRES);
Result<Record1<String>> resultR1S = create.select(Routines.getAllOrders()).fetch();
final String strResultFinal = resultR1S.formatJSON(
    new JSONFormat().header(false).recordFormat(RecordFormat.ARRAY)
);

...这是我在控制台上得到的输出(最后被截断,因为结果输出太长而无法放入):

[["\"orders\" : [\"order_id\" : 1, \"total_price\" : 29.98, \"order_date\" : \"2019-08-22T10:06:33\", \"user\" : \"user_id\" : 1, \"username\" : \"test\", \"order_items\" : [\"order_item_id\" : 1, \"amount\" : 1, \"book\" : \"book_id\" : 1, \"title\" : \"Harry Potter and the Philosopher's Stone\", \"price\" : 29.98, \"amount\" : 400, \"is_deleted\" : false, \"authors\" : [\"author_id\":4,\"first_name\":\"JK\",\"last_name\":\"Rowling\"], \"categories\" : [\"category_id\":2,\"name\":\"Lyric\",\"is_deleted\":false], \"order_id\" : 1, \"total_order_item_price\" : 29.98], ..."]]

我想要实现的是去掉 双尖括号(在输出的开头和结尾)反斜杠字符,所以它看起来像这样:

"orders" : ["order_id" : 1, "total_price" : 29.98, "order_date" : "2019-08-22T10:06:33", "user\" : "user_id" : 1, "username\" : "test", ...]

我似乎无法找到解决此问题的方法,所以有什么适当的方法可以通过使用 formatJSON(JSONFormat) 方法...或其他方法来实现吗? 非常感谢任何帮助/建议。

【问题讨论】:

【参考方案1】:

缺少一个允许将JSON/JSONB 列与Result.formatJSON()(或XML 列与Result.formatXML())结合使用的功能:https://github.com/jOOQ/jOOQ/issues/10361

作为一种解决方法,您必须自己手动完成这项工作,并避免使用formatJSON() 方法。

【讨论】:

您好 Lukas,感谢您的快速回复。是否有任何其他库可以推荐用于执行这种 JSON 格式(删除不必要的尖括号和反斜杠)?提前谢谢你。 @NikolaS:我不会修复错误的输出。我会从一开始就确保输出是正确的。 我同意,但是jOOQ中有没有合适的方法来实现这样的事情?现在我正在尝试使用 String 类方法,例如 replaceAll()substring() 来修复混乱的输出作为临时解决方案(因为我似乎找不到其他更好的方法)。 我已经为我的用例发布了(临时)解决方案作为我问题的答案。如果您有什么要补充/更正的,请告诉我。欢迎任何意见/建议。 :) @NikolaS:正如我所说。我不会修复错误的输出。绝不。不是 jOOQ,不是其他任何东西。格式化的数据是丢失的数据。最好编写一些正确格式化原始数据的自定义逻辑。至少,这是我的看法。【参考方案2】:

在对合适的 JSON 库进行一些研究以实现我想要的结果后,我决定这样做(直到 jOOQ 3.13.1 中提供更方便的方法):

String strResultFinal = resultR1S.formatJSON(
        new JSONFormat()
        .header(false)
        .recordFormat(RecordFormat.ARRAY)
);
final String fixedJSONString = strResultFinal
        .substring(3, strResultFinal.length() - 3)
        .replaceAll("\\\\n", "") // for some reason '\n' is being part of String (I presume for new row) and needs to be removed for proper JSON format... 
        .replaceAll("\\\\", ""); //...as well as escaping backslash character

现在我得到了这样的所需 JSON 格式(顺便说一句,它被修剪了 :)):

"orders" : ["order_id" : 1, "total_price" : 29.98, "order_date" : "2019-08-22T10:06:33", "user" : "user_id" : 1, "username" : "test", ..]

【讨论】:

以上是关于如何在 jOOQ 中使用 formatJSON(JSONFormat) 正确格式化生成的 JSON 类型的常规结果?的主要内容,如果未能解决你的问题,请参考以下文章

JOOQ 插入到具有大量记录的选择中

如何在 JOOQ 中使用 toChar 函数?

jooq 记录在获取数据时是不是使用列索引?

如何在 jOOQ 中使用 Scala 的字符串插值?

如何使用 jOOQ 执行特定查询

如何在带有jooq的普通sql中使用命名参数