经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » JSON » 查看文章
PostgreSQL 务实应用(四/5)JSON
来源:cnblogs  作者:三人行工作室  时间:2019/5/17 8:43:23  对本文有异议

JSON 可谓风靡互联网,在数据交换使用上,其优势特别明显,其结构简洁、可读易读、形式灵活。很多 API 接口的数据都采用 JSON 来表示。

PostgreSQL 对 JSON 提供了良好的支持。具体的相关函数可参考:JSON类型和函数

从使用的角度而言,个人觉得常见的应用场景为:

  1. 读取单个 JSON 的属性值
  2. 遍历单个 JSON 的所有属性
  3. 遍历一个 JSON 数组
  4. 创建一个 JSON 作为返回值

之所以仅这些简单的场景,原因在于,在应用中使用高级语言处理 JSON 与在数据库中使用那些高级的 JSON 函数相比,从操作上和可读性上均爽很多。在不支持 JSON 的数据库中,我们也常使用单个文本字段存储 JSON 字符串,然后在应用中加以解析处理。

四个场景

我们以以下的 JSON 字符串作为输入,来了解 PostgreSQL 在各场景中的应用实现。

  1. {
  2. "label": {
  3. "names": ["Amy", "Kala", "Lily"]
  4. },
  5. "color": "red",
  6. "count": 3
  7. }
  8. // 写成一行即是
  9. {"label":{"names":["Amy","Kala","Lily"]},"color":"red","count":3}

1.读取属性

首先,通过下面的表格,感受一下 JavaScript 与?PostgreSQL 中读取 color 属性与 label 属性中 names 的第二个值的形式。

读属性 JavaScript PostgreSQL
定义 var jsonObj =?{"label":{"names":["Amy","Kala","Lily"]}, "color":"red","count":3}; jsonObj := '{"label":{"names":["Amy","Kala","Lily"]}, "color":"red","count":3}'::json;
读取 JSON 的 color 属性 jsonObj.color jsonObj -> 'color'
读取 JSON 的 label 中 names 的第二个值 jsonObj.label.names[1] jsonObj -> 'label' -> 'names' -> 1

在 PostgreSQL 中我们可以使用以下语句逐层指定属性路径(属性名称需要使用字符串需单引号,数组索引使用数字)来获取值:

  1. -- 取得 color 属性
  2. SELECT '{"label":{"names":["Amy","Kala","Lily"]},"color":"red","count":3}'::json
  3. -> 'color';
  4. -- 取得 label 属性下的 names 的第二个值
  5. SELECT '{"label":{"names":["Amy","Kala","Lily"]},"color":"red","count":3}'::json
  6. -> 'label' -> 'names' -> 1;

?此时取得的值仍然为 json 类型,如果需要取得值的文本形式,则把最后一个 "->" 变成 "->>" 即可。

当然,路径的表示,也可以通过 #> '{label,names,1}' 的形式表示:

  1. SELECT '{"label":{"names":["Amy","Kala","Lily"]},"color":"red","count":3}'::json
  2. #> '{label,names,1}';

?2.遍历属性

使用 json_each 函数,即可返回属性键值对的数据集,数据集包括两列,key 表示属性,value 表示属性值。如下语句输出所有结果:

  1. DO $$
  2. DECLARE
  3. lv_row record;
  4. jsonObj json := '{"label":{"names":["Amy","Kala","Lily"]},"color":"red","count":3}'::json;
  5. BEGIN
  6. FOR lv_row IN SELECT * FROM json_each(jsonObj) LOOP
  7. raise notice 'key is %, value is %', lv_row.key, lv_row.value;
  8. END LOOP;
  9. END $$;

输出

NOTICE: key is label, value is {"names":["Amy","Kala","Lily"]}

NOTICE: key is color, value is "red"

NOTICE: key is count, value is 3

3.遍历数组

通过使用?json_array_length 函数获取数组的长度,然后根据索引遍历整个数组即可。

  1. DO $$
  2. DECLARE
  3. lv_row record;
  4. lv_size int;
  5. jsonObj json := '{"label":{"names":["Amy","Kala","Lily"]},"color":"red","count":3}'::json;
  6. BEGIN
  7. -- 取得label names 这个json数组
  8. jsonObj := jsonObj #> '{label,names}';
  9. -- 取得数组的长度
  10. lv_size := json_array_length(jsonObj);
  11. -- 按索引遍历整个数组
  12. FOR i IN 0..lv_size-1 LOOP
  13. raise notice '%', jsonObj -> i;
  14. END LOOP;
  15. END $$;

输出:

NOTICE: "Amy"

NOTICE: "Kala"

NOTICE: "Lily"?

4.创建一个 JSON

使用 json_build_object 函数,传递? key, value 成对的参数即可创建一个 json,如以下语句形成一个 api 常用的返回执行情况的 json。?

  1. SELECT json_build_object('code', 200, 'err_msg', 'run success!');

应用示例

我们以填写学生地址为例,传递给存储过程的是一个 json 数组,每个数组中的 json 对象包括了学生标识与地址信息。

以下语句创建数据表

  1. -- student_id 学生标识, address 地址
  2. CREATE TABLE student_address (student_id varchar(10) PRIMARY KEY, address varchar(100));

image.gif

以下为处理过程

  1. CREATE OR REPLACE FUNCTION save_student_addresses_json(
  2. v_array_json json)
  3. RETURNS json
  4. LANGUAGE 'plpgsql'
  5. AS $$
  6. DECLARE
  7. lv_row_json json;
  8. lv_length int;
  9. lv_field_student_id varchar;
  10. lv_field_address varchar;
  11. BEGIN
  12. -- 取得数组的长度
  13. lv_length := json_array_length(v_array_json);
  14. FOR i IN 0..lv_length-1 LOOP
  15. -- 取得第 i 行的 json
  16. lv_row_json := v_array_json -> i;
  17. lv_field_student_id := lv_row_json ->> 'student_id';
  18. lv_field_address := lv_row_json ->> 'address';
  19. -- 插入学生地址信息,如果存在则更新地址
  20. INSERT INTO student_address (student_id, address)
  21. VALUES (lv_field_student_id, lv_field_address)
  22. ON CONFLICT (student_id)
  23. DO UPDATE SET address = excluded.address;
  24. END LOOP;
  25. RETURN json_build_object(
  26. 'err_code', 200,
  27. 'err_msg', '保存或更新 ' || lv_length || ' 条记录'
  28. );
  29. end
  30. $$

我们执行以下操作

  1. SELECT save_student_addresses_json(
  2. '[
  3. {"student_id":"01","address":"街道A"},
  4. {"student_id":"02","address":"街道B"}
  5. ]'
  6. );

运行结果:{"err_code":200,"err_msg":"保存或更新 2 条记录"}

小结一下

PostgreSQL 对 JSON 的操作支持特性很丰富,但文档中那么多函数一下映入眼帘,让人觉得复杂凌乱。本文从简单易理解的几个应用场景出发,希望能先爽上一把,而后再细细深入。I love PostgreSQL!

原文链接:http://www.cnblogs.com/timeddd/p/10875808.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号