重構舊項目實體類

本文只是拋磚引玉,不能百分百確認沒有錯誤

我們公司使用了最開始的人自己封裝的數據庫操作,但是效率過低,只是用了mybatis,現在想改成mybatis-plus,之前也沒有swagger 現在也想使用,都是生成的get和set方法,這改成lombok,但是數據庫里面并沒有注釋,只是在代碼中寫了注釋,這里介紹下我重構的思路,和自己寫的樣本

給大家截一個圖 注解都是自定義的


image.png

生成后的效果圖(onlyMp = true 表示不需要遠來封裝的注解)

image.png

代碼里面有很多沒有格式化,導致取字符串的時候對字符串操作很多
再截一個圖 還存在 這種注釋

image.png

沒有縮進的也有

image.png

接下來開始解析文件

  1. 獲取所有目標文件,這個就不用貼代碼了,使用字符流讀取文件(最后會給所有代碼)
        List<File> files = getFiles(from);
        for (File file : files) {
//            if (!file.getName().equals("TransferFormVO.java")) {
//                continue;
//            }
            TableInfo tableInfo = createTableInfo(file);
            if (tableInfo == null || tableInfo.getClassName() == null || createExclude.contains(tableInfo.getClassName())) {
                continue;
            }
            tableInfoList.add(tableInfo);
        }

