详解MySQL5.7新增的JSON数据类型

php laravel框架操作json字段详见:https://xueyuanjun.com/post/8834

json据说是MySQL5.7新增数据类型,以下为学习笔记

1)创建使用json数据类型的表:

CREATE TABLE oper_log (
 id INT NOT NULL AUTO_INCREMENT,
 oper_name VARCHAR(30) NOT NULL,
 oper_detail JSON DEFAULT NULL,#注意字段类型为json
 PRIMARY KEY(id)
);

2)插入数据

-- 插入含有json数组的记录
INSERT INTO oper_log(oper_name,oper_detail ) VALUES( 'admin', JSON_ARRAY(1, "course", NULL, TRUE, CURTIME()));

-- 插入含有json对象的记录
-- 可以使JSON_OBJECT()方法来创建json对象,方法内带有偶数个参数,一个键一个值得形式转换为json
INSERT INTO oper_log(oper_name,oper_detail ) VALUES( 'admin', JSON_OBJECT("course", "维修保养课程", "currentTime", now()));
-- 如果如下面向JSON_OBJECT()方法传入奇数个参数,会报错:Incorrect parameter count in the call to native function 'JSON_OBJECT'
INSERT INTO oper_log(oper_name,oper_detail ) VALUES( 'admin', JSON_OBJECT("course", "维修保养课程", "currentTime"));//错误的
-- 还可以使用json字符串的形式传入json对象
INSERT INTO oper_log(oper_name,oper_detail ) VALUES( 'admin', '{"course":"数据结构课程", "currentTime":"2018-010-1 14:01:00"}');
-- 一定要转换为字符串,如下直接传入对象,会报错:You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"course":"数据结构课程", "currentTime":"2018-010-1 14:01:00"})' at line 1
INSERT INTO oper_log(oper_name,oper_detail ) VALUES( 'admin', {"course":"数据结构课程", "currentTime":"2018-010-1 14:01:00"}); //错误的

上面插入的数据:

3)查询json中某个字段的值

SELECT id,JSON_EXTRACT(oper_detail,'$.course') as course FROM oper_log;

或:
SELECT id,oper_detail->'$.course' as course FROM oper_log;

详解MySQL5.7新增的JSON数据类型_第1张图片

4)以json中的某个字段进行查询

 SELECT * FROM oper_log WHERE JSON_EXTRACT(oper_detail,'$.course') LIKE '%2%';

另一个案例,方法更全

一、我们先创建一个表,准备点数据

1

2

3

4

5

