使用 jooq/postgresql - java 从 json 中提取 key/value 对

Extracting key/value pairs from json using jooq/postgresql - java

我在 PostgreSQL 数据库列中有 json 数据,格式如下:

myData [{"key1": "value1", "key2": "value2"}, {"key1": "value1", "key2": "value2"} ]

其中 myData 是一个包含两个对象的数组。 我阅读了以下链接,仅使用 java 解决了我的问题,但我的问题略有不同。 Converting JSON to JavaParsing JSON Object in Java

  1. 在数据库(postgresql)中提取 key/value 对会更有效,还是我应该在 java 中获取整个字符串并使用 java 库?甚至可以在数据库中进行吗?

  2. 如果可以选择在数据库中执行此操作,JOOQ 是否对此提供任何支持?

  3. 如果在Java中解析是更好的选择,那么上面链接给出的两个库中哪个更stable/efficient? org.json 或 Gson

你有几个有趣的问题。

1。数据库中的查询逻辑与 Java

中的查询逻辑

取决于。首先,在 PostgreSQL 中,jsonb 有更好的索引支持。我不是该主题的专家,但我很确定一旦您对 1-2 件事进行基准测试,您就会得出这个结论。这是一个有趣的博客 post 比较不同数据类型在 Postgre 中的性能 SQL:

http://www.databasesoup.com/2015/01/tag-all-things.html

... 这让我想到了是将谓词放入您的 SQL 查询中,还是稍后在 Java 中执行它们。总的来说:把它放在数据库中。如果你的谓词非常有选择性,那么你可以:

  1. 避免很多不必要的I/O数据库
  2. 用数据库
  3. 避免了很多不必要的I/O

两者都会大大降低您的查询延迟。如果您的谓词不是很有选择性,那么这几乎不会成为问题,除非在极端负载下。但是,如果您的系统处于极端负载下并且您的谓词 是选择性的,那么如果您 运行 数据库中的谓词,您仍然会大大减少负载。

2。 jOOQ 支持 JSON 谓词

jOOQ 目前不为 JSON(B) 谓词提供任何开箱即用的支持,但您可以使用 jOOQ 的普通 SQL 支持轻松地自己构建一个实用程序:

http://www.jooq.org/doc/latest/manual/sql-building/plain-sql

本质上就是这样写:

public static Condition someJsonPredicate(Field<?> someJsonColumn, String someValue) {
    return DSL.condition("some_json_predicate({0}, {1})", 
        someJsonColumn, DSL.val(someValue));
}

3。 org.json 对比 Gson

我不会在这里回答这部分,因为您的基准可能与我的不同。

从 Java 中的 PostgreSQL 数据库获取 JSON 数据的解决方案。

  • this article 摘要。
  • 我发现这个答案的最后一部分非常强大且易于阅读。很容易用方法包装它
  • 代码是为了提供视觉提示,而不是完整的示例。
  • 这个答案不用jooq。

PostgreSQL JSON(存储为文本)和 JSONB(存储为二进制)的比较

JSON JSONB
Stores data in text format Stores data in decomposed binary format
Input is fast, as no conversion are required Input is slightly slower, as there is an overhead related to binary conversion
Processing functions must re-parse the data on each execution Re-parsing is not needed, making data processing significantly faster
All white space and line feeds in the input are preserved as-is Extra white space and line feeds are stripped
Indexing is not supported Indexing is supported
Duplicate keys are retained, processing functions only consider the last value Duplicate keys are purged at input, only the last value is stored
Order of the keys is preserved Order is not preserved

Database structure

my_table
   id = PK
   json_column = JSON or BYTEA

json_column

的数据示例
    {"customer_name": "John", "items": { "description": "milk", "quantity": 4 } }
    {"customer_name": "Susan", "items": { "description": "bread", "quantity": 2 } }

JAVA parsing json (bof bof...)

String sql = "select json_column from my_table";
Statement stmt = conn.createStatement(...);
ResultSet rs = stmt.executeQuery(sql);
 
while(rs.next()) {
   // Not really true as data are store in binary, not nice to parse it in string here...
   JSONObject json = new JSONObject(rs.getString(1));
   JSONObject json2 = (JSONObject)json.get("items");
   System.out.println(json.get("customer_name"));
   System.out.println(json2.get("quantity"));
}

PostgreSQL (LOVE THIS PART!)

select json_column->'customer_name' from my_table
select json_column->'items'->'quantity' from my_table

Both (really nice solution)

sql = "select json_column->'items'->'quantity' from my_table";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while(rs.next()) {
   rs.getInt(1);
   ...
}