雖然MySQL5.7開始原生支持json格式數據,但是如果需要把數據庫表中的樹結構json解析轉成相應樹表結構的話,一般是通過c#、java、js等語言解析完成再寫入table的。其實,在MySQL內部,不需借助其它語言,就能完成轉換。
- 多層嵌套json數據示例
以下json字符串存儲在treejson表的tree字段中
{ "children" : [ { "id" : 2, "name" : "西安", "children" : [] } ], "id" : 1, "name" : "陝西" }
- 表treejson結構
列名---數據類型---描述
num---INT(11)-----自增id
id-------INT(11)-----treeId
tree----JSON-------treeJson
- 使用表treetable接收轉換后的數據
列名---數據類型---描述
num-----INT(11)------------自增id
rootId---INT(11)------------tree根節點id
id--------INT(11)-------------treeNodeId
pId------INT(11)-------------treePNodeId
name---VARCHAR(45)---nodeName
path-----VARCHAR(50)---nodePath
level-----TINYINT(2)-------nodeLevel
- 使用存儲過程轉換
CREATE DEFINER=`root`@`localhost` PROCEDURE `extractjson`(IN jsonPath varchar(100), IN treePath varchar(50), IN parentId int, IN treeLevel int, IN treeJsonId int) BEGIN # 當前節點id DECLARE tempId INT DEFAULT '0'; # 當前節點下屬的子節點數目 DECLARE childrenLen INT DEFAULT '0'; # 當前節點下屬的子節點json的解析路徑 DECLARE nextJsonPath varchar(100) DEFAULT ''; # 設置變量值 SET tempId = (SELECT JSON_EXTRACT(tree,CONCAT(jsonPath,'.id')) FROM treejson WHERE id = treeJsonId); SET childrenLen = (SELECT JSON_LENGTH(tree,CONCAT(jsonPath,'.children')) FROM treejson WHERE id = treeJsonId); # 內置參數必要的遞歸層深限制 SET @@max_sp_recursion_depth = 100; # 把當前節點插入到數據表 INSERT INTO treetable(rootId,id,pId,name,path,level) SELECT JSON_EXTRACT(tree,'$.id') AS rootId ,tempId AS id ,parentId AS pId ,JSON_EXTRACT(tree,CONCAT(jsonPath,'.name')) AS name ,CONCAT(treePath,',',tempId) AS path ,(treeLevel + 1) AS level FROM treejson WHERE treejson.id = treeJsonId; # 循環把所有子節點插入數據表 WHILE childrenLen > 0 DO SET nextJsonPath = CONCAT(jsonPath, '.children[', childrenLen - 1, ']'); CALL extractjson(nextJsonPath, CONCAT(treePath,',',tempId), tempId, (treeLevel + 1), treeJsonId); SET childrenLen = childrenLen - 1; END WHILE; END