重點是 createTableInfo這個方法

  1. 獲取包名,導報,排除靜態,get,set方法
                //包名
                if (line.startsWith("package")) {
                    tableInfo.setPackag(line.replace("package", "").replace(";", "").trim());
                }
                //導入的類
                if (line.startsWith("import")) {
                    String anImport = line.replace("import", "").replace(";", "").trim();
                    if (!anImport.isEmpty() && anImport.contains("sysenum") && !enums.isEmpty()) {
                        anImport = anImport.replace("com.caijai.base.sysenum", enums);
                    }
                    tableInfo.getImportPackage().add(anImport);
                }
                //排除靜態,get set方法
                if (line.isEmpty() || line.contains("static") || line.contains("()") || line.contains("void")) {
                    continue;
                }
  1. 獲取類信息,獲取舊框架的注解,獲取類的注釋
                //獲取類的信息
                if (line.contains("public class ")) {
                    String className;
                    if (line.contains("extends")) {
                        if (line.split("extends").length > 0) {
                            tableInfo.setSupper(line.substring(line.indexOf("extends"), line.indexOf("{")).replace("extends", "").trim());
                            if (tableInfo.getSupper().equals("BaseEntity")) {
                                tableInfo.setSupper("BaseTable");
                                tableInfo.getImportPackage().add("com.caijai.base.entity.BaseTable");
                            }
                        }
                        className = line.substring(line.indexOf("class"), line.indexOf("extends")).replace("class", "").trim();
                    } else {
                        className = line.substring(line.indexOf("class"), line.indexOf("{")).replace("class", "").trim();
                    }
                    tableInfo.setClassName(className);
                    continue;
                } else if (line.startsWith("@Table")) {
                    //獲取表名
                    tableInfo.setTableName(line.substring(line.indexOf("\""), line.indexOf("\")")).replace("\"", ""));
                    continue;
                }
                if (tableInfo.getClassName() == null) {
                    //獲取類注釋
                    if ((line.startsWith("http://") || line.startsWith("*") || line.startsWith("/**")) && !line.startsWith("*/")) {
                        if (line.equals("*")) {
                            tableInfo.setRemarks(tableInfo.getRemarks() + "\n");
                            continue;
                        }
                        if (tableInfo.getRemarks() != null) {
                            tableInfo.setRemarks(tableInfo.getRemarks() + "\n" + line.replace("* ", ""));
                        } else {
                            tableInfo.setRemarks(line.replace("* ", ""));
                        }
                    }
                }
  1. 如果類的信息已存在,那么接下來讀的都是字段信息
                    List<TableFiled> files = tableInfo.getFiles();
                    TableFiled filed = new TableFiled();
                    if (files.isEmpty()) {
                        files.add(filed);
                    }
                    TableFiled tableFiled = files.get(files.size() - 1);
                    //判斷該字段到底有沒有 如果沒有就用之前的,否則就添加新的
                    if (tableFiled.getProperty() != null) {
                        files.add(filed);
                    }
                    filed = files.get(files.size() - 1);
                    //字段注釋
                    if ((line.startsWith("http://") || line.startsWith("*") || line.startsWith("/**")) && !line.startsWith("*/")) {
                        if (line.equals("*")) {
                            filed.setRemarks(filed.getRemarks() + "\n");
                            continue;
                        }
                        if (filed.getRemarks() != null) {
                            filed.setRemarks(filed.getRemarks() + "\n" + line.replace("* ", ""));
                        } else {
                            filed.setRemarks(line.replace("* ", "").replace("/*", "").replace("*/", ""));
                        }
                    } else if (line.startsWith("@Column")) {
                        filed.setExits(true);
                        //老框架封裝的數據庫 保留
                        String[] primaries = line.split("=");
                        for (int i = 0; i < primaries.length; i++) {
                            String primary = primaries[i].trim();
                            if (primary.contains("primary")) {
                                filed.setPrimary(Boolean.parseBoolean(primaries[i + 1].trim().replace(")", "")));
                            } else if (primary.contains("readonly")) {
                                filed.setExits(false);
                                filed.setReadonly(Boolean.parseBoolean(primaries[i + 1].trim().replace(")", "")));
                            } else if (primary.contains("byInt")) {
                                filed.setByInt(Boolean.parseBoolean(primaries[i + 1].trim().replace(")", "")));
                            } else if (primary.contains("byDouble")) {
                                filed.setByDouble(Boolean.parseBoolean(primaries[i + 1].trim().replace(")", "")));
                            } else if (primary.contains("sort ")) {
                                filed.setSort(primaries[i + 1].trim().replace(")", ""));
                            }
                        }
                        //獲取數據庫對應的字段名
                        int i = line.indexOf("\",");
                        if (i != -1) {
                            filed.setColumn(line.substring(line.indexOf("\"") + 1, i).replace("\"", "").trim());
                        } else if ((i = line.indexOf("\")")) != -1) {
                            i = line.indexOf("\")");
                            filed.setColumn(line.substring(line.indexOf("\"") + 1, i).replace("\"", "").trim());
                        } else if ((i = line.indexOf("\" ,")) != -1) {
                            filed.setColumn(line.substring(line.indexOf("\"") + 1, i).replace("\"", "").trim());
                        }
                    } else if (line.startsWith("@Relation")) {
                        //獲取舊框架 關聯查詢字段
                        String[] split = line.split("=");
                        for (int i = 0; i < split.length; i++) {
                            String s = split[i].trim();
                            if (s.contains("table")) {
                                filed.setTable(split[i + 1].trim().replace(")", "").split(",")[0]);
                            } else if (s.contains("ref")) {
                                filed.setRef(split[i + 1].trim().replace(")", "").split(",")[0]);
                            } else if (s.contains("value")) {
                                filed.setValue(split[i + 1].trim().replace(")", "").split(",")[0]);
                            } else if (s.contains("show")) {
                                filed.setShow(split[i + 1].trim().replace(")", "").split(",")[0]);
                            }
                        }
                        filed.setJoinTable(line.replace("table", "表名").replace("value", "關聯表字段").replace("ref", "當前表字段").replace("show", "查詢的字段"));
                    } else if ((line.startsWith("private") || line.startsWith("public")) && !line.contains("class")) {
                        // 修飾符 類型名稱 字段名稱 備注
                        line = line.replace("  ", " ").replace(" ;", ";");
                        String[] s = line.split(" ");
                        filed.setModifier(s[0].trim());
                        filed.setClassName(s[1].trim());
                        filed.setProperty(s[2].substring(0, s[2].indexOf(";")).replace("\t", ""));
                        String[] split = line.split("http://");
                        if (split.length > 1) {
                            filed.setRemarks(split[1]);
                        }
                    }

