解析json生成创建数据库表结构


import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.JsonNodeType;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

 

import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

 

/**
 * 解析Json 创建表结构
 */
@Service
public class JsonService {

 


    /**
     * 根据Json返回字符串创建表语句
     * @param jsonParam
     * @return
     */
    public String createTableSqlByJson(String jsonParam) {
        List analysisResult = analysisJson(jsonParam);
        if (CollectionUtils.isNotEmpty(analysisResult)) {
            //Map> mapperByParentName = analysisResult.stream().collect(Collectors.groupingBy(JsonMapper::getParentName));
            Map> mapperByParentName = analysisResult.stream().collect(Collectors.groupingBy(JsonMapper::getParentName,
                    Collectors.mapping(JsonMapper::getCurrName, Collectors.toList())));
            Iterator iterator = mapperByParentName.entrySet().iterator();
            String sql = "";
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry) iterator.next();
                sql = sql + createSql(entry.getKey().toString(), (List) entry.getValue());
            }
            return sql;
        }
        return null;
    }

 

    /**
     * Jackson 解析json
     * @param jsonParam
     * @return
     */
    public List analysisJson(String jsonParam) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            JsonNode jsonNodeRoot = mapper.readTree(jsonParam);
            List tableMapper = new ArrayList<>();
            List fieldMapper = new ArrayList<>();
            recursiveAnalysis(tableMapper, fieldMapper, "rootJson",jsonNodeRoot);

 

            // 表与表之间
            if (CollectionUtils.isNotEmpty(tableMapper)) {
                // 合并
                fieldMapper.addAll(tableMapper);
                /*for (JsonMapper jsonMapper : tableMapper){
                    System.out.println(jsonMapper.getParentName() + "===111===" +jsonMapper.getCurrName());
                }*/
            }

 

            // 属性与表之间
            if (CollectionUtils.isNotEmpty(fieldMapper)) {

 

                // 去重
                List fieldMapperAfter = fieldMapper.stream().collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(
                                Comparator.comparing(o -> o.getParentName() + ";" + o.getCurrName()))), ArrayList::new));

 

                // 排序
                Collections.sort(fieldMapperAfter, new Comparator(){
                    public int compare(JsonMapper o1, JsonMapper o2) {
                        return o1.getParentName().compareTo(o2.getParentName());// 按照父节点升序
                    }
                });
                /*for (JsonMapper jsonMapper : fieldMapperAfter){
                    System.out.println(jsonMapper.getParentName() + "======" +jsonMapper.getCurrName());
                }*/
                return fieldMapperAfter;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

 

    /**
     *  Jackson 递归解析子节点
     * @param tableMapper 表与表之间关联映射
     * @param fieldMapper 字段属性与表之间关联映射
     * @param parentNodeName 父节点名称
     * @param jsonNode 当前节点
     */
    public void recursiveAnalysis(List tableMapper,List fieldMapper, String parentNodeName,JsonNode jsonNode) {
        if (jsonNode.isContainerNode()){
            if (JsonNodeType.OBJECT == jsonNode.getNodeType()) {
                Iterator fieldNames = jsonNode.fieldNames();
                while (fieldNames.hasNext()) {
                    String fieldName = fieldNames.next();
                    if (jsonNode.get(fieldName).isContainerNode()){
                        //System.out.println("父对象:" +parentNodeName +"当前对象的名称:" + fieldName);
                        tableMapper.add(new JsonMapper(parentNodeName, fieldName));
                        recursiveAnalysis(tableMapper, fieldMapper, fieldName, jsonNode.get(fieldName));
                    } else {
                        //System.out.println("父属性:" +parentNodeName +"当前属性的名称:" +fieldName + "===" + jsonNode.get(fieldName).getNodeType());
                        fieldMapper.add(new JsonMapper(parentNodeName, fieldName + ":" + jsonNode.get(fieldName).getNodeType()));
                    }
                }
            } else if (JsonNodeType.ARRAY == jsonNode.getNodeType()) {
                Iterator jsonNodeElements = jsonNode.iterator();
                while (jsonNodeElements.hasNext()) {
                    JsonNode jsonNodeElement = jsonNodeElements.next();
                    recursiveAnalysis(tableMapper, fieldMapper, parentNodeName, jsonNodeElement);
                }
            }
        }
    }

 

    /**
     * 获取创建表前缀,根据拆分表数字
     * @param tableName
     * @param splitNum
     * @return
     */
    public String getTablePrefix(String tableName, int splitNum) {
        if (splitNum > 0) {
            tableName = tableName + "_" + splitNum;
        }
        StringBuilder tablePrefix = new StringBuilder();
        tablePrefix.append("CREATE TABLE `"+tableName+"` ( \r\n");
        tablePrefix.append("  `id` INT(11) NOT NULL AUTO_INCREMENT COMMENT '主键', \r\n");
        tablePrefix.append("  `orders_id` INT(11) NOT NULL COMMENT '订单ID', \r\n");
        tablePrefix.append("  `user_id` INT(11) DEFAULT NULL, \r\n");
        return tablePrefix.toString();
    }

 

    /**
     * 获取创建表后缀
     * @param tableName
     * @return
     */
    public String getTableSuffix(String tableName) {
        StringBuilder tableSuffix = new StringBuilder();
        tableSuffix.append("  `create_time` DATETIME DEFAULT NULL, \r\n");
        tableSuffix.append("PRIMARY KEY (`id`), \r\n");
        tableSuffix.append("KEY `index_user_id` (`user_id`) USING BTREE \r\n");
        tableSuffix.append(") ENGINE=InnoDB DEFAULT CHARSET=UTF8; \r\n");
        tableSuffix.append(" \r\n");
        return tableSuffix.toString();
    }
    /**
     *  根据表名以及列名称创建表结构
     * @param tableName
     * @param columnNames
     * @return
     */
    public String createSql(String tableName, List columnNames) {

 

        boolean isSplit = isSplitToTables(columnNames.size());

 

        StringBuilder sqlAll = new StringBuilder();
        sqlAll.append(getTablePrefix(tableName, 0));
        for (int i = 0; i < columnNames.size(); i++) {
            if (columnNames.get(i).contains(":")) {
                String str[] = columnNames.get(i).split(":");
                String columnType = buildColumnType(str[1]);
                sqlAll.append("  `"+str[0]+"` "+columnType+" DEFAULT NULL, \r\n");
            }else {
                sqlAll.append("  `"+columnNames.get(i)+"` LONGTEXT DEFAULT NULL, \r\n");
            }
            if (isSplit) {
                if (i > 0 && i % 50 == 0) {
                    sqlAll.append(getTableSuffix(tableName));
                    sqlAll.append(getTablePrefix(tableName, i / 50));
                }
            }
        }
        sqlAll.append(getTableSuffix(tableName));
        return sqlAll.toString();
    }

 

    /**
     * 根据json 字段类型构建数据库字段类型
     * 默认 varchar(20)
     * @param jsonType
     */
    public String buildColumnType(String jsonType) {
        if (JsonNodeType.BOOLEAN.toString().equals(jsonType)) {
            return "CHAR(1)";
        } else if (JsonNodeType.NUMBER.toString().equals(jsonType)) {
            if (jsonType.contains(".")) {
                return "VARCHAR(20)";
            }
            return "INT(11)";
        } else if (JsonNodeType.STRING.toString().equals(jsonType)) {
            return "VARCHAR(100)";
        } else {
            return "VARCHAR(20)";
        }
    }

 

    /**
     * 根据表的列数判断是否需要拆分字段到多个表
     * 当字段 > 80 时,自动创建多表,多表采用单表 50个字段进行分拆
     * @param columns
     * @return
     */
    public boolean isSplitToTables(int columns){
        if (columns >= 80) {
            return true;
        }
        return false;
    }
}

@Data
public class JsonMapper implements Serializable {

 

    private String parentName;

 

    private String currName;

 

    public JsonMapper(String parentName, String currName) {
        this.parentName = parentName;
        this.currName =currName;
    }
}

你可能感兴趣的:(Java)