一键代码生成 java 实现
enum CodeBuildEnum {
BO_START("build BO start"),
FORM_TO_BO_START("build Form to BO start"),
VO_START("build VO start"),
FORM_START("build form start"),
MODEL_VO_START("build MODEL VO start"),
SAVE_BO_TO_PO_START("save BO to PO start"),
UPDATE_BO_TO_PO_START("update BO to PO start"),;
private String des;
CodeBuildEnum(String des) {
this.des = des;
}
public String getDes() {
return des;
}
}
public class CurdUtil {
public static void main(String[] args) throws Exception {
String project = "项目名称";
String model = "model名";
Class> clazz = 实体类.class;
String tableNameCn = "表名";
String author = "作者";
CurdUtil c = new CurdUtil();
c.init(tableNameCn, clazz, project, author, model);
c.buildCode();
}
/**
* 处理 CodeBuildEnum.des 标记的模板文本
* 如果代码模板里增加了标记锚点(CodeBuildEnum.des),在下面增加处理方法即可
*
* @param s 单行模板文本
* @return 构造后的代码文本
*/
private String generatorBoCode(String s) {
CodeBuildEnum codeBuildEnum = getCodeBuildEnum(s);
if (codeBuildEnum == null) return "";
switch (codeBuildEnum) {
case BO_START:
return buildBoStart();
case VO_START:
return buildVoStart();
case FORM_START:
return buildFormStart();
case MODEL_VO_START:
return buildModelVoStart();
case FORM_TO_BO_START:
return buildFormToBoStart();
case SAVE_BO_TO_PO_START:
return buildSaveBoToPoStart();
case UPDATE_BO_TO_PO_START:
return buildSaveBoToPoStart();
}
return "";
}
/**
* 处理模板文本
* 替换文本中所有 $开头标记的字段
* 如果代码模板里增加了标记字段,在下面增加一行处理方法即可
*
* @param s 单行模板文本
* @return 替换处理后的代码文本
*/
private String buildLine(String s) {
if (s == null) return "";
s = StringUtils.replaceAll(s, "\\$NAME", name);
s = StringUtils.replaceAll(s, "\\$CN_NAME", cnName);
s = StringUtils.replaceAll(s, "\\$LOWER_NAME", lowerCamName);
s = StringUtils.replaceAll(s, "\\$LOWER_ALL_NAME", lowerName);
s = StringUtils.replaceAll(s, "\\$UP_NAME", upName);
s = StringUtils.replaceAll(s, "\\$UP_SNAKE_NAME", upSnakeName);
s = StringUtils.replaceAll(s, "\\$AUTHOR", author);
s = StringUtils.replaceAll(s, "\\$FILE_CREATE_DATE", createDate);
s = StringUtils.replaceAll(s, "\\$PROJECT_MODEL", model);
return s;
}
/**
* 构造代码文件
*/
public void buildCode() {
try {
buildService();
buildServiceImpl();
buildServicePojo();
buildController();
buildForm();
buildModel();
} catch (IOException e) {
e.printStackTrace();
}
}
// do NOT modify
private String cnName;
private Class> clazz;
private String rootPath;
private String tmplPath;
private String tableName;
private CodeBuildEnum[] TEMP_CODE = CodeBuildEnum.values();
private String name;
private String lowerName;
private String lowerCamName;
private String upName;
private String controllerPath;
private String servicePath;
private String formPath;
private String modelVoPath;
private String author;
private String createDate;
private String upSnakeName;
private String model;
private List fieldNames;
private void init(String cnName, Class> clazz, String project, String author, String model) throws Exception {
this.author = author;
this.createDate = LocalDate.now().toString();
this.rootPath = new File(".").getCanonicalPath() + "/";
this.tmplPath = rootPath + project + "-common/src/test/resources/tmpl/";
this.cnName = cnName;
this.clazz = clazz;
this.tableName = clazz.getSimpleName();
this.name = StringUtils.removeFirst(tableName, "***名");
this.lowerName = name.toLowerCase();
this.lowerCamName = convertToLowerCam(name);
this.upName = name.toUpperCase();
this.upSnakeName = camelCovertToUpSnake(name);
this.model = model;
this.servicePath = rootPath + project + "-common/src/main/java/com/jiayu/***/common/service/"; //service 路径
this.controllerPath = rootPath + project + "-" + model + "/src/main/java/com/jiayu/***/" + model + "/controller/"; //controller 路径
this.formPath = rootPath + project + "-" + model + "/src/main/java/com/jiayu/***/" + model + "/form/"; // form 路径
this.modelVoPath = rootPath + project + "-" + model + "/src/main/java/com/jiayu/***/" + model + "/model/"; // modelVo 路径
this.fieldNames = buildFieldName();
}
private List buildFieldName() throws Exception {
List fieldNames = new ArrayList<>();
Constructor> constructor = clazz.getDeclaredConstructor();
Object o = constructor.newInstance();
Field[] fields = clazz.getFields();
String simpleName = clazz.getSimpleName();
for (Field field : fields) {
if (field.getName().equals(camelCovertToUpSnake(simpleName))) continue;
FieldName fieldName = new FieldName();
Object o1 = field.get(o);
TableField tb = (TableField) o1;
String name = tb.getName();
fieldName.UP_SNAKE_NAME = name;
String camelName = upSnakeToCamel(name);
fieldName.camelName = camelName;
fieldName.UpCameName = convertToUpCam(camelName);
fieldName.snake_name = name.toLowerCase();
fieldName.comment = tb.getComment();
fieldName.typeName = tb.getType().getSimpleName();
fieldNames.add(fieldName);
}
return fieldNames;
}
private void buildController() throws IOException {
String fileName = controllerPath + name + "Controller.java";
String tmplFile = "TmplController.txt";
stdFile(null, fileName, tmplFile);
}
private void buildForm() throws IOException {
String serviceChildPah = formPath + lowerName + "/";
String fileNameSave = serviceChildPah + "Save" + name + "Form.java";
String tmplFileSave = "TmplSaveForm.txt";
stdFile(serviceChildPah, fileNameSave, tmplFileSave);
String fileNameUpdate = serviceChildPah + "Update" + name + "Form.java";
String tmplFileUpdate = "TmplUpdateForm.txt";
stdFile(serviceChildPah, fileNameUpdate, tmplFileUpdate);
}
private void buildModel() throws IOException {
String fileName = modelVoPath + name + "Vo.java";
String tmplFile = "TmplModelVo.txt";
stdFile(null, fileName, tmplFile);
}
private void buildService() throws IOException {
String serviceChildPah = servicePath + lowerName + "/";
String fileName = serviceChildPah + name + "Service.java";
String tmplFile = "TmplService.txt";
stdFile(serviceChildPah, fileName, tmplFile);
}
private void buildServiceImpl() throws IOException {
String serviceChildPah = servicePath + lowerName + "/impl/";
String fileName = serviceChildPah + name + "ServiceImpl.java";
String tmplFile = "TmplServiceImpl.txt";
stdFile(serviceChildPah, fileName, tmplFile);
}
private void buildServicePojo() throws IOException {
String serviceChildPah = servicePath + lowerName + "/pojo/";
String fileNameSave = serviceChildPah + name + "SaveBo.java";
String tmplFileSave = "TmplSaveBo.txt";
stdFile(serviceChildPah, fileNameSave, tmplFileSave);
String fileNameUpdate = serviceChildPah + name + "UpdateBo.java";
String tmplFileUpdate = "TmplUpdateBo.txt";
stdFile(serviceChildPah, fileNameUpdate, tmplFileUpdate);
}
private void stdFile(String childPath, String fileName, String tmplFile) throws IOException {
if (StringUtils.isNotBlank(childPath)) {
File path = new File(childPath);
if (!path.exists()) {
path.mkdir();
System.out.println("===============" + childPath + "\t\t 新建成功====================");
}
}
File file = new File(fileName);
if (file.exists()) {
System.out.println("===============" + fileName + "\t\t 已经存在====================");
return;
}
FileWriter fileWriter = new FileWriter(fileName);
List template = Files.readAllLines(Paths.get(tmplPath + tmplFile));
for (String s : template) {
if (needGeneratorBoCode(s)) {
fileWriter.append(generatorBoCode(s)).append("\n");
} else {
fileWriter.append(buildLine(s)).append("\n");
}
}
fileWriter.flush();
fileWriter.close();
System.out.println("====================================================================\n");
System.out.println("成功 build \t" + fileName + "\n");
System.out.println("====================================================================\n\n");
}
private String buildSaveBoToPoStart() {
StringBuilder sb = new StringBuilder();
for (FieldName fieldName : fieldNames) {
String camelName = fieldName.camelName;
if (commonFormVerify(camelName)) {
continue;
}
sb.append(" if (bo.get").append(fieldName.UpCameName).append("() != null) po.set")
.append(fieldName.UpCameName)
.append("(bo.get")
.append(fieldName.UpCameName)
.append("());\n");
}
sb.append("\n");
return sb.toString();
}
private String buildFormToBoStart() {
StringBuilder sb = new StringBuilder();
for (FieldName fieldName : fieldNames) {
String camelName = fieldName.camelName;
if (commonFormVerify(camelName)) {
continue;
}
String typeName = fieldName.typeName;
String upCameName = fieldName.UpCameName;
String get = "form.get" + upCameName + "()";
sb.append(" ");
if ("Long".equalsIgnoreCase(typeName)) {
sb.append(typeName).append(" ").append(camelName).append(" = LongUtil.object(").append(get).append(");");
} else if ("Integer".equalsIgnoreCase(typeName)) {
sb.append(typeName).append(" ").append(camelName).append(" = IntegerUtil.object(").append(get).append(");");
} else if ("BigDecimal".equalsIgnoreCase(typeName)) {
sb.append(typeName).append(" ").append(camelName).append(" = DecimalUtil.object(").append(get).append(");");
} else if ("Boolean".equalsIgnoreCase(typeName)) {
sb.append(typeName).append(" ").append(camelName).append(" = BooleanUtils.toBoolean(").append(get).append(");");
} else {
sb.append(typeName).append(" ").append(camelName).append(" = ").append(get).append(";");
}
sb.append("\n");
sb.append(" if (")
.append(camelName)
.append(" == null) {\n")
.append(" result.setMessage(\"请填写 ")
.append(fieldName.comment)
.append(" \");\n return false;\n }\n");
sb.append(" bo.set")
.append(upCameName)
.append("(")
.append(camelName)
.append(");\n");
}
sb.append(" return true;\n");
return sb.toString();
}
private String buildVoStart() {
StringBuilder sb = new StringBuilder();
for (FieldName fieldName : fieldNames) {
String camelName = fieldName.camelName;
if (commonModelVoVerify(camelName)) {
continue;
}
sb.append(" vo.set")
.append(fieldName.UpCameName)
.append("(")
.append(typeToString(fieldName.typeName, fieldName.UpCameName))
.append(");\n");
}
sb.append("\n");
return sb.toString();
}
private String typeToString(String typeName, String upName) {
String get = "po.get" + upName + "()";
if ("String".equalsIgnoreCase(typeName)) {
return get;
} else if ("BigDecimal".equalsIgnoreCase(upName)) {
return "(DecimalUtils.string(" + get + ", 2))";
}
return "Objects.toString(" + get + ")";
}
private String buildFormStart() {
StringBuilder sb = new StringBuilder("");
List fieldNames = this.fieldNames.stream().filter(filedName -> !commonFormVerify(filedName.camelName)).collect(Collectors.toList());
for (FieldName fieldName : fieldNames) {
String camelName = fieldName.camelName;
if (model.equals("front") && camelName.equalsIgnoreCase("userId")) continue;
buildFiledField(sb, camelName, fieldName.UpCameName, "String");
}
for (FieldName fieldName : fieldNames) {
String camelName = fieldName.camelName;
if (model.equals("front") && camelName.equalsIgnoreCase("userId")) continue;
buildFiledGetSet(sb, camelName, fieldName.UpCameName, "String");
}
buildFiledToString(sb, fieldNames);
return sb.toString();
}
private String buildModelVoStart() {
StringBuilder sb = new StringBuilder("");
List fieldNames = this.fieldNames.stream().filter(filedName -> !commonModelVoVerify(filedName.camelName)).collect(Collectors.toList());
for (FieldName fieldName : fieldNames) {
String camelName = fieldName.camelName;
if (model.equals("front") && camelName.equalsIgnoreCase("userId")) continue;
buildFiledField(sb, camelName, fieldName.UpCameName, "String");
}
for (FieldName fieldName : fieldNames) {
String camelName = fieldName.camelName;
if (model.equals("front") && camelName.equalsIgnoreCase("userId")) continue;
buildFiledGetSet(sb, camelName, fieldName.UpCameName, "String");
}
buildFiledToString(sb, fieldNames);
return sb.toString();
}
private String buildBoStart() {
StringBuilder sb = new StringBuilder("");
List fieldNames = this.fieldNames.stream().filter(filedName -> !commonFormVerify(filedName.camelName)).collect(Collectors.toList());
for (FieldName fieldName : fieldNames) {
String camelName = fieldName.camelName;
if (commonFormVerify(camelName)) {
continue;
}
buildFiledField(sb, camelName, fieldName.UpCameName, fieldName.typeName);
}
for (FieldName fieldName : fieldNames) {
String camelName = fieldName.camelName;
buildFiledGetSet(sb, camelName, fieldName.UpCameName, fieldName.typeName);
}
buildFiledToString(sb, fieldNames);
return sb.toString();
}
private boolean commonFormVerify(String camelName) {
return camelName.equalsIgnoreCase("serialVersionUID")
|| camelName.equalsIgnoreCase("id")
|| camelName.equalsIgnoreCase("createTime")
|| camelName.equalsIgnoreCase("modifyTime")
|| camelName.equalsIgnoreCase("isDeleted")
|| camelName.equalsIgnoreCase("logno");
}
private boolean commonModelVoVerify(String camelName) {
return camelName.equalsIgnoreCase("serialVersionUID")
|| camelName.equalsIgnoreCase("modifyTime")
|| camelName.equalsIgnoreCase("isDeleted")
|| camelName.equalsIgnoreCase("logno");
}
private void buildFiledGetSet(StringBuilder sb, String name, String upName, String typeName) {
sb.append(" public void set")
.append(upName)
.append("(")
.append(typeName)
.append(" ")
.append(name)
.append(") {\n this.")
.append(name)
.append(" = ")
.append(name)
.append(";\n")
.append(" }\n\n")
.append(" public ")
.append(typeName)
.append(" get")
.append(upName)
.append("() {\n return this.")
.append(name)
.append(";\n")
.append(" }\n\n")
;
}
private void buildFiledToString(StringBuilder sb, List fieldNames) {
sb.append("\n @Override\n")
.append(" public String toString() {\n")
.append(" return \"")
.append(name)
.append("{\" +\n");
int size = fieldNames.size();
for (int i = 0; i < size; i++) {
FieldName fieldName = fieldNames.get(i);
String camelName = fieldName.camelName;
sb.append(" \"");
if (i != 0) {
sb.append(", ");
}
sb.append(camelName).append("=");
boolean typeString = "String".equalsIgnoreCase(fieldName.typeName);
if (typeString) {
sb.append("'");
}
sb.append("\" + ").append(camelName);
if (typeString) {
sb.append(" + '\\''");
}
sb.append(" +\n");
}
sb.append(" '}';\n }");
}
private void buildFiledField(StringBuilder sb, String name, String upName, String typeName) {
sb.append(" private ")
.append(typeName)
.append(" ")
.append(name)
.append(";\n\n");
}
private boolean needGeneratorBoCode(String s) {
if (EmptyUtil.is(s)) return false;
for (CodeBuildEnum buildEnum : TEMP_CODE) {
if (s.contains(buildEnum.getDes())) return true;
}
return false;
}
private CodeBuildEnum getCodeBuildEnum(String s) {
if (EmptyUtil.is(s)) return null;
for (CodeBuildEnum buildEnum : TEMP_CODE) {
if (s.contains(buildEnum.getDes())) return buildEnum;
}
return null;
}
private static String convertToLowerCam(String s) {
char c = s.charAt(0);
if (c >= 65 && c <= 90) {
return StringUtils.replaceFirst(s, String.valueOf(c), String.valueOf((char) (c + 32)));
}
return s;
}
private static String convertToUpCam(String s) {
char c = s.charAt(0);
if (c >= 97 && c <= 122) {
return StringUtils.replaceFirst(s, String.valueOf(c), String.valueOf((char) (c - 32)));
}
return s;
}
private static String camelCovertToUpSnake(String s) {
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c >= 65 && c <= 90) {
if (i != 0) {
sb.append("_");
}
sb.append(c);
} else if (c >= 48 && c <= 57) {
sb.append(c);
} else {
sb.append((char) (c - 32));
}
}
return sb.toString();
}
private static String upSnakeToCamel(String s) {
StringBuilder sb = new StringBuilder("");
boolean up = false;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
// '_' == 95
if ((c >= 65 && c <= 90) || (95 == (int) c)) {
if (95 == (int) c) {
up = true;
continue;
}
if (up) {
sb.append(c);
up = false;
} else {
sb.append((char) (c + 32));
}
} else if (c >= 48 && c <= 57) {
sb.append(c);
}
}
return sb.toString();
}
class FieldName {
String camelName;
String UP_SNAKE_NAME;
String UpCameName;
String snake_name;
String typeName;
String comment;
}
}