首先需要设计Json解析后保存的关系型数据库表结构,包括主表,附表,各表的主键和外键;
解析详细代码如下:
package jsonparser;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.*;
/**
* Created by leboop on 2020/7/18.
* 将一个json转换成关系型数据库表
*/
public class JsonParser {
/**
* 保存字段名和字段值(字段值可能多个)
*/
private static Map<String, List<String>> map = new HashMap<String, List<String>>();
/**
* 保存文件名,一个文件名相当于一个关系型数据库表
*/
private static Map<String, List<String>> saveFileMap = new HashMap<String, List<String>>();
/**
* 从文件中读取json字符串
*
* @return
*/
private static String readJson() {
StringBuilder sb = new StringBuilder();
try {
BufferedReader br = new BufferedReader(new FileReader(
new File("G:\\idea_workspace\\oozie\\data\\data.json")));
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (Exception e) {
}
return sb.toString();
}
/**
* 从文件中读取字段保存的文件(文件可以理解成一张数据库表)
*/
private static void readSaveFile() {
try {
BufferedReader metaBR = new BufferedReader(new FileReader(
new File("G:\\idea_workspace\\oozie\\data\\meta")));
String line;
while ((line = metaBR.readLine()) != null) {
String k = line.split(":")[0];
String[] vs = line.split(":")[1].split("\\|");
List<String> list = new ArrayList<String>();
for (String v : vs) {
list.add(v);
}
saveFileMap.put(k, list);
}
System.out.println("保存文件名:");
for (Map.Entry<String, List<String>> entry : saveFileMap.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
System.out.println("+++++++++++++++++++++++++++++++");
} catch (Exception e1) {
}
}
public static void main(String[] args) {
String jsonStr = readJson(); //读取json数据
// 使用gson包,将json字符串转换成json对象
com.google.gson.JsonParser jsonParser = new com.google.gson.JsonParser();
JsonElement e = jsonParser.parse(jsonStr);
System.out.println("读取到的json字符串:");
System.out.println(e);
// 解析json
StringBuilder key = new StringBuilder();
jsonTree(e, key);
System.out.println("解析后的json数据:");
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
//读取保存文件
readSaveFile();
//
for (Map.Entry<String, List<String>> entry : saveFileMap.entrySet()) { // 遍历文件
int maxSize = 0;
List<List<String>> tmp = new ArrayList<List<String>>();
for (String fieldName : entry.getValue()) {//遍历字段
List<String> fieldValueList = map.get(fieldName); //字段可能不存在
if (fieldValueList != null) {
if (fieldValueList.size() > maxSize) {
maxSize = fieldValueList.size();
}
tmp.add(fieldValueList);
} else {
tmp.add(Arrays.asList(""));
}
}
// 填充数组
String[][] arr = fill(tmp, maxSize);
//数组转换成字符串
String resultStr = arrToStr(arr);
//写入保存文件
System.out.println("保存文件"+entry.getKey() + ":");
System.out.println(resultStr);
System.out.println("++++++++++++++++++++++++++++++++++++++++++");
}
}
/**
* 数组转换成可写入文件的字符串
*
* @param arr
* @return
*/
private static String arrToStr(String[][] arr) {
StringBuilder resultSb = new StringBuilder();
for (int r = 0; r < arr.length; r++) {
for (int c = 0; c < arr[r].length; c++) {
resultSb.append(arr[r][c]).append("|");
}
resultSb.append("\n");
}
return resultSb.toString();
}
/**
* 数据填充
*
* @param tmp
* @param maxSize
* @return
*/
private static String[][] fill(List<List<String>> tmp, int maxSize) {
String[][] arr = new String[maxSize][tmp.size()];
if (tmp.size() > 0) { //数据填充
for (int c = 0; c < tmp.size(); c++) {
List<String> curr = tmp.get(c);
if (maxSize % curr.size() != 0) { // 异常数据
break;
} else {
int rep = maxSize / curr.size(); //副本数
for (int k = 0; k < curr.size(); k++) { // 行数 =k*r
for (int r = 0; r < rep; r++) {
arr[k * rep + r][c] = curr.get(k);
}
}
}
}
}
return arr;
}
/**
* 递归解析json
*
* @param e
* @param key
*/
private static void jsonTree(JsonElement e, StringBuilder key) {
// 原始数据类型
if (e.isJsonNull() || e.isJsonPrimitive()) {
String keyStr = key.toString();
if (map.containsKey(keyStr)) {
List<String> list = map.get(keyStr);
list.add(e.toString());
map.put(keyStr, list);
} else {
List<String> list = new ArrayList<String>();
list.add(e.toString());
map.put(keyStr, list);
}
key.setLength(0);
return;
}
// 对象数组,注:对象数组不一定是OA,反之OA一定是对象数组
if (e.isJsonArray()) {
JsonArray jsonArr = e.getAsJsonArray();
if (null != jsonArr) {
for (JsonElement je : jsonArr) {
if (je.isJsonNull() || je.isJsonPrimitive()) { // 数组中元素依然是原始数据类型
String keyStr = key.toString();
if (map.containsKey(keyStr)) {
List<String> list = map.get(keyStr);
list.set(0, map.get(keyStr).get(0) + "," + je.toString());
map.put(keyStr, list);
} else {
List<String> list = new ArrayList<String>();
list.add(je.toString());
map.put(keyStr, list);
}
} else { // 不是原始数据类型继续递归
jsonTree(je, key); //递归
}
}
}
}
// json对象
if (e.isJsonObject()) {
// json的所有key=value对
Set<Map.Entry<String, JsonElement>> es = e.getAsJsonObject().entrySet();
String pKey = key.toString(); // 存储父节点
for (Map.Entry<String, JsonElement> en : es) {
if (pKey.length() > 0) { //连接符拼接
key = new StringBuilder(pKey + "-->" + en.getKey());
} else {
key = new StringBuilder(en.getKey());
}
JsonElement element = en.getValue();
jsonTree(element, key); //递归
}
}
}
}
代码中涉及到的文件如下:
(1)data.json
{
"OA": [
{
"rd": 1,
"rn": "s"
},
{
"rd": 2,
"rn": "d"
}
],
"OOA": [
{
"a": 1,
"b": [
{
"c": 1,
"d": [
{
"e": 1
},
{
"e": 2
}
]
},
{
"c": 2,
"d": [
{
"e": 2
},
{
"e": 2
}
]
}
]
},
{
"a": 2,
"b": [
{
"c": 1,
"d": [
{
"e": 1
},
{
"e": 1
}
]
},
{
"c": 2,
"d": [
{
"e": 2
},
{
"e": 2
}
]
}
]
}
],
"name": {
"c": "Rick and Morty",
"d": "dd"
},
"hobby":["t","m",{"s":true}],
"id": "kladu8yak8asdha8",
"boolean": true,
"number": 3,
"k": null,
"ARRAY": [
{
"FIRST": "Rick",
"SEC": "tt"
},
{
"LAST": "Morty"
}
]
}
(2)meta
file_1:name-->c|name-->d|hobby|hobby-->s|id|boolean|number|k|ARRAY-->FIRST|ARRAY-->SEC|ARRAY-->LAST
file_2:id|OA-->rd|OA-->rn
file_3:id|OOA-->a
file_4:OOA-->a|OOA-->b-->c|OOA-->b-->d-->e
输出结果如下:
读取到的json字符串:
{"OA":[{"rd":1,"rn":"s"},{"rd":2,"rn":"d"}],"OOA":[{"a":1,"b":[{"c":1,"d":[{"e":1},{"e":2}]},{"c":2,"d":[{"e":2},{"e":2}]}]},{"a":2,"b":[{"c":1,"d":[{"e":1},{"e":1}]},{"c":2,"d":[{"e":2},{"e":2}]}]}],"name":{"c":"Rick and Morty","d":"dd"},"hobby":["t","m",{"s":true}],"id":"kladu8yak8asdha8","boolean":true,"number":3,"k":null,"ARRAY":[{"FIRST":"Rick","SEC":"tt"},{"LAST":"Morty"}]}
解析后的json数据:
OOA-->a = [1, 2]
ARRAY-->LAST = ["Morty"]
k = [null]
hobby-->s = [true]
OA-->rn = ["s", "d"]
number = [3]
name-->c = ["Rick and Morty"]
name-->d = ["dd"]
boolean = [true]
OOA-->b-->d-->e = [1, 2, 2, 2, 1, 1, 2, 2]
ARRAY-->SEC = ["tt"]
OA-->rd = [1, 2]
ARRAY-->FIRST = ["Rick"]
OOA-->b-->c = [1, 2, 1, 2]
id = ["kladu8yak8asdha8"]
hobby = ["t","m"]
保存文件名:
file_1 = [name-->c, name-->d, hobby, hobby-->s, id, boolean, number, k, ARRAY-->FIRST, ARRAY-->SEC, ARRAY-->LAST]
file_2 = [id, OA-->rd, OA-->rn]
file_3 = [id, OOA-->a]
file_4 = [OOA-->a, OOA-->b-->c, OOA-->b-->d-->e]
+++++++++++++++++++++++++++++++
保存文件file_1:
"Rick and Morty"|"dd"|"t","m"|true|"kladu8yak8asdha8"|true|3|null|"Rick"|"tt"|"Morty"|
++++++++++++++++++++++++++++++++++++++++++
保存文件file_2:
"kladu8yak8asdha8"|1|"s"|
"kladu8yak8asdha8"|2|"d"|
++++++++++++++++++++++++++++++++++++++++++
保存文件file_3:
"kladu8yak8asdha8"|1|
"kladu8yak8asdha8"|2|
++++++++++++++++++++++++++++++++++++++++++
保存文件file_4:
1|1|1|
1|1|2|
1|2|2|
1|2|2|
2|1|1|
2|1|1|
2|2|2|
2|2|2|
++++++++++++++++++++++++++++++++++++++++++
版权声明:本文为L_15156024189原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。