CREATE TABLE `json_test` (

  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',

  `json` json DEFAULT NULL COMMENT 'json数据',

  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

详解MySQL5.7新增的JSON数据类型_第2张图片

二、检索json列的字段

通过使用 -> 或 ->> 运算符检索json列的字段

1

select id, json->'$[0].items[0].name' from json_test;

详解MySQL5.7新增的JSON数据类型_第3张图片

1

select id, json->>'$[0].items[0].name' from json_test;

详解MySQL5.7新增的JSON数据类型_第4张图片

使用 -> 和 ->> 的区别是结果用了引号包裹。

三、查询json的一些函数

JSON_PRETTY(json_val) 以优雅的格式显示json值

1

select id, JSON_PRETTY(json) from json_test\G;

JSON_CONTAINS(target, candidate[, path]) 判断给定的candidate是否包含在target中,如果指定了path,则在指定路径中进行查找。

注意,注意,注意,这里的candidate如果是数字,需要用单引号包裹,如果是字符串,单引号里再加上双引号包裹。

1

2

select JSON_CONTAINS(json->'$[0].name''"1号篮子"') from json_test;

select JSON_CONTAINS(json, '"1号篮子"''$[0].name') from json_test;

JSON_CONTAINS_PATH(json_doc, one_or_all, path[, path] ...)  判断json_doc中的路径是否存在,通俗点说就是json中的key是否存在

1

select JSON_CONTAINS_PATH(json, 'one''$[0].name''$[0].test') from json_test;

第二个参数'one'表示只要有一个key存在就返回1,否则为0

1

select JSON_CONTAINS_PATH(json, 'all''$[0].name''$[0].test') from json_test;

第二个参数'all'表示所有key存在才返回1,否则为0

JSON_SET(json_doc, path, val[, path, val] ...) 插入或更新数据并返回结果

1

select JSON_SET(json, '$[0].name''2号篮子''$[0].test''test') from json_test;

我们修改$[0].name的值,并添加一个key为test,值为test的项

JSON_INSERT(json_doc, path, val[, path, val] ...) 插入数据并返回结果,但不替换现有值。

1

select JSON_INSERT(json, '$[0].name''2号篮子''$[0].exts''扩展') from json_test;

这时$[0].name不会被更新,只会新增一个字段$[0].exts

JSON_REPLACE(json_doc, path, val[, path, val] ...) 替换现有值并返回结果

1

select JSON_REPLACE(json, '$[0].name''替换') from json_test;

将$[0].name中的值替换成新值

JSON_REMOVE(json_doc, path[, path] ...)  删除数据并返回结果

1

select JSON_REMOVE(json, '$[0].name') from json_test;

删除$[0].name这项数据

JSON_KEYS(json_doc[, path]) 获取json文档中的所有键

1

select JSON_KEYS(json, '$[0]') from json_test;

获取$[0]路径下的所有键

JSON_LENGTH(json_doc[, path]) 获取json文档的长度

1

select JSON_LENGTH(json, '$[0]') from json_test;

获取$[0]下的元素数量

JSON_EXTRACT(json_doc, path[, path] ...)  返回json文档中的数据

1

2

select JSON_EXTRACT(json, '$[0]') from json_test;

select JSON_EXTRACT(json, '$[0].name') from json_test;

返回json文档指定路径下的数据

JSON_ARRAY([val[, val] ...])  创建json数组

1

select JSON_ARRAY(1, '2', true, 5.6, null, now());

  

JSON_OBJECT([key, val[, key, val] ...]) 通过键值对, 创建json对象

1

select JSON_OBJECT('name''xiaoxu''age', 28, 'height', 1.72);

注意,这里键和值要成对出现

JSON_MERGE_PATCH(json_doc, json_doc[, json_doc] ...)  合并json文档,如果有重复键,后面的数据覆盖前面的

1

select JSON_MERGE_PATCH('{"name":"test1"}''{"name":"test2"}');

  

JSON_MERGE_PRESERVE(json_doc, json_doc[, json_doc] ...)  合并json文档,如果有重复键,则会通过数组把值都保存起来

1

select JSON_MERGE_PRESERVE('{"name":"test1"}''{"name":"test2"}');

  

JSON_QUOTE(string)  通过用双引号字符包裹并转义内部引号和其他字符

1

select JSON_QUOTE('你好"世界"');

  

JSON_UNQUOTE(json_val)  将转义字符转换回普通字符

1

select JSON_UNQUOTE('你好\\t\"世界\"');

  

通过json_set函数,来修改data字段的值

mysql> update tab_json set data = json_set(data,"$.address","Guangzhou") where id = 1;  #对id = 1的行的address的键值进行修改.
Query OK, 1 row affected (0.26 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from tab_json;
+----+--------------------------------------------------------------+
| id | data                                                         |
+----+--------------------------------------------------------------+
|  1 | {"tel": 13249872314, "name": "Mike", "address": "Guangzhou"} |
|  2 | {"tel": 189776542, "name": "David", "address": "Shanghai"}   |
+----+--------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> update tab_json set data = json_set(data,"$.address","Shenzhen");
Query OK, 2 rows affected (0.02 sec)
Rows matched: 2  Changed: 2  Warnings: 0

mysql> select * from tab_json;
+----+-------------------------------------------------------------+
| id | data                                                        |
+----+-------------------------------------------------------------+
|  1 | {"tel": 13249872314, "name": "Mike", "address": "Shenzhen"} |
|  2 | {"tel": 189776542, "name": "David", "address": "Shenzhen"}  |
+----+-------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> update tab_json set data = json_set(data,"$.address","Hangzhou") where id = 2; #对id为2的address键值进行修改
Query OK, 1 row affected (0.03 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from tab_json;
+----+-------------------------------------------------------------+
| id | data                                                        |
+----+-------------------------------------------------------------+
|  1 | {"tel": 13249872314, "name": "Mike", "address": "Shenzhen"} |
|  2 | {"tel": 189776542, "name": "David", "address": "Hangzhou"}  |
+----+-------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> update tab_json set data = json_set(data,"$.passcode","654567") where id = 1;  #对id为1的passcode字段进行修改,发现没有这个键值,就增加了一个键值对.
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from tab_json;
+----+-----------------------------------------------------------------------------------+
| id | data                                                                              |
+----+-----------------------------------------------------------------------------------+
|  1 | {"tel": 13249872314, "name": "Mike", "address": "Shenzhen", "passcode": "654567"} |
|  2 | {"tel": 189776542, "name": "David", "address": "Hangzhou"}                        |
+----+-----------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> update tab_json set data = json_set(data,"$.olds","12") where id = 2;
Query OK, 1 row affected (0.17 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from tab_json;
+----+-----------------------------------------------------------------------------------+
| id | data                                                                              |
+----+-----------------------------------------------------------------------------------+
|  1 | {"tel": 13249872314, "name": "Mike", "address": "Shenzhen", "passcode": "654567"} |
|  2 | {"tel": 189776542, "name": "David", "olds": "12", "address": "Hangzhou"}          |
+----+-----------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql> update tab_json set data = json_set(data,"$.age","33");
Query OK, 2 rows affected (0.02 sec)
Rows matched: 2  Changed: 2  Warnings: 0

mysql> select * from tab_json;
+----+------------------------------------------------------------------------------------------------+
| id | data                                                                                           |
+----+------------------------------------------------------------------------------------------------+
|  1 | {"age": "33", "tel": 13249872314, "name": "Mike", "address": "Shenzhen", "passcode": "654567"} |
|  2 | {"age": "33", "tel": 189776542, "name": "David", "olds": "12", "address": "Hangzhou"}          |
+----+------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

备注:以上就是通过json_set进行对json字段的键值进行修改,如果存在就进行替换,如果不存在键值,就增加键值对.

update shape_element set property = json_set(property, '$.imgSrc', replace(property->'$.imgSrc', 'https://fp-static.wondershare.com/', '')) where id = 36181;

你可能感兴趣的:(mysql,tidb)