Mysql之如何使用json

@(KNB架构)
欢迎关注作者博客
简书传送门

文章目录

        • 需求
        • 常用函数
          • 创建JSON
          • 查询JSON
          • 修改JSON
          • META信息
        • 单表
          • 单表查询
          • 单表新增
          • 单表修改
        • 多表
          • 关联查询
          • 多表更新
          • 多表详情
          • 多表删除

需求

  1. 详情页实现自定义功能,可自行拖拽编辑内容;
  2. 列表页面可自定义搜索功能
  3. 多表业务关联

不规则json模板

    {
	"id": "1",
	"title": "手术记录",
	"name": "",
	"describe": "请填写手术记录",
	"questions": [{
			"a0": "a0",
			"id": 0,
			"name": "a0",
			"type": 0,
			"input": "a0-input",
			"title": "question1-术前诊断1",
			"answer": [{
					"id": 0,
					"a0-0": "a0-0",
					"name": "a0-0",
					"type": 0,
					"input": "question1-answer-a0-a0-0",
					"title": "question1-answer-术前诊断",
					"content": "sdsd",
					"describe": "question1-answer-手术前的检查",
					"ischecked": 0,
					"locationinput": "questions[0].answer[0].input",
					"locationdescribe": "questions[0].answer[0].describe",
					"locationtitle": "questions[0].answer[0].title",
					"locationcontent": "questions[0].answer[0].content"

				},
				{
					"id": 0,
					"a0-0": "a0-0",
					"name": "a0-0",
					"type": 0,
					"input": "question1-answer-a0-a0-0",
					"title": "question1-answer-术前诊断",
					"content": "sdsd",
					"describe": "question1-answer-手术前的检查",
					"ischecked": 0,
					"locationinput": "questions[0].answer[1].input",
					"locationdescribe": "questions[0].answer[1].describe",
					"locationtitle": "questions[0].answer[1].title",
					"locationcontent": "questions[0].answer[1].content"
				}
			],
			"writeOr": 0,
			"describe": "question1-手术前的检查1",
			"locationinput": "questions[0].input",
			"locationdescribe": "questions[0].describe",
			"locationtitle": "questions[0].title",
			"locationcontent": "questions[0].content"
		},
		{
			"a0": "a0",
			"id": 0,
			"name": "a0",
			"type": 0,
			"input": "a0-input",
			"title": "question1-术前诊断1",
			"answer": [{
					"id": 0,
					"a0-0": "a0-0",
					"name": "a0-0",
					"type": 0,
					"input": "question1-answer-a0-a0-0",
					"title": "question1-answer-术前诊断",
					"content": "sdsd",
					"describe": "question1-answer-手术前的检查",
					"ischecked": 0,
					"locationinput": "questions[1].answer[0].input",
					"locationdescribe": "questions[1].answer[0].describe",
					"locationtitle": "questions[1].answer[0].title",
					"locationcontent": "questions[1].answer[0].content"
				},
				{
					"id": 0,
					"a0-0": "a0-0",
					"name": "a0-0",
					"type": 0,
					"input": "question1-answer-a0-a0-0",
					"title": "question1-answer-术前诊断",
					"content": "sdsd",
					"describe": "question1-answer-手术前的检查",
					"ischecked": 0,
					"locationinput": "questions[1].answer[1].input",
					"locationdescribe": "questions[1].answer[1].describe",
					"locationtitle": "questions[1].answer[1].title",
					"locationcontent": "questions[1].answer[1].content"
				}
			],
			"writeOr": 0,
			"describe": "question1-手术前的检查1",
			"locationinput": "questions[0].input",
			"locationdescribe": "questions[0].describe",
			"locationtitle": "questions[0].title",
			"locationcontent": "questions[0].content"
		}
	],
	"filename": "scmd_test2",
	"version":"v1.0",
	"server":"drclinic",
	"invoke":"/user/insert"
}

常用函数

创建JSON

  类似 varchar,设置 JSON 主要将字段的 type 是 json, 不能设置长度,可以是 NULL 但不能有默认值。

