翻译MYSQL建表语句,生成表结构的JSON

  根据建表语句解析表结构,并将表结构解析为JSON。根据MYSQL的建表语句,

  建表语句:

CREATE TABLE `TEST` (

`ID` varchar(56) NOT NULL,

`CREAETE_TIME` datetime NOT NULL,

`IS_DEL` varchar(6) NOT NULL COMMENT '否已删除:0 否、1 是',

`DESC` varchar(255) NOT NULL COMMENT '描述',

`SORT` int(16) NOT NULL COMMENT '排序'

);

  设置自动机如下:

  代码实现:

public class MysqlBeanUtil {
    static String expression = "";

    public static void main(String[] args) {
        MysqlBeanUtil m = new MysqlBeanUtil();
        Analysis analysis = m.new Analysis();
        List<Analysis.TableContext> list = analysis.scope(expression);
        String res = "";
        for (int i = 0; i < list.size(); i++) {
            Analysis.TableContext table = list.get(i);
            res += System.lineSeparator();
            res += ">>>>>>>>>>>>>>>>" + table.tableName + "<<<<<<<<<<<<<<<";
            res += System.lineSeparator();
            JSONArray fields = table.fields;
            String beanStr = "";
            String mybatisStr = "";
            for (int j = 0; j < fields.size(); j++) {
                JSONObject field = fields.getJSONObject(j);
                String fieldName = field.getString("field");
                String transfieldName = m.transferUpper(fieldName);
                String fieldType = field.getString("type");
                String comment = field.getString("comment");
//                String beanType = fieldType.contains("int") ? "int" : "String";
                String beanType = "String";
                String isReq = field.getString("isReq");
                if ("sort".equals(transfieldName)) {
                    beanStr += "@FieldDev(name = \"" + comment + "\", isRequired = " + isReq + ", nameForSource = \"" + transfieldName + "\", defaultValue = \"1\")";
                } else if ("isDel".equals(transfieldName)) {
                    beanStr += "@FieldDev(name = \"" + comment + "\", isRequired = " + isReq + ", nameForSource = \"" + transfieldName + "\", defaultValue = \"0\")";
                } else if ("id".equals(transfieldName)) {
                    beanStr += "@FieldDev(name = \"" + comment + "\", isRequired = " + isReq + ", nameForSource = \"" + transfieldName + "\", defaultValue = \"${uuid}\")";
                } else if ("createTime".equals(transfieldName)) {
                    beanStr += "@FieldDev(name = \"" + comment + "\", isRequired = " + isReq + ", nameForSource = \"" + transfieldName + "\", defaultValue = \"${currentTime}>>yyyy-MM-dd HH:mm:ss\")";
                } else
                    beanStr += "@FieldDev(name = \"" + comment + "\", isRequired = " + isReq + ", nameForSource = \"" + transfieldName + "\")";
                beanStr += System.lineSeparator();
                if ("id".equals(transfieldName)) {
                    beanStr += "@TableId(\"ID\")";
                    beanStr += System.lineSeparator();
                }
                beanStr += "private " + beanType + " " + transfieldName + ";";
                beanStr += System.lineSeparator();
                mybatisStr += "<result column=\"" + fieldName + "\" property=\"" + transfieldName + "\"/>";
                mybatisStr += System.lineSeparator();
            }
            res += ">>>>>>>>>> beanStr <<<<<<<<<";
            res += System.lineSeparator();
            res += "@Data";
            res += System.lineSeparator();
            res += "@TableName(\"" + table.tableName + "\")";
            res += System.lineSeparator();
            res += "public class " + m.transferUpper(table.tableName) + " extends BaseEntity implements Serializable {private static final long serialVersionUID = 1L;";
            res += System.lineSeparator();
            res += beanStr;
            res += "}";
            res += System.lineSeparator();

            res += ">>>>>>>>>> mybatisStr <<<<<<<<<";
            res += System.lineSeparator();
            res += mybatisStr;
        }
        System.out.println(res);
    }

