gson解析Json后保存到关系数据库表中(Json含多层嵌套对象数组)

  • Post author:
  • Post category:其他


首先需要设计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 版权协议,转载请附上原文出处链接和本声明。