函数说明:

函数名 说明
JSON_ARRAY() 创建json数组
JSON_OBJECT() 创建json对象
JSON_MERGE() 合并json数组或对象
查询JSON

示例数据:

id category tags
1 {“id”: 1, “name”: “lnmp.cn”} [1, 3, 4]
2 {“id”: 2, “name”: “php.net”} [1, 3, 5]

函数说明:

函数名 示例 说明
JSON_CONTAINS() JSON_CONTAINS(category,‘1’,’$.id’) 查询category字段下id值为1的json串,判断是否包含某个json值
JSON_CONTAINS_PATH() 判断某个路径下是否包json值
JSON_EXTRACT() 提取json值
JSON_KEYS() 提取json中的键值为json数组
JSON_SEARCH() 判断某个路径下是否包json值
JSON_CONTAINS_PATH() 按给定字符串关键字搜索json,返回匹配的路径
JSON_UNQUOTE() 等价于"->>"
修改JSON

更新 JSON 下的元素,MySQL 并不支持 column->path 的形式

函数名 说明 备注
JSON_APPEND() 在指定的数组末尾以JSON文本形式追加指定的值并返回。
JSON_ARRAY_APPEND()
JSON_INSERT() 插入新值,但已经存在的值不会被覆盖
JSON_ARRAY_INSERT() 插入数组元素
JSON_SET() 插入新值,并覆盖已经存在的值
JSON_QUOTE()
JSON_REPLACE() 只替换存在的值
JSON_REMOVE() 删除 JSON 元素
META信息
函数名 说明
JSON_DEPTH() 返回json文档的最大深度
JSON_LENGTH() 返回json文档的长度
JSON_TYPE() 返回json值得类型
JSON_VALID() 判断是否为合法json文档

  在5.7.9及之后的版本,可以使用column->path作为JSON_EXTRACT(column, path)的快捷方式。这个函数可以作为列数据的别名出现在SQL语句中的任意位置,包括WHERE,ORDER BY,和GROUP BY语句。同样包含SELECT, UPDATE, DELETE,CREATE TABLE和其他SQL语句。
->左边的参数为JSON数据的列名而不是一个表达式,其右边参数JSON数据中的某个路径表达式。

单表

单表查询

技巧:
mysql json 查询结果去掉双引号 “”
方法1
select json->>’$.attr’ from table;

方法2
select JSON_UNQUOTE(json_extract(json,’$.attr’)) from table;

sql:

SELECT id,json->'$.title' FROM test2 
# 去除字符串引号
SELECT id,json->>'$.questions[0].title' FROM test2 
select id,JSON_UNQUOTE(json_extract(json,'$.questions[0].title')) from test2;

Mysql之如何使用json_第1张图片

# 携带where条件
SELECT id,json->>'$.title' FROM test2 where json->'$.title' = '手术记录'

在这里插入图片描述

# json字符串 解析成对应字段
select JSON_EXTRACT(json,'$.questions[*].title') as questiontitle,
JSON_EXTRACT(json,'$.questions[*].input') as questioninput,
JSON_EXTRACT(json,'$.questions[*].name') as questionname
FROM test2
# 查询所有一级key
select json_keys(json) as a from test2; 

Mysql之如何使用json_第2张图片

# 根据name(name唯一,如:a0-0),查找当前对象的位置:
select replace(json_search(json,'one','a0-0'),'"','') as a from test2;

Mysql之如何使用json_第3张图片

# 通过解析替换,将name替换成input,得到当前对象输入内容
SELECT id,json->'$.questions[0].answer[0].input' as 内容 FROM test2  

Mysql之如何使用json_第4张图片

单表新增
INSERT INTO `table1` (`id`, `info`)
VALUES
	(1 ,'{ "id" : 1, "name" : "aaa" }')
