本文只是拋磚引玉谣殊,不能百分百確認(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
接下來開始解析文件
- 獲取所有目標(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這個方法
- 獲取包名达布,導(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;
}
- 獲取類信息直奋,獲取舊框架的注解,獲取類的注釋
//獲取類的信息
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("* ", ""));
}
}
}
- 如果類的信息已存在施禾,那么接下來讀的都是字段信息
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
- 如果該類有繼承就把繼承的類找出來邮绿,不生成相同字段
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());
}
- 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());
- 排除字段
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());
}
- 具體的屬性字段,要判斷泛型船逮,基礎(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;
}
}