本文只是抛砖引玉,不能百分百确认没有错误
我们公司使用了最开始的人自己封装的数据库操作,但是效率过低,只是用了mybatis,现在想改成mybatis-plus,之前也没有swagger 现在也想使用,都是生成的get和set方法,这改成lombok,但是数据库里面并没有注释,只是在代码中写了注释,这里介绍下我重构的思路,和自己写的样本
给大家截一个图 注解都是自定义的
生成后的效果图(onlyMp = true 表示不需要远来封装的注解)
代码里面有很多没有格式化,导致取字符串的时候对字符串操作很多
再截一个图 还存在 这种注释
没有缩进的也有
接下来开始解析文件
- 获取所有目标文件,这个就不用贴代码了,使用字符流读取文件(最后会给所有代码)
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这个方法
- 获取包名,导报,排除静态,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;
}
- 获取类信息,获取旧框架的注解,获取类的注释
//获取类的信息
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("//") || 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("//") || 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("//");
if (split.length > 1) {
filed.setRemarks(split[1]);
}
}
获取类的数据,接下来就开始生成文件,使用的是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());
}
- 具体的属性字段,要判断泛型,基础数据类型,数组只考虑了字符串数组,还有枚举
//查找是否是导入的类
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("//") || 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("//") || 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("//");
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("//", ""));
}
}
} 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;
}
}