单表修改
UPDATE sc_role SET info = json_set(info,'$.tablename','sc_role_test');
UPDATE sc_role
SET info = json_replace (
	info,
	'$.questions[0].answerInfo.answer[0].tablename',
	"zhouzhixiang",
	'$.describe',
	"zhouzhixiang"
)
WHERE
	id = 'pNqGp45iHt507R85m5d7Jy5V1u190wgPr61m51Akop579325B5g4v5a2578Q1864';
UPDATE sc_table2 AS sc_table2
SET sc_table2.info = '{"version":"v1.0"}'
WHERE
	sc_table2.id = '|10nr6M52n270p65'

多表

关联查询
  1. sc_role
{
	"id": "pNqGp45iHt507R85m5d7Jy5V1u190wgPr61m51Akop579325B5g4v5a2578Q1863",
	"name": "",
	"open": "isTemplatePublish",
	"size": 20,
	"title": "手术记录",
	"current": 1,
	"orderBy": "createtime",
	"version": "v1.0",
	"describe": "测试发布",
	"openSort": true,
	"startNum": 0,
	"questions": [{
		"id": 0,
		"name": "a0",
		"type": 0,
		"class": "icon-tiankongti",
		"input": "三妻四妾所",
		"title": "姓名",
		"writeOr": 0,
		"describe": "",
		"tablename": "sc_role",
		"answerInfo": {
			"answer": [{
				"name": "",
				"type": 0,
				"input": "",
				"title": "",
				"content": "",
				"describe": "",
				"ischecked": 0,
				"tablename": "sc_permission",
				"locationinput": "",
				"locationtitle": "",
				"locationcontent": "",
				"locationdescribe": ""
			}, {
				"name": "",
				"type": 0,
				"input": "",
				"title": "",
				"content": "",
				"describe": "",
				"ischecked": 0,
				"tablename": "sc_role",
				"locationinput": "",
				"locationtitle": "",
				"locationcontent": "",
				"locationdescribe": ""
			}],
			"ischeckedid": []
		},
		"locationinput": "",
		"locationtitle": "",
		"locationcontent": "",
		"locationdescribe": ""
	}],
	"tablename": "sc_role",
	"createtime": 1539597448573,
	"isComplete": 0,
	"modulename": "sc_surgical_record",
	"updatetime": 1539597448573,
	"creatername": "",
	"updatername": "",
	"isTemplatePublish": 1
}
  1. sc_permission
{
	"createtime": 1539597448573,
	"roleid": "pNqGp45iHt507R85m5d7Jy5V1u190wgPr61m51Akop579325B5g4v5a2578Q1863",
	"openSort": true,
	"isTemplatePublish": 1,
	"questions": [{
		"locationinput": "",
		"answerInfo": {
			"answer": [{
				"input": "",
				"locationinput": "",
				"locationdescribe": "",
				"name": "",
				"ischecked": 0,
				"describe": "",
				"type": 0,
				"title": "",
				"content": "",
				"locationtitle": "",
				"tablename": "sc_role",
				"locationcontent": ""
			}, {
				"input": "",
				"locationinput": "",
				"locationdescribe": "",
				"name": "",
				"ischecked": 0,
				"describe": "",
				"type": 0,
				"title": "",
				"content": "",
				"locationtitle": "",
				"tablename": "sc_permission",
				"locationcontent": ""
			}],
			"ischeckedid": []
		},
		"writeOr": 0,
		"type": 0,
		"title": "姓名",
		"locationtitle": "",
		"input": "三妻四妾所",
		"locationdescribe": "",
		"tablename": "sc_permission",
		"name": "a0",
		"id": 0,
		"describe": "",
		"class": "icon-tiankongti",
		"locationcontent": ""
	}],
	"orderBy": "createtime",
	"title": "手术记录1111111",
	"version": "v1.0",
	"updatername": "",
	"current": 1,
	"size": 20,
	"name": "",
	"startNum": 0,
	"modulename": "sc_surgical_record",
	"describe": "测试发布1111111111",
	"id": "11qGp45iHt507R85m5d7Jy5V1u190wgPr61m51Akop579325B5g4v5a2578Q1863",
	"tablename": "sc_permission",
	"updatetime": 1539597448573,
	"creatername": "",
	"open": "isTemplatePublish",
	"isComplete": 0
}
SELECT
	sc_role.id AS sc_role_id,
	sc_role.info -> "$.tablename" AS sc_role_tablename,
	sc_permission.id AS sc_permission_id,
	sc_permission.info -> "$.tabkl[]ename" AS sc_permission_tablename