獲取類的數據,接下來就開始生成文件,使用的是javapoet

  1. 如果該類有繼承就把繼承的類找出來,不生成相同字段
        if (tableInfo.getSupper() != null) {
            classBuilder.addAnnotation(AnnotationSpec.builder(EqualsAndHashCode.class).addMember("callSuper", "true").build());
            Optional<String> first = tableInfo.getImportPackage().stream().filter(s -> s.contains(tableInfo.getSupper())).findFirst();
            info = tableInfoList.stream().filter(s -> {
                        boolean supper = s.getClassName().equals(tableInfo.getSupper());
                        boolean equals = s.getPackag().equals(first.orElse("").replace("." + s.getClassName(), ""));
                        return equals && supper;
                    }
            ).findFirst().orElse(null);
            if (first.isPresent()) {
                String replace1 = first.get().replace("." + tableInfo.getSupper(), "");
                if (changePackage) {
                    //交換包名(我起的不一樣所有要改成我自己的,如果是false就是原包名)
                    String[] split = replace1.replace("com.caijai.", "").split("\\.");
                    String s = split[0];
                    String s1 = split[1];
                    StringBuilder s3 = new StringBuilder();
                    if (split.length > 2) {
                        for (int i = 2; i < split.length; i++) {
                            s3.append(".").append(split[i]);
                        }
                    }
                    replace1 = newPackage + "." + s1 + "." + s + s3.toString();
                }
                classBuilder.superclass(ClassName.get(replace1, tableInfo.getSupper()));
            }
        }
  1. 添加類注解和備注
        if (tableInfo.getTableName() != null) {
            if (!onlyMp) {
                AnnotationSpec tableSpec = AnnotationSpec.builder(ClassName.get("com.caijai.base.anno", "Table")).addMember("name", "$S", tableInfo.getTableName()).build();
                classBuilder.addAnnotation(tableSpec);
            }
            classBuilder.addAnnotation(AnnotationSpec.builder(TableName.class).addMember("value", "$S", tableInfo.getTableName()).build());
        }
        String replace = tableInfo.getRemarks();
        if (tableInfo.getRemarks() != null) {
            replace = replace.replace("\n", "");
            classBuilder.addAnnotation(AnnotationSpec.builder(ApiModel.class).addMember("description", "$S", replace).build());
            classBuilder.addJavadoc(tableInfo.getRemarks());
        }
  1. swagger注解
//字段
            FieldSpec.Builder filedBuilder = FieldSpec.builder(className, !lowerFirstCase ? file.getProperty() : lowerFirstCase(file.getProperty()), Modifier.PRIVATE)
                    .addAnnotation(AnnotationSpec.builder(ApiModelProperty.class)
                            .addMember("value", "$S", remarks.trim()).build());
  1. 排除字段
                    if (file.isExits()) {
                    filedBuilder.addAnnotation(AnnotationSpec.builder(TableField.class).addMember("value", "$S", file.getColumn()).build());
                } else {
                    if (file.getTable() != null && !onlyMp) {
                        //老框架帶入
                        AnnotationSpec.Builder relationSpec = AnnotationSpec.builder(ClassName.get("com.caijai.base.anno", "Relation"))
                                .addMember("table", file.getTable())
                                .addMember("value", file.getValue())
                                .addMember("ref", file.getRef())
                                .addMember("show", file.getShow());
                        filedBuilder.addAnnotation(relationSpec.build());
                    }
                    filedBuilder.addAnnotation(AnnotationSpec.builder(TableField.class).addMember("exist", "false").build());
                }
  1. 具體的屬性字段,要判斷泛型,基礎數據類型,數組只考慮了字符串數組,還有枚舉
            //查找是否是導入的類
            Optional<String> first = tableInfo.getImportPackage().stream().filter(s -> s.contains(finalClassNam)).findFirst();
            TypeName className;
            if (first.isPresent()) {
                String className1 = file.getClassName();
                //如果是泛型就取出真正的類型
                if (className1.contains("<")) {
                    int start = file.getClassName().indexOf("<") + 1;
                    int end = file.getClassName().indexOf(">");
                    className1 = file.getClassName().substring(start, end);
                }
                String replace1 = first.get().replace("." + className1, "");
                if (!replace1.contains("enum") && !replace1.contains("java") && changePackage) {
                    //交換包名(我起的不一樣所有要改成我自己的,如果是false就是原包名)
                    String[] split = replace1.replace("com.caijai.", "").split("\\.");
                    String s = split[0];
                    String s1 = split[1];
                    StringBuilder s3 = new StringBuilder();
                    if (split.length > 2) {
                        for (int i = 2; i < split.length; i++) {
                            s3.append(".").append(split[i]);
                        }
                    }
                    replace1 = newPackage + "." + s1 + "." + s + s3.toString();
                }
                //如果是集合 加上泛型   不是就正常類型(包括導入的類型)
                if (file.getClassName().contains("List")) {
                    className = ClassName.get(replace1, finalClassNam);
                    ClassName name = ClassName.get("java.util", "List");
                    className = ParameterizedTypeName.get(name, className);
                } else {
                    className = ClassName.get(replace1, file.getClassName());
                }
            } else {
                // java自帶的不需要導包的類型
                //集合
                if (file.getClassName().contains("List")) {
                    int start = file.getClassName().indexOf("<") + 1;
                    int end = file.getClassName().indexOf(">");
                    String s2 = file.getClassName().substring(start, end);
                    first = tableInfo.getImportPackage().stream().filter(a -> a.contains(s2)).findFirst();
                    String s3 = first.orElse("");
                    ClassName name = ClassName.get("java.util", "List");
                    className = ParameterizedTypeName.get(name, ClassName.get(s3, s2));
                } else {
                    //基礎數據類型
                    switch (file.getClassName()) {
                        case "int":
                        case "float":
                        case "short":
                        case "double":
                        case "long":
                        case "byte":
                        case "boolean":
                        case "char":
                        case "String[]":
                            //可能出現 String數組 className就是 String[]
                            className = ClassName.get("", file.getClassName().replace("[]", ""));
                            break;
                        default:
                            try {
                                className = ClassName.get("java.lang", file.getClassName().replace("[]", ""));
                                //加載下這個類,看是不是報錯 如果是就當做泛型處理
                                Class.forName("java.lang." + file.getClassName());
                            } catch (ClassNotFoundException e) {
                                className = ClassName.get(enums, file.getClassName());
                            }
                            break;
                    }
                }
            }

