使用 jooq/postgresql 从 json 中提取键/值对 - java
Posted
技术标签:
【中文标题】使用 jooq/postgresql 从 json 中提取键/值对 - java【英文标题】:Extracting key/value pairs from json using jooq/postgresql - java 【发布时间】:2017-02-04 00:04:51 【问题描述】:我在 PostgreSQL 数据库列中有以下格式的 json 数据:
myData ["key1": "value1", "key2": "value2", "key1": "value1", "key2": "value2" ]
其中myData
是一个包含两个对象的数组。
我阅读了以下链接以仅使用 java 解决我的问题,但我的问题略有不同。
Converting JSON to Java 和
Parsing JSON Object in Java
在数据库 (postgresql) 中提取键/值对会更有效,还是应该在 java 中获取整个字符串并使用 java 库?甚至可以在数据库中进行吗?
如果可以在数据库中执行此操作,JOOQ 是否对此提供任何支持?
如果在 Java 中解析是更好的选择,以上链接中给出的两个库中哪个更稳定/更高效? org.json 或 Gson
【问题讨论】:
对于 (1),我怀疑如果你在 postgres 中使用jsonb
列会更快。
here 你有一个很好的 Java 和 PostgreSQL 实现示例。我喜欢这种选择select jsonColumn->'key1'->'subKey1' from myTable
【参考方案1】:
您有几个有趣的问题。
1。数据库中的查询逻辑与 Java 中的查询逻辑
它取决于。首先,在 PostgreSQL 中,jsonb
有更好的索引支持。我不是该主题的专家,但我敢肯定,一旦您对 1-2 个事物进行基准测试,您就会得出这个结论。这是一篇有趣的博文,比较了 PostgreSQL 中不同数据类型的性能:
http://www.databasesoup.com/2015/01/tag-all-things.html
... 这让我想到是将谓词放入 SQL 查询中,还是稍后在 Java 中执行它们。一般来说:把它放在数据库中。如果您的谓词非常有选择性,那么您可以:
-
避免大量不必要的 I/O 在数据库中
使用数据库避免大量不必要的 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 vs Gson
我不会在这里回答这部分,因为您的基准可能与我的不同。
【讨论】:
【参考方案2】:从 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 |
数据库结构
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解析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(喜欢这部分!)
select json_column->'customer_name' from my_table
select json_column->'items'->'quantity' from my_table
两者(非常好的解决方案)
sql = "select json_column->'items'->'quantity' from my_table";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while(rs.next())
rs.getInt(1);
...
【讨论】:
以上是关于使用 jooq/postgresql 从 json 中提取键/值对 - java的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 SwiftyJSON 从 JSON 对象中获取 JSON 密钥?
使用 Cloudant 从 JSON 数组中检索 JSON 对象