    //  分析建 mysql 表语句
    class Analysis {
        public List<TableContext> scope(String express) {
            int len = express.length(), left = 0, right = left;
            express = express.replaceAll(System.lineSeparator(), "");
            TableContext currentContext = new TableContext();
            currentContext.expStatus = ExpStatus.START;
            List<TableContext> tableList = new LinkedList<TableContext>();
            while (right < len) {
                char c = express.charAt(right);
                if (c == ';') {
                    tableList.add(currentContext);
                    currentContext = new TableContext();
                    currentContext.expStatus = ExpStatus.START;
                    right++;
                    continue;
                }
                if (c == ' ' || c == '\n') {
                    right++;
                    continue;
                }
                if (c == ',') {
                    if (currentContext.expStatus == ExpStatus.TYPE || currentContext.expStatus == ExpStatus.NN) {
                        JSONObject fieldJson = new JSONObject();
                        fieldJson.put("field", currentContext.field);
                        fieldJson.put("type", currentContext.type);
                        fieldJson.put("isReq", currentContext.isReq ? "true" : "false");
                        fieldJson.put("comment", "");
                        currentContext.fields.add(fieldJson);
                        currentContext.expStatus = ExpStatus.W_KEY;
                    }
                    right++;
                    continue;
                }
                if (c == '`' || c == '\'') {
                    if (currentContext.expStatus == ExpStatus.W_TABLE) {
                        currentContext.expStatus = ExpStatus.TABLE;
                    } else if (currentContext.expStatus == ExpStatus.TABLE) {
                        currentContext.expStatus = ExpStatus.W_KEY;
                    } else if (currentContext.expStatus == ExpStatus.W_KEY) {
                        currentContext.expStatus = ExpStatus.KEY;
                    } else if (currentContext.expStatus == ExpStatus.KEY) {
                        currentContext.expStatus = ExpStatus.W_TYPE;
                    } else if (currentContext.expStatus == ExpStatus.W_COM1) {
                        currentContext.expStatus = ExpStatus.COM;
                    } else if (currentContext.expStatus == ExpStatus.COM) {
                        currentContext.expStatus = ExpStatus.W_KEY;
                    }
                    right++;
                    continue;
                }
                Token currentToken = this.getToken(express, right);
                right = currentToken.right;
                // 关键字
                if ("COMMENT".equals(currentToken.token)) {
                    if (currentContext.expStatus == ExpStatus.TYPE) currentContext.expStatus = ExpStatus.W_COM1;
                    else if (currentContext.expStatus == ExpStatus.NULL) currentContext.expStatus = ExpStatus.W_COM1;
                    else if (currentContext.expStatus == ExpStatus.NOT_NULL2)
                        currentContext.expStatus = ExpStatus.W_COM1;
                } else if ("NOT".equals(currentToken.token)) {
                    if (currentContext.expStatus == ExpStatus.TYPE) currentContext.expStatus = ExpStatus.NOT_NULL1;
                } else if ("NULL".equals(currentToken.token)) {
                    if (currentContext.expStatus == ExpStatus.TYPE) {
                        currentContext.expStatus = ExpStatus.NULL;
                        currentContext.isReq = false;
                    } else if (currentContext.expStatus == ExpStatus.NOT_NULL1) {
                        currentContext.expStatus = ExpStatus.NOT_NULL2;
                        currentContext.isReq = true;
                    }
                } else {
                    // 普通 token
                    if (currentContext.expStatus == ExpStatus.START) {
                        if ("TABLE".equals(currentToken.token)) {
                            currentContext.expStatus = ExpStatus.W_TABLE;
                        }
                    } else if (currentContext.expStatus == ExpStatus.TABLE) {
                        currentContext.tableName = currentToken.token;
                    } else if (currentContext.expStatus == ExpStatus.KEY) {
                        currentContext.field = currentToken.token;
                    } else if (currentContext.expStatus == ExpStatus.W_TYPE) {
                        currentContext.type = currentToken.token;
                        currentContext.expStatus = ExpStatus.TYPE;
                    } else if (currentContext.expStatus == ExpStatus.NULL ||
                            currentContext.expStatus == ExpStatus.NOT_NULL2) {
                        currentContext.expStatus = ExpStatus.NN;
                    } else if (currentContext.expStatus == ExpStatus.COM) {
                        currentToken = this.getCommentToken(express, currentToken.left);
                        right = currentToken.right;
                        currentContext.comment = currentToken.token;
                        JSONObject fieldJson = new JSONObject();
                        fieldJson.put("field", currentContext.field);
                        fieldJson.put("type", currentContext.type);
                        fieldJson.put("isReq", currentContext.isReq ? "true" : "false");
                        fieldJson.put("comment", currentContext.comment);
                        currentContext.fields.add(fieldJson);
                    }
                }
            }
            return tableList;
        }

        public Token getToken(String express, int left) {
            int len = express.length(), right = left;
            char c = express.charAt(right);
            StringBuilder sb = new StringBuilder();
            while (right < len && c != '`' && c != ' ' && c != '\'' && c != ';' && c != ',') {
                sb.append(c);
                right++;
                if (right < len) c = express.charAt(right);
            }
            return new Token(sb.toString(), left, right);
        }

        // comment 中可能有空格
        public Token getCommentToken(String express, int left) {
            int len = express.length(), right = left;
            char c = express.charAt(right);
            StringBuilder sb = new StringBuilder();
            while (left < len && c != '`' && c != '\'' && c != ';') {
                sb.append(c);
                right++;
                c = express.charAt(right);
            }
            return new Token(sb.toString(), left, right);
        }

        class TableContext {
            String tableName;
            JSONArray fields;
            ExpStatus expStatus;
            String field;
            String type;
            String comment;
            Boolean isReq;

            TableContext() {
                this.fields = new JSONArray();
            }

        }

        class Token {
            String token;
            int left;
            int right;

            Token(String token, int left, int right) {
                this.token = token;
                this.left = left;
                this.right = right;
            }

        }
    }

    enum ExpStatus {
        START, W_TABLE, TABLE, W_KEY, KEY, W_TYPE, TYPE, W_COM1, NULL, NOT_NULL1, NOT_NULL2, NN, COM, SUCC
    }

    public String transferUpper(String str) {
        str = str.toLowerCase();
        int point = 0, len = str.length();
        char[] cs = str.toCharArray();
        StringBuilder sb = new StringBuilder();
        while (point < len) {
            //不是字母就是分隔符
            if (cs[point] < 'a' || cs[point] > 'z') {
                //不是字母就略过
                while ((cs[point] < 'a' || cs[point] > 'z') && point < len) point++;
                if (point == len) break;
                if (cs[point] >= 'a' && cs[point] <= 'z') sb.append((char) (cs[point] - 32));
                else sb.append(cs[point]);
            } else sb.append(cs[point]);
            point++;
        }
        if (sb.length() == 0) throw new RuntimeException("字符串 : " + str + "无法转换为驼峰格式!");
        return sb.toString();
    }

}

 

posted @ 2023-02-16 18:15  牛有肉  阅读(244)  评论(0编辑  收藏  举报