完整代碼


import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.squareup.javapoet.*;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;

import javax.lang.model.element.Modifier;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

class TaskApplicationTests {
    static final String from = "E:\\java_project\\ims-parent";
    //    static final String rootPath = "E:\\java_project\\ims-parent";
    static final String rootPath = "E:\\java_project\\sunad\\comm\\src\\main\\java";

    static final String baseTablePack = "com.finish.comm.entity.base";
    static final String newPackage = "com.finish.comm";
    static final String enums = "com.finish.comm.enums";
    static final List<String> baseFiled = Arrays.asList("createdBy", "ts", "dr", "id", "createdOn", "modifiedBy", "modifiedOn");
    static final List<String> exclude = Arrays.asList("HTTPURL", "U9BaseData", "BaseData", "BaseJSON", "ListenerEvent", "CorpVO");
    static final List<String> createExclude = Arrays.asList("BaseTable");
    static final boolean onlyMp = true;
    static final boolean changePackage = true;
    //屬性首字母是否轉小寫
    static final boolean lowerFirstCase = true;
    static final List<TableInfo> tableInfoList = new ArrayList<>();

    public static void main(String[] args) throws Exception {
        List<File> files = getFiles(from);
        for (File file : files) {
//            if (!file.getName().equals("TransferFormVO.java")) {
//                continue;
//            }
            TableInfo tableInfo = createTableInfo(file);
            if (tableInfo == null || tableInfo.getClassName() == null || createExclude.contains(tableInfo.getClassName())) {
                continue;
            }
            tableInfoList.add(tableInfo);
        }
        for (TableInfo tableInfo : tableInfoList) {
            TypeSpec typeSpec = createFile(tableInfo);
            File file1 = new File(rootPath);
            if (!file1.exists()) {
                file1.mkdirs();
            }
            String packag = tableInfo.getPackag();
            if (changePackage) {
                JavaFile.builder(packag.replace(".entity", "").replace("com.caijai", "com.finish.comm.entity"), typeSpec).build().writeTo(file1);
            } else {
                JavaFile.builder(packag, typeSpec).build().writeTo(file1);
            }
        }
    }

    private static List<File> getFiles(String path) {
        List<File> files = new ArrayList<>();
        File file = new File(path);
        if (!file.exists()) {
            return files;
        }
        if (file.isFile()) {
            files.add(file);
            return files;
        }
        File[] listFiles = file.listFiles();
        for (File listFile : listFiles) {
            if (listFile.getName().equals("utils")) {
                continue;
            }
            if (listFile.isDirectory()) {
                files.addAll(getFiles(listFile.getAbsolutePath()));
            } else {
                if (listFile.getAbsolutePath().contains("entity")) {
                    files.add(listFile);
                }
            }
        }
        return files;
    }