FROM
	sc_role sc_role
LEFT JOIN sc_permission sc_permission ON sc_role.id = sc_permission.info -> "$.roleid"

在这里插入图片描述

SELECT
	sc_table2.info -> '$.tablename' AS sc_table1_tablename,
	sc_table1.info -> '$.tablename' AS sc_table2_tablename,
	sc_table3.info -> '$.tablename' AS sc_table3_tablename
FROM
	sc_table2 AS sc_table2
LEFT JOIN sc_table1 AS sc_table1 ON sc_table2.info -> '$.sc_table2_id' = sc_table1.info -> '$.sc_table1_id'
LEFT JOIN sc_table3 AS sc_table3 ON sc_table2.info -> '$.sc_table2_id' = sc_table3.info -> '$.sc_table3_id'

Mysql之如何使用json_第5张图片

多表更新
UPDATE sc_role AS sc_role,
 sc_permission AS sc_permission
SET sc_role.info = json_set (
	sc_role.info,
	'$.tablename',
	'sc_role_test2'
),
 sc_permission.info = json_set (
	sc_permission.info,
	'$.tablename',
	'sc_permission_test2'
)
WHERE
	sc_permission.info -> "$.roleid" = sc_role.info -> "$.id";
UPDATE sc_table1 AS sc_table1,
 sc_table3 AS sc_table3,
 sc_table2 AS sc_table2
SET sc_table1.info = json_set (
	sc_table1.info,
	'$.table1realname',
	'zzzzzz'
),
 sc_table3.info = json_set (
	sc_table3.info,
	'$.table3realname',
	'zzzzzz'
),
 sc_table2.info = '{
	"version": "v1.0",
	"sc_table2_id": "3",
	"sc_table1_id": "3",
	"sc_table3_id": "3",
	"tablename": "sc_table2",
	"dominantForeignids": ["sc_table1_id", "sc_table3_id"],
	"dominantForeignFields": ["$.startpoint_sc_table1_endpoint_table1realname", "$.startpoint_sc_table2_endpoint_table2realname", "$.startpoint_sc_table3_endpoint_table3realname"],
	"$.startpoint_sc_table1_endpoint_table1realname": "zzzzzz",
	"$.startpoint_sc_table2_endpoint_table2realname": "zzzzzz",
	"$.startpoint_sc_table3_endpoint_table3realname": "zzzzzz"
}'
WHERE
	sc_table2.info -> '$.sc_table1_id' = sc_table1.info -> '$.sc_table1_id'
AND sc_table2.info -> '$.sc_table3_id' = sc_table3.info -> '$.sc_table3_id'
AND sc_table2.id = '4'
多表详情
UPDATE sc_role AS sc_role,
 sc_permission AS sc_permission
SET sc_role.info = json_set (
	sc_role.info,
	'$.tablename',
	'sc_role_test2'
),
 sc_permission.info = json_set (
	sc_permission.info,
	'$.tablename',
	'sc_permission_test2'
)
WHERE
	sc_permission.info -> "$.roleid" = sc_role.info -> "$.id";
多表删除
DELETE sc_role,
 sc_permission
FROM
	sc_role AS sc_role
LEFT JOIN sc_permission AS sc_permission ON sc_role.info -> "$.id" = sc_permission.info -> "$.roleid"
WHERE
	sc_role.info -> "$.id" = 'pNqGp45iHt507R85m5d7Jy5V1u190wgPr61m51Akop579325B5g4v5a2578Q1863'
欢迎加入Java猿社区!
免费领取我历年收集的所有学习资料哦!

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