MySQL5.7的JSON基本操作

MySQL5.7的JSON基本操作

1、建表

在新建表时字段类型可以直接设置为json类型,比如我们创建一张表:

create table `test_user`
(
    `id`   int primary key auto_increment,
    `name` varchar(50) not null,
    `info` json
);

json类型字段可以为NULL

2、插入

(1)直接使用字符串构建json对象

insert into test_user(`name`, `info`)
values ('xiaoming', '{
  "sex": 1,
  "age": 18,
  "nick_name": "小萌"
}');

json类型的字段必须时一个有效的json字符串

(2)可以使用JSON_OBJECT()函数构造json对象

insert into test_user(`name`, `info`)
values ('xiaohua', json_object("sex", 0, "age", 17));

(3)使用JSON_ARRAY()函数构造json数组

insert into test_user(`name`, `info`)
values ('xiaozhang', json_object("sex", 1, "age", 19, "tag", json_array(3, 5, 90)));

查看test_user表中的数据:

mysql> select * from test_user;
+----+-----------+----------------------------------------------+
| id | name      | info                                         |
+----+-----------+----------------------------------------------+
|  1 | xiaoming  | {"age": 18, "sex": 1, "nick_name": "小萌"}   |
|  2 | xiaohua   | {"age": 17, "sex": 0}                        |
|  3 | xiaozhang | {"age": 19, "sex": 1, "tag": [3, 5, 90]}     |
+----+-----------+----------------------------------------------+
3 rows in set (0.00 sec)

3、查询

(1)查询json属性

表达式: 对象为json列->'$.键', 数组为json列->'$.键[index]'

mysql> select name, info -> '$.nick_name' as nick_name, info -> '$.sex' as sex, info -> '$.tag[0]' as 1st_tag from test_user;
+-----------+-----------+------+---------+
| name      | nick_name | sex  | 1st_tag |
+-----------+-----------+------+---------+
| xiaoming  | "小萌"    | 1    | NULL    |
| xiaohua   | NULL      | 0    | NULL    |
| xiaozhang | NULL      | 1    | 3       |
+-----------+-----------+------+---------+
3 rows in set (0.00 sec)

等价于:对象为JSON_EXTRACT(json列 , '$.键'),数组为JSON_EXTRACT(json列 , '$.键[index]')

mysql> select name, JSON_EXTRACT(info, '$.nick_name') as nick_name, JSON_EXTRACT(info, '$.sex') as sex, JSON_EXTRACT(info, '$.tag[0]') as 1st_tag from test_user;
+-----------+-----------+------+---------+
| name      | nick_name | sex  | 1st_tag |
+-----------+-----------+------+---------+
| xiaoming  | "小萌"    | 1    | NULL    |
| xiaohua   | NULL      | 0    | NULL    |
| xiaozhang | NULL      | 1    | 3       |
+-----------+-----------+------+---------+
3 rows in set (0.00 sec)

不过看到上面"小萌"是带双引号的,这不是我们想要的,可以用JSON_UNQUOTE函数将双引号去掉

mysql> select name, JSON_UNQUOTE(info -> '$.nick_name') as nick_name from test_user where name = 'xiaoming';
+----------+-----------+
| name     | nick_name |
+----------+-----------+
| xiaoming | 小萌      |
+----------+-----------+
1 row in set (0.00 sec)

也可以直接使用操作符->>

mysql> select name, info ->> '$.nick_name' as nick_name from test_user where name = 'xiaoming';
+----------+-----------+
| name     | nick_name |
+----------+-----------+
| xiaoming | 小萌      |
+----------+-----------+
1 row in set (0.00 sec)

(2)json属性作为查询条件

mysql> select name, info ->> '$.nick_name' as nick_name from test_user where info -> '$.nick_name' = '小萌';
+----------+-----------+
| name     | nick_name |
+----------+-----------+
| xiaoming | 小萌      |
+----------+-----------+
1 row in set (0.00 sec)

(3)通过虚拟列对JSON类型的指定属性进行快速查询。

创建虚拟列:

mysql> alter table `test_user` add `nick_name` varchar(50) generated always as (info ->> '$.nick_name') virtual;

注意用操作符->>去除双引号

删除虚拟列

mysql> alter table `test_user` drop `nick_name`;

使用时和普通类型的列查询是一样:

