重構(gòu)舊項目實體類

本文只是拋磚引玉谣殊,不能百分百確認(rèn)沒有錯誤

我們公司使用了最開始的人自己封裝的數(shù)據(jù)庫操作王凑,但是效率過低,只是用了mybatis薄腻,現(xiàn)在想改成mybatis-plus,之前也沒有swagger 現(xiàn)在也想使用届案,都是生成的get和set方法庵楷,這改成lombok,但是數(shù)據(jù)庫里面并沒有注釋楣颠,只是在代碼中寫了注釋尽纽,這里介紹下我重構(gòu)的思路,和自己寫的樣本

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


image.png

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

image.png

代碼里面有很多沒有格式化童漩,導(dǎo)致取字符串的時候?qū)ψ址僮骱芏?br> 再截一個圖 還存在 這種注釋

image.png

沒有縮進的也有

image.png

接下來開始解析文件

  1. 獲取所有目標(biāo)文件楞泼,這個就不用貼代碼了,使用字符流讀取文件(最后會給所有代碼)
        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. 獲取包名达布,導(dǎo)報舱权,排除靜態(tài)溉贿,get,set方法
                //包名
                if (line.startsWith("package")) {
                    tableInfo.setPackag(line.replace("package", "").replace(";", "").trim());
                }
                //導(dǎo)入的類
                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);
                }
                //排除靜態(tài)豆拨,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);
                        //老框架封裝的數(shù)據(jù)庫 保留
                        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(")", ""));
                            }
                        }
                        //獲取數(shù)據(jù)庫對應(yīng)的字段名
                        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")) {
                        //獲取舊框架 關(guān)聯(lián)查詢字段
                        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", "關(guān)聯(lián)表字段").replace("ref", "當(dāng)前表字段").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]);
                        }
                    }

獲取類的數(shù)據(jù),接下來就開始生成文件弥搞,使用的是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. 具體的屬性字段,要判斷泛型船逮,基礎(chǔ)數(shù)據(jù)類型顾腊,數(shù)組只考慮了字符串?dāng)?shù)組,還有枚舉
            //查找是否是導(dǎo)入的類
            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();
                }
                //如果是集合 加上泛型   不是就正常類型(包括導(dǎo)入的類型)
                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自帶的不需要導(dǎo)包的類型
                //集合
                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 {
                    //基礎(chǔ)數(shù)據(jù)類型
                    switch (file.getClassName()) {
                        case "int":
                        case "float":
                        case "short":
                        case "double":
                        case "long":
                        case "byte":
                        case "boolean":
                        case "char":
                        case "String[]":
                            //可能出現(xiàn) String數(shù)組 className就是 String[]
                            className = ClassName.get("", file.getClassName().replace("[]", ""));
                            break;
                        default:
                            try {
                                className = ClassName.get("java.lang", file.getClassName().replace("[]", ""));
                                //加載下這個類杂靶,看是不是報錯 如果是就當(dāng)做泛型處理
                                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;
    //屬性首字母是否轉(zhuǎn)小寫
    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()));
            }
        }
        //添加類相關(guān)注解
        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;
            //查找是否是導(dǎo)入的類
            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();
                }
                //如果是集合 加上泛型   不是就正常類型(包括導(dǎo)入的類型)
                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自帶的不需要導(dǎo)包的類型
                //集合
                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 {
                    //基礎(chǔ)數(shù)據(jù)類型
                    switch (file.getClassName()) {
                        case "int":
                        case "float":
                        case "short":
                        case "double":
                        case "long":
                        case "byte":
                        case "boolean":
                        case "char":
                        case "String[]":
                            //可能出現(xiàn) String數(shù)組 className就是 String[]
                            className = ClassName.get("", file.getClassName().replace("[]", ""));
                            break;
                        default:
                            try {
                                className = ClassName.get("java.lang", file.getClassName().replace("[]", ""));
                                //加載下這個類吗垮,看是不是報錯 如果是就當(dāng)做泛型處理
                                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());
                    //舊框架封裝的數(shù)據(jù)庫操作
                    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());
                }
                //導(dǎo)入的類
                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);
                }
                //排除靜態(tài),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);
                        //老框架封裝的數(shù)據(jù)庫 保留
                        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(")", ""));
                            }
                        }
                        //獲取數(shù)據(jù)庫對應(yīng)的字段名
                        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")) {
                        //獲取舊框架 關(guān)聯(lián)查詢字段
                        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", "關(guān)聯(lián)表字段").replace("ref", "當(dāng)前表字段").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;
        //數(shù)據(jù)庫是否存在
        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;

        //關(guān)聯(lián)的表
        private String joinTable;
        //base是否存在
        private boolean baseExits;
        private String modifier;
    }
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末烁登,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蔚舀,更是在濱河造成了極大的恐慌饵沧,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蝗敢,死亡現(xiàn)場離奇詭異捷泞,居然都是意外死亡足删,警方通過查閱死者的電腦和手機寿谴,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來失受,“玉大人讶泰,你說我怎么就攤上這事》鞯剑” “怎么了痪署?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長兄旬。 經(jīng)常有香客問我狼犯,道長,這世上最難降的妖魔是什么领铐? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任悯森,我火速辦了婚禮,結(jié)果婚禮上绪撵,老公的妹妹穿的比我還像新娘瓢姻。我一直安慰自己,他們只是感情好音诈,可當(dāng)我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布幻碱。 她就那樣靜靜地躺著绎狭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪褥傍。 梳的紋絲不亂的頭發(fā)上儡嘶,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天,我揣著相機與錄音恍风,去河邊找鬼社付。 笑死,一個胖子當(dāng)著我的面吹牛邻耕,可吹牛的內(nèi)容都是我干的鸥咖。 我是一名探鬼主播,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼兄世,長吁一口氣:“原來是場噩夢啊……” “哼啼辣!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起御滩,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤鸥拧,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后削解,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體富弦,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年氛驮,在試婚紗的時候發(fā)現(xiàn)自己被綠了腕柜。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡矫废,死狀恐怖盏缤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情蓖扑,我是刑警寧澤唉铜,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站律杠,受9級特大地震影響潭流,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜柜去,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一灰嫉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧诡蜓,春花似錦熬甫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瞻颂。三九已至,卻和暖如春郑象,著一層夾襖步出監(jiān)牢的瞬間贡这,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工厂榛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留盖矫,地道東北人。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓击奶,卻偏偏與公主長得像辈双,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子柜砾,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,691評論 2 361