    private static TypeSpec createFile(TableInfo tableInfo) {
        TypeSpec.Builder classBuilder = TypeSpec.classBuilder(tableInfo.getClassName()).addModifiers(Modifier.PUBLIC);
        classBuilder.addAnnotation(Data.class);
        TableInfo info = null;
        if (tableInfo.getSupper() != null) {
            classBuilder.addAnnotation(AnnotationSpec.builder(EqualsAndHashCode.class).addMember("callSuper", "true").build());
            Optional<String> first = tableInfo.getImportPackage().stream().filter(s -> s.contains(tableInfo.getSupper())).findFirst();
            info = tableInfoList.stream().filter(s -> {
                        boolean supper = s.getClassName().equals(tableInfo.getSupper());
                        boolean equals = s.getPackag().equals(first.orElse("").replace("." + s.getClassName(), ""));
                        return equals && supper;
                    }
            ).findFirst().orElse(null);
            if (first.isPresent()) {
                String replace1 = first.get().replace("." + tableInfo.getSupper(), "");
                if (changePackage) {
                    //交換包名(我起的不一樣所有要改成我自己的,如果是false就是原包名)
                    String[] split = replace1.replace("com.caijai.", "").split("\\.");
                    String s = split[0];
                    String s1 = split[1];
                    StringBuilder s3 = new StringBuilder();
                    if (split.length > 2) {
                        for (int i = 2; i < split.length; i++) {
                            s3.append(".").append(split[i]);
                        }
                    }
                    replace1 = newPackage + "." + s1 + "." + s + s3.toString();
                }
                classBuilder.superclass(ClassName.get(replace1, tableInfo.getSupper()));
            }
        }
        //添加類相關注解
        if (tableInfo.getTableName() != null) {
            if (!onlyMp) {
                AnnotationSpec tableSpec = AnnotationSpec.builder(ClassName.get("com.caijai.base.anno", "Table")).addMember("name", "$S", tableInfo.getTableName()).build();
                classBuilder.addAnnotation(tableSpec);
            }
            classBuilder.addAnnotation(AnnotationSpec.builder(TableName.class).addMember("value", "$S", tableInfo.getTableName()).build());
        }
        String replace = tableInfo.getRemarks();
        if (tableInfo.getRemarks() != null) {
            replace = replace.replace("\n", "");
            classBuilder.addAnnotation(AnnotationSpec.builder(ApiModel.class).addMember("description", "$S", replace).build());
            classBuilder.addJavadoc(tableInfo.getRemarks());
        }
        for (TableFiled file : tableInfo.getFiles()) {
            if (info != null) {
                if (info.getFiles().stream().filter(s -> s.getProperty() != null).anyMatch(s -> s.getProperty().equals(file.getProperty()))) {
                    continue;
                }
            }
            if (file.isBaseExits() || file.getProperty() == null) {
                continue;
            }
            if (file.getRemarks() == null) {
                file.setRemarks("");
            }
            String classNam = file.getClassName();
            if (classNam.contains("<")) {
                int start = file.getClassName().indexOf("<") + 1;
                int end = file.getClassName().indexOf(">");
                classNam = classNam.substring(start, end);
            }
            String finalClassNam = classNam;
            //查找是否是導入的類
            Optional<String> first = tableInfo.getImportPackage().stream().filter(s -> s.contains(finalClassNam)).findFirst();
            TypeName className;
            if (first.isPresent()) {
                String className1 = file.getClassName();
                //如果是泛型就取出真正的類型
                if (className1.contains("<")) {
                    int start = file.getClassName().indexOf("<") + 1;
                    int end = file.getClassName().indexOf(">");
                    className1 = file.getClassName().substring(start, end);
                }
                String replace1 = first.get().replace("." + className1, "");
                if (!replace1.contains("enum") && !replace1.contains("java") && changePackage) {
                    //交換包名(我起的不一樣所有要改成我自己的,如果是false就是原包名)
                    String[] split = replace1.replace("com.caijai.", "").split("\\.");
                    String s = split[0];
                    String s1 = split[1];
                    StringBuilder s3 = new StringBuilder();
                    if (split.length > 2) {
                        for (int i = 2; i < split.length; i++) {
                            s3.append(".").append(split[i]);
                        }
                    }
                    replace1 = newPackage + "." + s1 + "." + s + s3.toString();
                }
                //如果是集合 加上泛型   不是就正常類型(包括導入的類型)
                if (file.getClassName().contains("List")) {
                    className = ClassName.get(replace1, finalClassNam);
                    ClassName name = ClassName.get("java.util", "List");
                    className = ParameterizedTypeName.get(name, className);
                } else {
                    className = ClassName.get(replace1, file.getClassName());
                }
            } else {
                // java自帶的不需要導包的類型
                //集合
                if (file.getClassName().contains("List")) {
                    int start = file.getClassName().indexOf("<") + 1;
                    int end = file.getClassName().indexOf(">");
                    String s2 = file.getClassName().substring(start, end);
                    first = tableInfo.getImportPackage().stream().filter(a -> a.contains(s2)).findFirst();
                    String s3 = first.orElse("");
                    ClassName name = ClassName.get("java.util", "List");
                    className = ParameterizedTypeName.get(name, ClassName.get(s3, s2));
                } else {
                    //基礎數據類型
                    switch (file.getClassName()) {
                        case "int":
                        case "float":
                        case "short":
                        case "double":
                        case "long":
                        case "byte":
                        case "boolean":
                        case "char":
                        case "String[]":
                            //可能出現 String數組 className就是 String[]
                            className = ClassName.get("", file.getClassName().replace("[]", ""));
                            break;
                        default:
                            try {
                                className = ClassName.get("java.lang", file.getClassName().replace("[]", ""));
                                //加載下這個類,看是不是報錯 如果是就當做泛型處理
                                Class.forName("java.lang." + file.getClassName());
                            } catch (ClassNotFoundException e) {
                                className = ClassName.get(enums, file.getClassName());
                            }
                            break;
                    }
                }
            }
            //備注
            String remarks = file.getRemarks().replace("\n", "");
            if (remarks.contains("@Column")) {
                remarks = remarks.substring(0, remarks.indexOf("@Column"));
            }
            if (remarks.startsWith("*")) {
                remarks = remarks.substring(1);
            }
            //字段
            FieldSpec.Builder filedBuilder = FieldSpec.builder(className, !lowerFirstCase ? file.getProperty() : lowerFirstCase(file.getProperty()), Modifier.PRIVATE)
                    .addAnnotation(AnnotationSpec.builder(ApiModelProperty.class)
                            .addMember("value", "$S", remarks.trim()).build());
            if (tableInfo.getTableName() != null) {
                if (!onlyMp) {
                    //老框架帶入
                    AnnotationSpec.Builder columnSpec = AnnotationSpec.builder(ClassName.get("com.caijai.base.anno", "Column"))
                            .addMember("name", "$S", file.getColumn());
                    //舊框架封裝的數據庫操作
                    if (file.isReadonly()) {
                        columnSpec.addMember("readonly", "true");
                    }
                    if (file.isByInt()) {
                        columnSpec.addMember("byInt", "true");
                    }
                    if (file.isByDouble()) {
                        columnSpec.addMember("byDouble", "true");
                    }
                    if (file.isPrimary()) {
                        columnSpec.addMember("primary", "true");
                    }
                    if (file.getSort() != null) {
                        String[] s1 = file.getSort().split("\\.");
                        Optional<String> optional = tableInfo.getImportPackage().stream().filter(s -> s.contains(s1[0])).findFirst();
                        optional.ifPresent(s -> columnSpec.addMember("sort", s + "." + s1[1]));
                    }
                    if (file.getColumn() != null) {
                        filedBuilder.addAnnotation(columnSpec.build());
                    }
                }
                if (file.isExits()) {
                    filedBuilder.addAnnotation(AnnotationSpec.builder(TableField.class).addMember("value", "$S", file.getColumn()).build());
                } else {
                    if (file.getTable() != null && !onlyMp) {
                        //老框架帶入
                        AnnotationSpec.Builder relationSpec = AnnotationSpec.builder(ClassName.get("com.caijai.base.anno", "Relation"))
                                .addMember("table", file.getTable())
                                .addMember("value", file.getValue())
                                .addMember("ref", file.getRef())
                                .addMember("show", file.getShow());
                        filedBuilder.addAnnotation(relationSpec.build());
                    }
                    filedBuilder.addAnnotation(AnnotationSpec.builder(TableField.class).addMember("exist", "false").build());
                }
            }
            classBuilder.addField(filedBuilder.build());
        }
        return classBuilder.build();
    }

