package com.core.generators; import com.core.common.Cools; import com.core.generators.constant.SqlOsType; import com.core.generators.domain.Column; import com.core.generators.utils.GeneratorUtils; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.nio.file.FileAlreadyExistsException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; public class CoolGenerator { private static final String[] ALL_TEMPLATES = { "Controller", "Service", "ServiceImpl", "Mapper", "Entity", "Xml", "Html", "Js", "Sql" }; private static final Set SYSTEM_MODEL = new LinkedHashSet<>(Arrays.asList("User", "Host")); public String url; public String username; public String password; public String table; public String packagePath; public boolean controller = true; public boolean service = true; public boolean mapper = true; public boolean entity = true; public boolean xml = true; public boolean html = true; public boolean js = true; public boolean sql = true; public SqlOsType sqlOsType; public String backendPrefixPath = ""; public String frontendPrefixPath = ""; private List columns = new ArrayList<>(); private String fullEntityName; private String simpleEntityName; private String entityImport; private String entityContent; private String xmlContent; private String htmlSearchContent; private String htmlDialogContent; private String jsTableContent; private String jsDateContent; private String vueFieldMetaContent; private String vueSearchRangeField; private String vueSearchRangeLabel; private String primaryKeyColumn; private String primaryKeyType; private String majorColumn; private String systemPackage; public void build() throws Exception { init(); System.out.println("开始生成表[" + table + "]对应代码,实体名[" + fullEntityName + "]"); for (String templateName : ALL_TEMPLATES) { boolean enabled = false; String fileDir = ""; String fileName = ""; String routeSegment = templateName.toLowerCase(); if (routeSegment.contains("impl")) { routeSegment = routeSegment.substring(0, routeSegment.length() - 4) + "/" + routeSegment.substring(routeSegment.length() - 4); } switch (templateName) { case "Controller": enabled = controller; fileDir = backendPrefixPath + "src/main/java/" + packagePath.replace(".", "/") + "/" + routeSegment + "/"; fileName = fullEntityName + "Controller.java"; break; case "Service": enabled = service; fileDir = backendPrefixPath + "src/main/java/" + packagePath.replace(".", "/") + "/" + routeSegment + "/"; fileName = fullEntityName + "Service.java"; break; case "ServiceImpl": enabled = service; fileDir = backendPrefixPath + "src/main/java/" + packagePath.replace(".", "/") + "/" + routeSegment + "/"; fileName = fullEntityName + "ServiceImpl.java"; break; case "Mapper": enabled = mapper; fileDir = backendPrefixPath + "src/main/java/" + packagePath.replace(".", "/") + "/" + routeSegment + "/"; fileName = fullEntityName + "Mapper.java"; break; case "Entity": enabled = entity; fileDir = backendPrefixPath + "src/main/java/" + packagePath.replace(".", "/") + "/" + routeSegment + "/"; fileName = fullEntityName + ".java"; break; case "Xml": enabled = xml; fileDir = backendPrefixPath + "src/main/resources/mapper/"; fileName = fullEntityName + "Mapper.xml"; break; case "Html": enabled = html; fileDir = frontendPrefixPath + "src/main/webapp//views/" + simpleEntityName + "/"; fileName = simpleEntityName + ".html"; break; case "Js": enabled = js; fileDir = frontendPrefixPath + "src/main/webapp/static/js/" + simpleEntityName + "/"; fileName = simpleEntityName + ".js"; break; case "Sql": enabled = sql; fileDir = backendPrefixPath + "version/sql/"; fileName = simpleEntityName + ".sql"; break; default: break; } if (!enabled) { continue; } try { String template = loadTemplate(templateName + ".txt"); String content = renderTemplate(template); writeFile(fileDir, fileName, content, templateName); } catch (Exception e) { System.out.println(fullEntityName + templateName + " 源文件创建失败:" + e.getMessage()); throw e; } } System.out.println("表[" + table + "]代码生成结束"); } private void init() throws Exception { validate(); systemPackage = resolveSystemPackage(); fullEntityName = GeneratorUtils.getNameSpace(table); simpleEntityName = GeneratorUtils.firstCharConvert(fullEntityName); System.out.println("开始读取表结构:" + table); Connection connection = createConnection(); try { switch (sqlOsType) { case MYSQL: columns = getMysqlColumns(connection, table, true, sqlOsType); break; case SQL_SERVER: columns = getSqlServerColumns(connection, table, true, sqlOsType); break; default: throw new IllegalArgumentException("Unsupported sql type: " + sqlOsType); } } finally { connection.close(); } if (Cools.isEmpty(columns)) { throw new IllegalStateException("table has no columns: " + table); } System.out.println("表结构读取完成,共 " + columns.size() + " 个字段"); primaryKeyColumn = resolvePrimaryKeyColumn(); primaryKeyType = resolvePrimaryKeyType(); majorColumn = resolveMajorColumn(); entityImport = buildEntityImports(); entityContent = buildEntityContent(); xmlContent = buildXmlContent(); htmlSearchContent = buildHtmlSearchContent(); htmlDialogContent = buildHtmlDialogContent(); jsTableContent = buildJsTableContent(); jsDateContent = buildJsDateContent(); vueFieldMetaContent = buildVueFieldMetaContent(); Column rangeColumn = resolveRangeSearchColumn(); vueSearchRangeField = rangeColumn == null ? "" : rangeColumn.getName(); vueSearchRangeLabel = rangeColumn == null ? "" : GeneratorUtils.supportHtmlName(rangeColumn.getComment()); } private void validate() { if (Cools.isEmpty(url, username, password, table, packagePath) || sqlOsType == null) { throw new IllegalArgumentException("url/username/password/table/packagePath/sqlOsType are required"); } } private String resolveSystemPackage() { String[] arr = packagePath.split("\\."); if (arr.length <= 2) { return packagePath; } return arr[0] + "." + arr[1]; } private Connection createConnection() throws Exception { String jdbcUrl = url; switch (sqlOsType) { case MYSQL: Class.forName("com.mysql.cj.jdbc.Driver"); if (!jdbcUrl.startsWith("jdbc:mysql://")) { jdbcUrl = "jdbc:mysql://" + jdbcUrl; } if (!jdbcUrl.contains("?")) { jdbcUrl = jdbcUrl + "?useUnicode=true&characterEncoding=utf-8&useSSL=false&remarksReporting=true"; } else if (!jdbcUrl.contains("remarksReporting=")) { jdbcUrl = jdbcUrl + "&remarksReporting=true"; } return DriverManager.getConnection(jdbcUrl, username, password); case SQL_SERVER: Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); if (!jdbcUrl.startsWith("jdbc:sqlserver://")) { jdbcUrl = "jdbc:sqlserver://" + jdbcUrl; } return DriverManager.getConnection(jdbcUrl, username, password); default: throw new IllegalArgumentException("Unsupported sql type: " + sqlOsType); } } public static List getMysqlColumns(Connection connection, String table, boolean withForeignKey, SqlOsType sqlOsType) throws Exception { return getColumns(connection, table, withForeignKey, sqlOsType); } public static List getSqlServerColumns(Connection connection, String table, boolean withForeignKey, SqlOsType sqlOsType) throws Exception { return getColumns(connection, table, withForeignKey, sqlOsType); } private static List getColumns(Connection connection, String table, boolean withForeignKey, SqlOsType sqlOsType) throws Exception { List columns = new ArrayList<>(); DatabaseMetaData metaData = connection.getMetaData(); TableRef tableRef = parseTableRef(table); Set primaryKeys = new LinkedHashSet<>(); ResultSet pkRs = metaData.getPrimaryKeys(tableRef.catalog, tableRef.schema, tableRef.table); try { while (pkRs.next()) { primaryKeys.add(pkRs.getString("COLUMN_NAME")); } } finally { pkRs.close(); } ResultSet columnRs = metaData.getColumns(tableRef.catalog, tableRef.schema, tableRef.table, null); try { while (columnRs.next()) { String columnName = columnRs.getString("COLUMN_NAME"); int sqlType = columnRs.getInt("DATA_TYPE"); String type = GeneratorUtils.getType(sqlType); if (Cools.isEmpty(type)) { type = "String"; } String remarks = columnRs.getString("REMARKS"); boolean primaryKey = primaryKeys.contains(columnName); boolean mainKey = primaryKey && isAutoIncrement(columnRs); boolean notNull = columnRs.getInt("NULLABLE") == DatabaseMetaData.columnNoNulls; Integer length = GeneratorUtils.getColumnLength(columnRs.getString("TYPE_NAME")); columns.add(new Column(connection, columnName, type, remarks, primaryKey, mainKey, notNull, length, withForeignKey, sqlOsType)); } } finally { columnRs.close(); } for (Column column : columns) { System.out.println(column.toString()); } return columns; } private static boolean isAutoIncrement(ResultSet columnRs) { try { return "YES".equalsIgnoreCase(columnRs.getString("IS_AUTOINCREMENT")); } catch (SQLException e) { return false; } } private static TableRef parseTableRef(String table) { if (table != null && table.contains(".")) { String[] arr = table.split("\\."); return new TableRef(null, arr[0], arr[arr.length - 1]); } return new TableRef(null, null, table); } private String resolvePrimaryKeyColumn() { for (Column column : columns) { if (column.isPrimaryKey()) { return column.getHumpName(); } } return columns.get(0).getHumpName(); } private String resolvePrimaryKeyType() { for (Column column : columns) { if (column.isPrimaryKey()) { return column.getType(); } } return columns.get(0).getType(); } private String resolveMajorColumn() { for (Column column : columns) { if (column.isMajor()) { return column.getHumpName(); } } for (Column column : columns) { if (!column.isPrimaryKey()) { return column.getHumpName(); } } return primaryKeyColumn; } private String buildEntityImports() { Set imports = new LinkedHashSet<>(); boolean hasTableId = false; boolean hasTableField = false; boolean hasDate = false; boolean needCools = false; boolean hasSpringUtils = false; boolean hasTableLogic = false; for (Column column : columns) { if (column.isPrimaryKey()) { hasTableId = true; } else if (!column.getName().equals(column.getHumpName())) { hasTableField = true; } if ("deleted".equals(column.getName())) { hasTableLogic = true; } if ("Date".equals(column.getType())) { hasDate = true; needCools = true; } if (!Cools.isEmpty(column.getEnums()) || !Cools.isEmpty(column.getForeignKey())) { needCools = true; } if (!Cools.isEmpty(column.getForeignKey())) { hasSpringUtils = true; imports.add("import " + getForeignBasePackage(column.getForeignKey()) + ".service." + column.getForeignKey() + "Service;"); imports.add("import " + getForeignBasePackage(column.getForeignKey()) + ".entity." + column.getForeignKey() + ";"); } } if (needCools) { imports.add("import com.core.common.Cools;"); } if (hasSpringUtils) { imports.add("import com.core.common.SpringUtils;"); } if (hasTableId) { imports.add("import com.baomidou.mybatisplus.annotation.TableId;"); imports.add("import com.baomidou.mybatisplus.annotation.IdType;"); } if (hasTableLogic) { imports.add("import com.baomidou.mybatisplus.annotation.TableLogic;"); } if (hasTableField) { imports.add("import com.baomidou.mybatisplus.annotation.TableField;"); } if (hasDate) { imports.add("import java.text.SimpleDateFormat;"); imports.add("import java.util.Date;"); imports.add("import org.springframework.format.annotation.DateTimeFormat;"); } if (imports.isEmpty()) { return ""; } StringBuilder builder = new StringBuilder(); for (String item : imports) { builder.append(item).append("\n"); } return builder.toString(); } private String buildEntityContent() { StringBuilder builder = new StringBuilder(); for (Column column : columns) { builder.append(" /**\n"); builder.append(" * ").append(column.getWholeComment()).append("\n"); builder.append(" */\n"); builder.append(" @ApiModelProperty(value= \"").append(escapeJava(column.getWholeComment())).append("\")\n"); if (column.isPrimaryKey()) { builder.append(" @TableId(value = \"").append(column.getName()).append("\", type = IdType.") .append(column.isMainKey() ? "AUTO" : "INPUT").append(")\n"); } else if (!column.getName().equals(column.getHumpName())) { builder.append(" @TableField(\"").append(column.getName()).append("\")\n"); } if ("deleted".equals(column.getName())) { builder.append(" @TableLogic\n"); } if ("Date".equals(column.getType())) { builder.append(" @DateTimeFormat(pattern=\"yyyy-MM-dd HH:mm:ss\")\n"); } builder.append(" private ").append(column.getType()).append(" ").append(column.getHumpName()).append(";\n\n"); } List constructorColumns = getNonPrimaryColumns(); builder.append(" public ").append(fullEntityName).append("() {}\n\n"); if (!constructorColumns.isEmpty()) { builder.append(" public ").append(fullEntityName).append("("); for (Column column : constructorColumns) { builder.append(column.getType()).append(" ").append(column.getHumpName()).append(","); } builder.deleteCharAt(builder.length() - 1); builder.append(") {\n"); for (Column column : constructorColumns) { builder.append(" this.").append(column.getHumpName()).append(" = ").append(column.getHumpName()).append(";\n"); } builder.append(" }\n\n"); builder.append("// ").append(fullEntityName).append(" ").append(simpleEntityName) .append(" = new ").append(fullEntityName).append("(\n"); for (int i = 0; i < constructorColumns.size(); i++) { Column column = constructorColumns.get(i); builder.append("// null"); if (i < constructorColumns.size() - 1) { builder.append(","); } builder.append(" // ").append(column.getComment()); if (column.isNotNull()) { builder.append("[非空]"); } if (i < constructorColumns.size() - 1) { builder.append("\n"); } } builder.append("\n// );\n\n"); } List displayGetters = buildDisplayGetters(); for (String getter : displayGetters) { builder.append(getter).append("\n\n"); } return trimTrailingBlankLines(builder.toString()); } private List buildDisplayGetters() { List getters = new ArrayList<>(); for (Column column : columns) { String field = column.getHumpName(); String methodName = GeneratorUtils.firstCharConvert(field, false); if ("Date".equals(column.getType())) { StringBuilder builder = new StringBuilder(); builder.append(" public String get").append(methodName).append("$(){\n"); builder.append(" if (Cools.isEmpty(this.").append(field).append(")){\n"); builder.append(" return \"\";\n"); builder.append(" }\n"); builder.append(" return new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\").format(this.").append(field).append(");\n"); builder.append(" }"); getters.add(builder.toString()); continue; } if (!Cools.isEmpty(column.getEnums())) { StringBuilder builder = new StringBuilder(); builder.append(" public String get").append(methodName).append("$(){\n"); builder.append(" if (null == this.").append(field).append("){ return null; }\n"); builder.append(" switch (String.valueOf(this.").append(field).append(")){\n"); for (Map map : column.getEnums()) { for (Map.Entry entry : map.entrySet()) { builder.append(" case \"").append(escapeJava(entry.getKey())).append("\":\n"); builder.append(" return \"").append(escapeJava(String.valueOf(entry.getValue()))).append("\";\n"); } } builder.append(" default:\n"); builder.append(" return String.valueOf(this.").append(field).append(");\n"); builder.append(" }\n"); builder.append(" }"); getters.add(builder.toString()); continue; } if (!Cools.isEmpty(column.getForeignKeyMajor())) { StringBuilder builder = new StringBuilder(); builder.append(" public String get").append(methodName).append("$(){\n"); builder.append(" ").append(column.getForeignKey()).append("Service service = SpringUtils.getBean(") .append(column.getForeignKey()).append("Service.class);\n"); builder.append(" ").append(column.getForeignKey()).append(" ") .append(GeneratorUtils.firstCharConvert(column.getForeignKey())).append(" = service.getById(this.") .append(field).append(");\n"); builder.append(" if (!Cools.isEmpty(").append(GeneratorUtils.firstCharConvert(column.getForeignKey())) .append(")){\n"); builder.append(" return String.valueOf(").append(GeneratorUtils.firstCharConvert(column.getForeignKey())) .append(".get").append(column.getForeignKeyMajor()).append("());\n"); builder.append(" }\n"); builder.append(" return null;\n"); builder.append(" }"); getters.add(builder.toString()); } } return getters; } private String buildXmlContent() { StringBuilder builder = new StringBuilder(); for (Column column : columns) { if (column.isPrimaryKey()) { builder.append(" \n"); } else { builder.append(" \n"); } } return trimTrailingBlankLines(builder.toString()); } private String buildHtmlSearchContent() { StringBuilder builder = new StringBuilder(); builder.append("
\n"); builder.append("
\n"); builder.append(" \n"); builder.append("
\n"); builder.append("
\n"); Column rangeColumn = resolveRangeSearchColumn(); if (rangeColumn != null) { builder.append("
\n"); builder.append("
\n"); builder.append(" \n"); builder.append("
\n"); builder.append("
\n"); } return trimTrailingBlankLines(builder.toString()); } private String buildHtmlDialogContent() { StringBuilder builder = new StringBuilder(); for (Column column : columns) { String field = column.getHumpName(); if (column.isPrimaryKey()) { builder.append(" \n"); continue; } builder.append("
\n"); builder.append(" \n"); builder.append("
\n"); appendFormField(builder, column, " "); builder.append("
\n"); builder.append("
\n"); } return trimTrailingBlankLines(builder.toString()); } private String buildJsTableContent() { StringBuilder builder = new StringBuilder(); for (Column column : columns) { String field = resolveDisplayField(column); builder.append(" ,{field: '").append(field).append("', align: 'center',title: '") .append(escapeJs(column.getComment())).append("'"); if (column.isCheckBox()) { builder.append(", templet:function(row){\n") .append(" var html = \"\";\n") .append(" return html;\n") .append(" }"); } if (column.isPrimaryKey()) { builder.append(", sort: true"); } builder.append("}\n"); } return trimTrailingBlankLines(builder.toString()); } private String buildJsDateContent() { StringBuilder builder = new StringBuilder(); for (Column column : columns) { if (column.isPrimaryKey()) { continue; } if (!"Date".equals(column.getType())) { continue; } builder.append(" layDate.render({\n"); builder.append(" elem: '#").append(column.getHumpName()).append("$',\n"); builder.append(" type: 'datetime',\n"); builder.append(" value: data!==undefined?data['").append(column.getHumpName()).append("$']:null\n"); builder.append(" });\n"); } return trimTrailingBlankLines(builder.toString()); } private String buildVueFieldMetaContent() { StringBuilder builder = new StringBuilder(); for (int i = 0; i < columns.size(); i++) { Column column = columns.get(i); builder.append(" {\n"); builder.append(" field: '").append(column.getHumpName()).append("',\n"); builder.append(" columnName: '").append(column.getName()).append("',\n"); builder.append(" label: '").append(escapeJs(GeneratorUtils.supportHtmlName(column.getComment()))).append("',\n"); builder.append(" tableProp: '").append(resolveDisplayField(column)).append("',\n"); builder.append(" exportField: '").append(resolveDisplayField(column)).append("',\n"); builder.append(" kind: '").append(resolveVueFieldKind(column)).append("',\n"); builder.append(" valueType: '").append(resolveVueValueType(column)).append("',\n"); builder.append(" required: ").append(column.isNotNull()).append(",\n"); builder.append(" primaryKey: ").append(column.isPrimaryKey()).append(",\n"); builder.append(" sortable: ").append(column.isPrimaryKey()).append(",\n"); builder.append(" textarea: ").append(isLongTextField(column)).append(",\n"); builder.append(" minWidth: ").append(resolveVueMinWidth(column)).append(",\n"); builder.append(" enumOptions: ").append(buildVueEnumOptions(column)).append(",\n"); builder.append(" foreignQuery: '") .append(Cools.isEmpty(column.getForeignKey()) ? "" : escapeJs(GeneratorUtils.firstCharConvert(column.getForeignKey()))) .append("',\n"); builder.append(" checkboxActiveRaw: '").append(resolveCheckboxActiveRaw(column)).append("',\n"); builder.append(" checkboxInactiveRaw: '").append(resolveCheckboxInactiveRaw(column)).append("'\n"); builder.append(" }"); if (i < columns.size() - 1) { builder.append(","); } builder.append("\n"); } return trimTrailingBlankLines(builder.toString()); } private String resolveVueFieldKind(Column column) { if (column.isImage()) { return "image"; } if (column.isCheckBox()) { return "checkbox"; } if ("Date".equals(column.getType())) { return "date"; } if (!Cools.isEmpty(column.getEnums())) { return "enum"; } if (!Cools.isEmpty(column.getForeignKeyMajor())) { return "foreign"; } return "text"; } private String resolveVueValueType(Column column) { return isNumericType(column.getType()) ? "number" : "string"; } private boolean isNumericType(String type) { return "Integer".equals(type) || "Long".equals(type) || "Double".equals(type) || "Float".equals(type) || "Short".equals(type) || "BigDecimal".equals(type) || "Byte".equals(type); } private String buildVueEnumOptions(Column column) { if (Cools.isEmpty(column.getEnums())) { return "[]"; } StringBuilder builder = new StringBuilder("["); boolean first = true; for (Map map : column.getEnums()) { for (Map.Entry entry : map.entrySet()) { if (!first) { builder.append(", "); } builder.append("{ rawValue: '").append(escapeJs(String.valueOf(entry.getKey()))) .append("', label: '").append(escapeJs(String.valueOf(entry.getValue()))).append("' }"); first = false; } } builder.append("]"); return builder.toString(); } private boolean isLongTextField(Column column) { if (column.isImage()) { return false; } if (column.getLength() != null && column.getLength() >= 120) { return true; } String name = column.getName() == null ? "" : column.getName().toLowerCase(); String comment = column.getComment() == null ? "" : column.getComment(); return name.contains("memo") || name.contains("remark") || name.contains("response") || name.contains("request") || name.contains("content") || comment.contains("备注") || comment.contains("响应") || comment.contains("报文") || comment.contains("描述") || comment.contains("内容"); } private int resolveVueMinWidth(Column column) { if (column.isPrimaryKey()) { return 90; } if ("Date".equals(column.getType())) { return 168; } if (column.isImage()) { return 140; } if (isLongTextField(column)) { return 180; } if (!Cools.isEmpty(column.getEnums()) || column.isCheckBox()) { return 120; } int base = GeneratorUtils.supportHtmlName(column.getComment()).length() * 18 + 26; return Math.max(110, Math.min(base, 180)); } private String resolveCheckboxActiveRaw(Column column) { return isNumericType(column.getType()) ? "1" : "Y"; } private String resolveCheckboxInactiveRaw(Column column) { return isNumericType(column.getType()) ? "0" : "N"; } private String resolveDisplayField(Column column) { if ("Date".equals(column.getType()) || !Cools.isEmpty(column.getEnums()) || !Cools.isEmpty(column.getForeignKeyMajor())) { return column.getHumpName() + "$"; } return column.getHumpName(); } private List getNonPrimaryColumns() { List result = new ArrayList<>(); for (Column column : columns) { if (!column.isPrimaryKey()) { result.add(column); } } return result; } private Column resolveRangeSearchColumn() { for (Column column : columns) { if ("Date".equals(column.getType()) && ("create_time".equals(column.getName()) || "createTime".equals(column.getHumpName()))) { return column; } } for (Column column : columns) { if ("Date".equals(column.getType())) { return column; } } return null; } private String getForeignBasePackage(String foreignKey) { if (SYSTEM_MODEL.contains(foreignKey)) { return systemPackage + ".system"; } return packagePath; } private void appendFormField(StringBuilder builder, Column column, String inputIndent) { String field = column.getHumpName(); if (Cools.isEmpty(column.getEnums())) { builder.append(inputIndent).append("\n"); if (!Cools.isEmpty(column.getForeignKeyMajor())) { String queryKey = GeneratorUtils.firstCharConvert(column.getForeignKey()) + "QueryBy" + field; builder.append(inputIndent).append("\n"); builder.append(inputIndent).append("
\n"); builder.append(inputIndent).append(" \n"); builder.append(inputIndent).append(" \n"); builder.append(inputIndent).append("
\n"); } return; } builder.append(inputIndent).append("\n"); } private String renderTemplate(String template) { Map values = new LinkedHashMap<>(); values.put("COMPANYNAME", packagePath); values.put("SYSTEMPACKAGE", systemPackage); values.put("ENTITYNAME", fullEntityName); values.put("SIMPLEENTITYNAME", simpleEntityName); values.put("TABLENAME", table); values.put("ENTITYIMPORT", entityImport); values.put("ENTITYCONTENT", entityContent); values.put("XMLCONTENT", xmlContent); values.put("HTMLSEARCHCONTENT", htmlSearchContent); values.put("HTMLDIALOGCONTENT", htmlDialogContent); values.put("JSTABLECONTENT", jsTableContent); values.put("JSDATECONTENT", jsDateContent); values.put("VUEFIELDMETA", vueFieldMetaContent); values.put("VUESEARCHRANGEFIELD", vueSearchRangeField); values.put("VUESEARCHRANGELABEL", vueSearchRangeLabel); values.put("PRIMARYKEYCOLUMN", GeneratorUtils.firstCharConvert(primaryKeyColumn, false)); values.put("PRIMARYKEYCOLUMN0", primaryKeyColumn); values.put("PRIMARYKEYTYPE", primaryKeyType); values.put("MAJORCOLUMN", GeneratorUtils.humpToLine(majorColumn)); values.put("UPCASEMARJORCOLUMN", GeneratorUtils.firstCharConvert(majorColumn, false)); String content = template; for (Map.Entry entry : values.entrySet()) { content = content.replace("@{" + entry.getKey() + "}", entry.getValue() == null ? "" : entry.getValue()); } return content; } private void writeFile(String dir, String fileName, String content, String templateName) throws IOException { Path directory = Paths.get(dir); Files.createDirectories(directory); Path file = directory.resolve(fileName); if (Files.exists(file)) { System.out.println(fullEntityName + templateName + " 源文件已经存在创建失败!"); return; } try { Files.write(file, content.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE); System.out.println(fullEntityName + templateName + " 源文件创建成功!"); } catch (FileAlreadyExistsException e) { System.out.println(fullEntityName + templateName + " 源文件已经存在创建失败!"); } } private String loadTemplate(String name) throws IOException { InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("templates/" + name); if (inputStream == null) { throw new IOException("template not found: " + name); } try { ByteArrayOutputStream output = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; while ((len = inputStream.read(buffer)) != -1) { output.write(buffer, 0, len); } return new String(output.toByteArray(), StandardCharsets.UTF_8); } finally { inputStream.close(); } } private String trimTrailingBlankLines(String text) { String trimmed = text; while (trimmed.endsWith("\n\n")) { trimmed = trimmed.substring(0, trimmed.length() - 1); } return trimmed; } private String escapeJava(String text) { return text == null ? "" : text.replace("\\", "\\\\").replace("\"", "\\\""); } private String escapeJs(String text) { return escapeJava(text).replace("'", "\\'"); } private static class TableRef { private final String catalog; private final String schema; private final String table; private TableRef(String catalog, String schema, String table) { this.catalog = catalog; this.schema = schema; this.table = table; } } }