mysql> select name, nick_name from test_user where nick_name = '小萌';
+----------+-----------+
| name     | nick_name |
+----------+-----------+
| xiaoming | 小萌      |
+----------+-----------+
1 row in set (0.00 sec)

4、更新

(1)使用JSON_INSERT()插入新值,但不会覆盖已经存在的值

更新前

mysql> select * from test_user where id = 2;
+----+---------+-----------------------+-----------+
| id | name    | info                  | nick_name |
+----+---------+-----------------------+-----------+
|  2 | xiaohua | {"age": 17, "sex": 0} | NULL      |
+----+---------+-----------------------+-----------+
1 row in set (0.00 sec)

更新

mysql> update test_user set info = json_insert(info, '$.sex', 1, '$.nick_name', '小花') where id = 2;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

更新后

mysql> select * from test_user where id = 2;
+----+---------+----------------------------------------------+-----------+
| id | name    | info                                         | nick_name |
+----+---------+----------------------------------------------+-----------+
|  2 | xiaohua | {"age": 17, "sex": 0, "nick_name": "小花"}   | 小花      |
+----+---------+----------------------------------------------+-----------+
1 row in set (0.00 sec)

(2)使用JSON_SET()插入新值,并覆盖已经存在的值

更新前

mysql> select * from test_user where id = 3;
+----+-----------+------------------------------------------+-----------+
| id | name      | info                                     | nick_name |
+----+-----------+------------------------------------------+-----------+
|  3 | xiaozhang | {"age": 19, "sex": 1, "tag": [3, 5, 90]} | NULL      |
+----+-----------+------------------------------------------+-----------+
1 row in set (0.00 sec)

更新

mysql> update test_user set info = json_set(info, '$.age', 20, '$.sex', 0, '$.nick_name', '小张') where id = 3;
Query OK, 1 row affected (0.03 sec)
Rows matched: 1  Changed: 1  Warnings: 0

更新后

mysql> select * from test_user where id = 3;
+----+-----------+-----------------------------------------------------------------+-----------+
| id | name      | info                                                            | nick_name |
+----+-----------+-----------------------------------------------------------------+-----------+
|  3 | xiaozhang | {"age": 20, "sex": 0, "tag": [3, 5, 90], "nick_name": "小张"}   | 小张      |
+----+-----------+-----------------------------------------------------------------+-----------+
1 row in set (0.00 sec)

(3)使用JSON_REPLACE()只替换存在的值

更新前

mysql> select * from test_user where id = 2;
+----+---------+----------------------------------------------+-----------+
| id | name    | info                                         | nick_name |
+----+---------+----------------------------------------------+-----------+
|  2 | xiaohua | {"age": 17, "sex": 0, "nick_name": "小花"}   | 小花      |
+----+---------+----------------------------------------------+-----------+
1 row in set (0.00 sec)

更新

mysql> update test_user set info = json_replace(info, '$.sex', 1, '$.tag', '[1,2,3]') where id = 2;
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0

更新后

mysql> select * from test_user where id = 2;
+----+---------+----------------------------------------------+-----------+
| id | name    | info                                         | nick_name |
+----+---------+----------------------------------------------+-----------+
|  2 | xiaohua | {"age": 17, "sex": 1, "nick_name": "小花"}   | 小花      |
+----+---------+----------------------------------------------+-----------+
1 row in set (0.00 sec)

可以看到tag没有更新进去

(4)使用JSON_REMOVE()删除JSON元素

更新前

mysql> select * from test_user where id = 1;
+----+----------+----------------------------------------------+-----------+
| id | name     | info                                         | nick_name |
+----+----------+----------------------------------------------+-----------+
|  1 | xiaoming | {"age": 18, "sex": 1, "nick_name": "小萌"}   | 小萌      |
+----+----------+----------------------------------------------+-----------+
1 row in set (0.00 sec)

更新

mysql> update test_user set info = json_remove(info, '$.sex', '$.tag') where id = 1;
Query OK, 1 row affected (0.05 sec)
Rows matched: 1  Changed: 1  Warnings: 0

更新后

mysql> select * from test_user where id = 1;
+----+----------+------------------------------------+-----------+
| id | name     | info                               | nick_name |
+----+----------+------------------------------------+-----------+
|  1 | xiaoming | {"age": 18, "nick_name": "小萌"}   | 小萌      |
+----+----------+------------------------------------+-----------+
1 row in set (0.00 sec)

你可能感兴趣的:(数据库,mysql)