    public static TableInfo createTableInfo(File file) throws Exception {
        System.out.println(file.getName());
        BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
        String line = null;
        TableInfo tableInfo = new TableInfo();
        try {
            while ((line = bufferedReader.readLine()) != null) {
                line = line.trim();
                String finalLine = line;
                if (exclude.stream().anyMatch(finalLine::contains)) {
                    return null;
                }
                //包名
                if (line.startsWith("package")) {
                    tableInfo.setPackag(line.replace("package", "").replace(";", "").trim());
                }
                //導入的類
                if (line.startsWith("import")) {
                    String anImport = line.replace("import", "").replace(";", "").trim();
                    if (!anImport.isEmpty() && anImport.contains("sysenum") && !enums.isEmpty()) {
                        anImport = anImport.replace("com.caijai.base.sysenum", enums);
                    }
                    tableInfo.getImportPackage().add(anImport);
                }
                //排除靜態,get set方法
                if (line.isEmpty() || line.contains("static") || line.contains("()") || line.contains("void")) {
                    continue;
                }
                //獲取類的信息
                if (line.contains("public class ")) {
                    String className;
                    if (line.contains("extends")) {
                        if (line.split("extends").length > 0) {
                            tableInfo.setSupper(line.substring(line.indexOf("extends"), line.indexOf("{")).replace("extends", "").trim());
                            if (tableInfo.getSupper().equals("BaseEntity")) {
                                tableInfo.setSupper("BaseTable");
                                tableInfo.getImportPackage().add("com.caijai.base.entity.BaseTable");
                            }
                        }
                        className = line.substring(line.indexOf("class"), line.indexOf("extends")).replace("class", "").trim();
                    } else {
                        className = line.substring(line.indexOf("class"), line.indexOf("{")).replace("class", "").trim();
                    }
                    tableInfo.setClassName(className);
                    continue;
                } else if (line.startsWith("@Table")) {
                    //獲取表名
                    tableInfo.setTableName(line.substring(line.indexOf("\""), line.indexOf("\")")).replace("\"", ""));
                    continue;
                }
                if (tableInfo.getClassName() == null) {
                    //獲取類注釋
                    if ((line.startsWith("http://") || line.startsWith("*") || line.startsWith("/**")) && !line.startsWith("*/")) {
                        if (line.equals("*")) {
                            tableInfo.setRemarks(tableInfo.getRemarks() + "\n");
                            continue;
                        }
                        if (tableInfo.getRemarks() != null) {
                            tableInfo.setRemarks(tableInfo.getRemarks() + "\n" + line.replace("* ", ""));
                        } else {
                            tableInfo.setRemarks(line.replace("* ", ""));
                        }
                    }
                } else {
                    List<TableFiled> files = tableInfo.getFiles();
                    TableFiled filed = new TableFiled();
                    if (files.isEmpty()) {
                        files.add(filed);
                    }
                    TableFiled tableFiled = files.get(files.size() - 1);
                    //判斷該字段到底有沒有 如果沒有就用之前的,否則就添加新的
                    if (tableFiled.getProperty() != null) {
                        files.add(filed);
                    }
                    filed = files.get(files.size() - 1);
                    //字段注釋
                    if ((line.startsWith("http://") || line.startsWith("*") || line.startsWith("/**")) && !line.startsWith("*/")) {
                        if (line.equals("*")) {
                            filed.setRemarks(filed.getRemarks() + "\n");
                            continue;
                        }
                        if (filed.getRemarks() != null) {
                            filed.setRemarks(filed.getRemarks() + "\n" + line.replace("* ", ""));
                        } else {
                            filed.setRemarks(line.replace("* ", "").replace("/*", "").replace("*/", ""));
                        }
                    } else if (line.startsWith("@Column")) {
                        filed.setExits(true);
                        //老框架封裝的數據庫 保留
                        String[] primaries = line.split("=");
                        for (int i = 0; i < primaries.length; i++) {
                            String primary = primaries[i].trim();
                            if (primary.contains("primary")) {
                                filed.setPrimary(Boolean.parseBoolean(primaries[i + 1].trim().replace(")", "")));
                            } else if (primary.contains("readonly")) {
                                filed.setExits(false);
                                filed.setReadonly(Boolean.parseBoolean(primaries[i + 1].trim().replace(")", "")));
                            } else if (primary.contains("byInt")) {
                                filed.setByInt(Boolean.parseBoolean(primaries[i + 1].trim().replace(")", "")));
                            } else if (primary.contains("byDouble")) {
                                filed.setByDouble(Boolean.parseBoolean(primaries[i + 1].trim().replace(")", "")));
                            } else if (primary.contains("sort ")) {
                                filed.setSort(primaries[i + 1].trim().replace(")", ""));
                            }
                        }
                        //獲取數據庫對應的字段名
                        int i = line.indexOf("\",");
                        if (i != -1) {
                            filed.setColumn(line.substring(line.indexOf("\"") + 1, i).replace("\"", "").trim());
                        } else if ((i = line.indexOf("\")")) != -1) {
                            i = line.indexOf("\")");
                            filed.setColumn(line.substring(line.indexOf("\"") + 1, i).replace("\"", "").trim());
                        } else if ((i = line.indexOf("\" ,")) != -1) {
                            filed.setColumn(line.substring(line.indexOf("\"") + 1, i).replace("\"", "").trim());
                        }
                    } else if (line.startsWith("@Relation")) {
                        //獲取舊框架 關聯查詢字段
                        String[] split = line.split("=");
                        for (int i = 0; i < split.length; i++) {
                            String s = split[i].trim();
                            if (s.contains("table")) {
                                filed.setTable(split[i + 1].trim().replace(")", "").split(",")[0]);
                            } else if (s.contains("ref")) {
                                filed.setRef(split[i + 1].trim().replace(")", "").split(",")[0]);
                            } else if (s.contains("value")) {
                                filed.setValue(split[i + 1].trim().replace(")", "").split(",")[0]);
                            } else if (s.contains("show")) {
                                filed.setShow(split[i + 1].trim().replace(")", "").split(",")[0]);
                            }
                        }
                        filed.setJoinTable(line.replace("table", "表名").replace("value", "關聯表字段").replace("ref", "當前表字段").replace("show", "查詢的字段"));
                    } else if ((line.startsWith("private") || line.startsWith("public")) && !line.contains("class")) {
                        // 修飾符 類型名稱 字段名稱 備注
                        line = line.replace("  ", " ").replace(" ;", ";");
                        String[] s = line.split(" ");
                        filed.setModifier(s[0].trim());
                        filed.setClassName(s[1].trim());
                        filed.setProperty(s[2].substring(0, s[2].indexOf(";")).replace("\t", ""));
                        String[] split = line.split("http://");
                        if (split.length > 1) {
                            filed.setRemarks(split[1]);
                        }
                    }
                    if (tableInfo.getSupper() != null) {
                        TableFiled finalFiled = filed;
                        //basetable是不是已存在
                        filed.setBaseExits(baseFiled.stream().anyMatch(s -> s.equalsIgnoreCase(finalFiled.getProperty()) || s.equalsIgnoreCase(finalFiled.getColumn())));
                    }
                    //去掉備注的雙斜杠
                    if (filed.getRemarks() != null)
                        filed.setRemarks(filed.getRemarks().replace("http://", ""));
                }
            }

        } catch (Exception e) {
            System.out.println(line);
            System.out.println(file.getName());
            throw e;
        }
        if (tableInfo.getRemarks() != null)
            tableInfo.setRemarks(tableInfo.getRemarks().replace("/**", ""));
        return tableInfo;
    }


    public static String lowerFirstCase(String s) {
        if (Character.isLowerCase(s.charAt(0)))
            return s;
        else
            return Character.toLowerCase(s.charAt(0)) + s.substring(1);
    }

    @Data
    static class TableInfo {
        private String className;
        private String supper;
        private String packag;
        private String remarks;
        private String tableName;
        private List<String> importPackage = new ArrayList<>();
        private List<TableFiled> files = new ArrayList<>();
    }

    @Data
    static class TableFiled {
        //字段名
        private String column;
        //屬性名
        private String property;
        private String remarks;
        //類型名稱
        private String className;
        //數據庫是否存在
        private boolean exits;

        private boolean readonly;
        private String sort;
        private boolean byInt;
        private boolean byDouble;
        private boolean primary;

        private String table;
        private String value;
        private String show;
        private String ref;

        //關聯的表
        private String joinTable;
        //base是否存在
        private boolean baseExits;
        private String modifier;
    }
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。