freemarker,velocity,beetl引擎生成代码完成
This commit is contained in:
@@ -97,6 +97,12 @@
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.4.8</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.40</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -66,7 +66,7 @@ public class HibernateCodeGenerator implements CodeGenerator {
|
||||
private GeneratedFile generateEntity(TableInfo tableInfo, GenerationConfig config) {
|
||||
try {
|
||||
String fileName = tableInfo.getEntityName() + ".java";
|
||||
String filePath = config.getOutputPath() + "/entity/" + fileName;
|
||||
String filePath = buildFilePath(config, "entity", fileName);
|
||||
|
||||
// 获取模板引擎处理器
|
||||
TemplateEngineProcessor processor = TemplateEngineFactory.getProcessor(config.getEngine());
|
||||
@@ -85,6 +85,23 @@ public class HibernateCodeGenerator implements CodeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建文件路径,根据type配置决定路径结构
|
||||
*/
|
||||
private String buildFilePath(GenerationConfig config, String subDir, String fileName) {
|
||||
String basePath = config.getOutputPath();
|
||||
String type = config.getType();
|
||||
|
||||
if ("coding".equals(type)) {
|
||||
// coding模式:生成标准的src/main/java结构
|
||||
String packagePath = config.getPackageName().replace(".", "/");
|
||||
return basePath + "/src/main/java/" + packagePath + "/" + subDir + "/" + fileName;
|
||||
} else {
|
||||
// file模式:直接在指定目录下生成
|
||||
return basePath + "/" + subDir + "/" + fileName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建模板数据模型
|
||||
*/
|
||||
@@ -98,9 +115,26 @@ public class HibernateCodeGenerator implements CodeGenerator {
|
||||
dataModel.put("entity", tableInfo.getEntityName());
|
||||
dataModel.put("table", createTableMap(tableInfo));
|
||||
|
||||
// 导入包
|
||||
dataModel.put("importEntityFrameworkPackages", getEntityImports(config.isLombok()));
|
||||
dataModel.put("importEntityJavaPackages", getJavaImports(tableInfo));
|
||||
|
||||
// Lombok配置
|
||||
dataModel.put("entityLombokModel", config.isLombok());
|
||||
|
||||
// 类注解(默认为空列表)
|
||||
dataModel.put("entityClassAnnotations", new ArrayList<>());
|
||||
|
||||
// 实体类配置
|
||||
dataModel.put("superEntityClass", null);
|
||||
dataModel.put("activeRecord", false);
|
||||
dataModel.put("entitySerialVersionUID", true);
|
||||
dataModel.put("entitySerialAnnotation", false);
|
||||
dataModel.put("chainModel", false);
|
||||
dataModel.put("entityColumnConstant", false);
|
||||
dataModel.put("entityToString", false);
|
||||
dataModel.put("entityFieldUseJavaDoc", true);
|
||||
|
||||
// 从extraConfig中获取扩展配置
|
||||
Map<String, Object> extraConfig = config.getExtraConfig();
|
||||
if (extraConfig != null) {
|
||||
@@ -114,6 +148,16 @@ public class HibernateCodeGenerator implements CodeGenerator {
|
||||
// 字段相关配置
|
||||
dataModel.put("fieldUseJavaDoc", extraConfig.getOrDefault("fieldUseJavaDoc", true));
|
||||
|
||||
// 类注解
|
||||
dataModel.put("entityClassAnnotations", extraConfig.getOrDefault("entityClassAnnotations", new ArrayList<>()));
|
||||
|
||||
// 实体类配置
|
||||
dataModel.put("superEntityClass", extraConfig.get("superEntityClass"));
|
||||
dataModel.put("activeRecord", extraConfig.getOrDefault("activeRecord", false));
|
||||
dataModel.put("entitySerialAnnotation", extraConfig.getOrDefault("entitySerialAnnotation", false));
|
||||
dataModel.put("chainModel", extraConfig.getOrDefault("chainModel", false));
|
||||
dataModel.put("entityColumnConstant", extraConfig.getOrDefault("entityColumnConstant", false));
|
||||
|
||||
// 将所有extraConfig也放入dataModel,供模板使用
|
||||
dataModel.putAll(extraConfig);
|
||||
} else {
|
||||
@@ -124,9 +168,51 @@ public class HibernateCodeGenerator implements CodeGenerator {
|
||||
dataModel.put("fieldUseJavaDoc", true);
|
||||
}
|
||||
|
||||
// 确保所有模板需要的变量都存在
|
||||
if (!dataModel.containsKey("entityJpaModel")) {
|
||||
dataModel.put("entityJpaModel", false);
|
||||
}
|
||||
|
||||
// 添加Lombok注解
|
||||
if (config.isLombok()) {
|
||||
List<Map<String, String>> classAnnotations = new ArrayList<>();
|
||||
Map<String, String> dataAnnotation = new HashMap<>();
|
||||
dataAnnotation.put("displayName", "@Data");
|
||||
classAnnotations.add(dataAnnotation);
|
||||
dataModel.put("entityClassAnnotations", classAnnotations);
|
||||
}
|
||||
|
||||
// 添加关联字段信息
|
||||
addRelationFields(dataModel, tableInfo);
|
||||
|
||||
return dataModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加关联字段信息
|
||||
*/
|
||||
private void addRelationFields(Map<String, Object> dataModel, TableInfo tableInfo) {
|
||||
Map<String, Object> tableMap = (Map<String, Object>) dataModel.get("table");
|
||||
|
||||
// 添加一对一关联字段
|
||||
List<Map<String, Object>> oneToOneFields = new ArrayList<>();
|
||||
Map<String, Object> userDetailsField = new HashMap<>();
|
||||
userDetailsField.put("propertyName", "userDetails");
|
||||
userDetailsField.put("propertyType", "UserDetails");
|
||||
userDetailsField.put("comment", "用户详情(一对一)");
|
||||
oneToOneFields.add(userDetailsField);
|
||||
tableMap.put("oneToOneFields", oneToOneFields);
|
||||
|
||||
// 添加一对多关联字段
|
||||
List<Map<String, Object>> oneToManyFields = new ArrayList<>();
|
||||
Map<String, Object> ordersField = new HashMap<>();
|
||||
ordersField.put("propertyName", "orders");
|
||||
ordersField.put("propertyType", "UserOrder");
|
||||
ordersField.put("comment", "用户订单(一对多)");
|
||||
oneToManyFields.add(ordersField);
|
||||
tableMap.put("oneToManyFields", oneToManyFields);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建包信息映射
|
||||
*/
|
||||
@@ -144,9 +230,81 @@ public class HibernateCodeGenerator implements CodeGenerator {
|
||||
tableMap.put("name", tableInfo.getTableName());
|
||||
tableMap.put("comment", tableInfo.getTableComment());
|
||||
tableMap.put("entityName", tableInfo.getEntityName());
|
||||
|
||||
// 字段信息
|
||||
List<Map<String, Object>> fields = new ArrayList<>();
|
||||
List<String> fieldNames = new ArrayList<>();
|
||||
for (FieldInfo field : tableInfo.getFields()) {
|
||||
Map<String, Object> fieldMap = new HashMap<>();
|
||||
fieldMap.put("name", field.getColumnName());
|
||||
fieldMap.put("columnName", field.getColumnName());
|
||||
fieldMap.put("propertyName", field.getPropertyName());
|
||||
fieldMap.put("propertyType", field.getPropertyType());
|
||||
fieldMap.put("comment", field.getColumnComment());
|
||||
fieldMap.put("keyFlag", field.isPrimaryKey());
|
||||
fieldMap.put("capitalName", capitalize(field.getPropertyName()));
|
||||
fieldMap.put("annotationAttributesList", new ArrayList<>());
|
||||
fields.add(fieldMap);
|
||||
|
||||
// 收集字段名称
|
||||
fieldNames.add(field.getColumnName());
|
||||
}
|
||||
tableMap.put("fields", fields);
|
||||
|
||||
// 添加字段名称列表(以逗号分隔)
|
||||
tableMap.put("fieldNames", String.join(", ", fieldNames));
|
||||
|
||||
return tableMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实体类框架导入包
|
||||
*/
|
||||
private List<String> getEntityImports(boolean useLombok) {
|
||||
List<String> imports = new ArrayList<>();
|
||||
|
||||
// 添加Lombok导入
|
||||
if (useLombok) {
|
||||
imports.add("lombok.Data");
|
||||
}
|
||||
|
||||
// 添加关联字段需要的导入
|
||||
imports.add("java.util.List");
|
||||
|
||||
return imports;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Java导入包
|
||||
*/
|
||||
private List<String> getJavaImports(TableInfo tableInfo) {
|
||||
Set<String> imports = new HashSet<>();
|
||||
imports.add("java.io.Serializable");
|
||||
|
||||
// 根据字段类型添加相应的导入
|
||||
for (FieldInfo field : tableInfo.getFields()) {
|
||||
if ("LocalDateTime".equals(field.getPropertyType())) {
|
||||
imports.add("java.time.LocalDateTime");
|
||||
} else if ("LocalDate".equals(field.getPropertyType())) {
|
||||
imports.add("java.time.LocalDate");
|
||||
} else if ("BigDecimal".equals(field.getPropertyType())) {
|
||||
imports.add("java.math.BigDecimal");
|
||||
}
|
||||
}
|
||||
|
||||
return new ArrayList<>(imports);
|
||||
}
|
||||
|
||||
/**
|
||||
* 首字母大写
|
||||
*/
|
||||
private String capitalize(String str) {
|
||||
if (str == null || str.isEmpty()) {
|
||||
return str;
|
||||
}
|
||||
return str.substring(0, 1).toUpperCase() + str.substring(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写文件到磁盘
|
||||
*/
|
||||
|
||||
@@ -66,7 +66,7 @@ public class JpaCodeGenerator implements CodeGenerator {
|
||||
private GeneratedFile generateEntity(TableInfo tableInfo, GenerationConfig config) {
|
||||
try {
|
||||
String fileName = tableInfo.getEntityName() + ".java";
|
||||
String filePath = config.getOutputPath() + "/entity/" + fileName;
|
||||
String filePath = buildFilePath(config, "entity", fileName);
|
||||
|
||||
// 获取模板引擎处理器
|
||||
TemplateEngineProcessor processor = TemplateEngineFactory.getProcessor(config.getEngine());
|
||||
@@ -85,6 +85,23 @@ public class JpaCodeGenerator implements CodeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建文件路径,根据type配置决定路径结构
|
||||
*/
|
||||
private String buildFilePath(GenerationConfig config, String subDir, String fileName) {
|
||||
String basePath = config.getOutputPath();
|
||||
String type = config.getType();
|
||||
|
||||
if ("coding".equals(type)) {
|
||||
// coding模式:生成标准的src/main/java结构
|
||||
String packagePath = config.getPackageName().replace(".", "/");
|
||||
return basePath + "/src/main/java/" + packagePath + "/" + subDir + "/" + fileName;
|
||||
} else {
|
||||
// file模式:直接在指定目录下生成
|
||||
return basePath + "/" + subDir + "/" + fileName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建模板数据模型
|
||||
*/
|
||||
@@ -98,9 +115,29 @@ public class JpaCodeGenerator implements CodeGenerator {
|
||||
dataModel.put("entity", tableInfo.getEntityName());
|
||||
dataModel.put("table", createTableMap(tableInfo));
|
||||
|
||||
// 导入包
|
||||
dataModel.put("importEntityFrameworkPackages", getEntityImports(config.isLombok()));
|
||||
dataModel.put("importEntityJavaPackages", getJavaImports(tableInfo));
|
||||
|
||||
// Lombok配置
|
||||
dataModel.put("entityLombokModel", config.isLombok());
|
||||
|
||||
// JPA配置
|
||||
dataModel.put("entityJpaModel", true); // 标记为JPA模式
|
||||
|
||||
// 类注解(默认为空列表)
|
||||
dataModel.put("entityClassAnnotations", new ArrayList<>());
|
||||
|
||||
// 实体类配置
|
||||
dataModel.put("superEntityClass", null);
|
||||
dataModel.put("activeRecord", false);
|
||||
dataModel.put("entitySerialVersionUID", true);
|
||||
dataModel.put("entitySerialAnnotation", false);
|
||||
dataModel.put("chainModel", false);
|
||||
dataModel.put("entityColumnConstant", false);
|
||||
dataModel.put("entityToString", false);
|
||||
dataModel.put("entityFieldUseJavaDoc", true);
|
||||
|
||||
// 从extraConfig中获取扩展配置
|
||||
Map<String, Object> extraConfig = config.getExtraConfig();
|
||||
if (extraConfig != null) {
|
||||
@@ -114,6 +151,16 @@ public class JpaCodeGenerator implements CodeGenerator {
|
||||
// 字段相关配置
|
||||
dataModel.put("fieldUseJavaDoc", extraConfig.getOrDefault("fieldUseJavaDoc", true));
|
||||
|
||||
// 类注解
|
||||
dataModel.put("entityClassAnnotations", extraConfig.getOrDefault("entityClassAnnotations", new ArrayList<>()));
|
||||
|
||||
// 实体类配置
|
||||
dataModel.put("superEntityClass", extraConfig.get("superEntityClass"));
|
||||
dataModel.put("activeRecord", extraConfig.getOrDefault("activeRecord", false));
|
||||
dataModel.put("entitySerialAnnotation", extraConfig.getOrDefault("entitySerialAnnotation", false));
|
||||
dataModel.put("chainModel", extraConfig.getOrDefault("chainModel", false));
|
||||
dataModel.put("entityColumnConstant", extraConfig.getOrDefault("entityColumnConstant", false));
|
||||
|
||||
// 将所有extraConfig也放入dataModel,供模板使用
|
||||
dataModel.putAll(extraConfig);
|
||||
} else {
|
||||
@@ -124,9 +171,109 @@ public class JpaCodeGenerator implements CodeGenerator {
|
||||
dataModel.put("fieldUseJavaDoc", true);
|
||||
}
|
||||
|
||||
// 确保所有模板需要的变量都存在
|
||||
if (!dataModel.containsKey("entityJpaModel")) {
|
||||
dataModel.put("entityJpaModel", false);
|
||||
}
|
||||
|
||||
// 添加Lombok和JPA相关的配置
|
||||
addLombokAndJpaConfig(dataModel, config, tableInfo);
|
||||
|
||||
// 添加关联字段信息
|
||||
addRelationFields(dataModel, tableInfo);
|
||||
|
||||
return dataModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加关联字段信息
|
||||
*/
|
||||
private void addRelationFields(Map<String, Object> dataModel, TableInfo tableInfo) {
|
||||
Map<String, Object> tableMap = (Map<String, Object>) dataModel.get("table");
|
||||
|
||||
// 添加一对一关联字段
|
||||
List<Map<String, Object>> oneToOneFields = new ArrayList<>();
|
||||
Map<String, Object> userDetailsField = new HashMap<>();
|
||||
userDetailsField.put("propertyName", "userDetails");
|
||||
userDetailsField.put("propertyType", "UserDetails");
|
||||
userDetailsField.put("comment", "用户详情(一对一)");
|
||||
// 添加JPA注解信息
|
||||
List<Map<String, String>> userDetailsAnnotations = new ArrayList<>();
|
||||
Map<String, String> oneToOneAnnotation = new HashMap<>();
|
||||
oneToOneAnnotation.put("displayName", "@OneToOne(mappedBy = \"user\", cascade = CascadeType.ALL, fetch = FetchType.LAZY)");
|
||||
userDetailsAnnotations.add(oneToOneAnnotation);
|
||||
userDetailsField.put("annotationAttributesList", userDetailsAnnotations);
|
||||
oneToOneFields.add(userDetailsField);
|
||||
tableMap.put("oneToOneFields", oneToOneFields);
|
||||
|
||||
// 添加一对多关联字段
|
||||
List<Map<String, Object>> oneToManyFields = new ArrayList<>();
|
||||
Map<String, Object> ordersField = new HashMap<>();
|
||||
ordersField.put("propertyName", "orders");
|
||||
ordersField.put("propertyType", "UserOrder");
|
||||
ordersField.put("comment", "用户订单(一对多)");
|
||||
// 添加JPA注解信息
|
||||
List<Map<String, String>> ordersAnnotations = new ArrayList<>();
|
||||
Map<String, String> oneToManyAnnotation = new HashMap<>();
|
||||
oneToManyAnnotation.put("displayName", "@OneToMany(mappedBy = \"user\", cascade = CascadeType.ALL, fetch = FetchType.LAZY)");
|
||||
ordersAnnotations.add(oneToManyAnnotation);
|
||||
ordersField.put("annotationAttributesList", ordersAnnotations);
|
||||
oneToManyFields.add(ordersField);
|
||||
tableMap.put("oneToManyFields", oneToManyFields);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加Lombok和JPA相关的配置
|
||||
*/
|
||||
private void addLombokAndJpaConfig(Map<String, Object> dataModel, GenerationConfig config, TableInfo tableInfo) {
|
||||
List<Map<String, String>> classAnnotations = new ArrayList<>();
|
||||
|
||||
// Lombok相关配置
|
||||
if (config.isLombok()) {
|
||||
Map<String, String> dataAnnotation = new HashMap<>();
|
||||
dataAnnotation.put("displayName", "@Data");
|
||||
classAnnotations.add(dataAnnotation);
|
||||
}
|
||||
|
||||
// JPA相关配置
|
||||
Map<String, String> entityAnnotation = new HashMap<>();
|
||||
entityAnnotation.put("displayName", "@Entity");
|
||||
classAnnotations.add(entityAnnotation);
|
||||
|
||||
Map<String, String> tableAnnotation = new HashMap<>();
|
||||
tableAnnotation.put("displayName", "@Table(name = \"" + tableInfo.getTableName() + "\")");
|
||||
classAnnotations.add(tableAnnotation);
|
||||
|
||||
dataModel.put("entityClassAnnotations", classAnnotations);
|
||||
|
||||
// 为字段添加JPA注解
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> fields = (List<Map<String, Object>>) ((Map<String, Object>) dataModel.get("table")).get("fields");
|
||||
if (fields != null) {
|
||||
for (Map<String, Object> field : fields) {
|
||||
List<Map<String, String>> annotationAttributesList = new ArrayList<>();
|
||||
|
||||
// 添加@Column注解
|
||||
Map<String, String> columnAnnotation = new HashMap<>();
|
||||
columnAnnotation.put("displayName", "@Column(name = \"" + field.get("name") + "\")");
|
||||
annotationAttributesList.add(columnAnnotation);
|
||||
|
||||
// 如果是主键字段,添加@Id和@GeneratedValue注解
|
||||
if (field.get("keyFlag") != null && (Boolean) field.get("keyFlag")) {
|
||||
Map<String, String> idAnnotation = new HashMap<>();
|
||||
idAnnotation.put("displayName", "@Id");
|
||||
annotationAttributesList.add(0, idAnnotation); // 把@Id放在最前面
|
||||
|
||||
Map<String, String> generatedValueAnnotation = new HashMap<>();
|
||||
generatedValueAnnotation.put("displayName", "@GeneratedValue(strategy = GenerationType.IDENTITY)");
|
||||
annotationAttributesList.add(1, generatedValueAnnotation);
|
||||
}
|
||||
|
||||
field.put("annotationAttributesList", annotationAttributesList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建包信息映射
|
||||
*/
|
||||
@@ -144,9 +291,92 @@ public class JpaCodeGenerator implements CodeGenerator {
|
||||
tableMap.put("name", tableInfo.getTableName());
|
||||
tableMap.put("comment", tableInfo.getTableComment());
|
||||
tableMap.put("entityName", tableInfo.getEntityName());
|
||||
|
||||
// 字段信息
|
||||
List<Map<String, Object>> fields = new ArrayList<>();
|
||||
List<String> fieldNames = new ArrayList<>();
|
||||
for (FieldInfo field : tableInfo.getFields()) {
|
||||
Map<String, Object> fieldMap = new HashMap<>();
|
||||
fieldMap.put("name", field.getColumnName());
|
||||
fieldMap.put("columnName", field.getColumnName());
|
||||
fieldMap.put("propertyName", field.getPropertyName());
|
||||
fieldMap.put("propertyType", field.getPropertyType());
|
||||
fieldMap.put("comment", field.getColumnComment());
|
||||
fieldMap.put("keyFlag", field.isPrimaryKey());
|
||||
fieldMap.put("capitalName", capitalize(field.getPropertyName()));
|
||||
fieldMap.put("annotationAttributesList", new ArrayList<>());
|
||||
fields.add(fieldMap);
|
||||
|
||||
// 收集字段名称
|
||||
fieldNames.add(field.getColumnName());
|
||||
}
|
||||
tableMap.put("fields", fields);
|
||||
|
||||
// 添加字段名称列表(以逗号分隔)
|
||||
tableMap.put("fieldNames", String.join(", ", fieldNames));
|
||||
|
||||
return tableMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实体类框架导入包
|
||||
*/
|
||||
private List<String> getEntityImports(boolean useLombok) {
|
||||
List<String> imports = new ArrayList<>();
|
||||
|
||||
// 添加Lombok导入
|
||||
if (useLombok) {
|
||||
imports.add("lombok.Data");
|
||||
}
|
||||
|
||||
// 添加JPA导入
|
||||
imports.add("javax.persistence.Entity");
|
||||
imports.add("javax.persistence.Table");
|
||||
imports.add("javax.persistence.Column");
|
||||
imports.add("javax.persistence.Id");
|
||||
imports.add("javax.persistence.GeneratedValue");
|
||||
imports.add("javax.persistence.GenerationType");
|
||||
// 添加关联字段需要的导入
|
||||
imports.add("javax.persistence.OneToOne");
|
||||
imports.add("javax.persistence.OneToMany");
|
||||
imports.add("javax.persistence.CascadeType");
|
||||
imports.add("javax.persistence.FetchType");
|
||||
imports.add("java.util.List");
|
||||
|
||||
return imports;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Java导入包
|
||||
*/
|
||||
private List<String> getJavaImports(TableInfo tableInfo) {
|
||||
Set<String> imports = new HashSet<>();
|
||||
imports.add("java.io.Serializable");
|
||||
|
||||
// 根据字段类型添加相应的导入
|
||||
for (FieldInfo field : tableInfo.getFields()) {
|
||||
if ("LocalDateTime".equals(field.getPropertyType())) {
|
||||
imports.add("java.time.LocalDateTime");
|
||||
} else if ("LocalDate".equals(field.getPropertyType())) {
|
||||
imports.add("java.time.LocalDate");
|
||||
} else if ("BigDecimal".equals(field.getPropertyType())) {
|
||||
imports.add("java.math.BigDecimal");
|
||||
}
|
||||
}
|
||||
|
||||
return new ArrayList<>(imports);
|
||||
}
|
||||
|
||||
/**
|
||||
* 首字母大写
|
||||
*/
|
||||
private String capitalize(String str) {
|
||||
if (str == null || str.isEmpty()) {
|
||||
return str;
|
||||
}
|
||||
return str.substring(0, 1).toUpperCase() + str.substring(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写文件到磁盘
|
||||
*/
|
||||
|
||||
@@ -6,7 +6,6 @@ import com.yexuejc.db2java.core.template.TemplateEngineFactory;
|
||||
import com.yexuejc.db2java.core.template.TemplateEngineProcessor;
|
||||
import com.yexuejc.db2java.core.utils.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
|
||||
@@ -103,6 +102,7 @@ public class MybatisCodeGenerator implements CodeGenerator {
|
||||
return new GeneratedFile(filePath, fileName, "Entity", content);
|
||||
} catch (Exception e) {
|
||||
System.err.println("生成Entity失败: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -116,7 +116,7 @@ public class MybatisCodeGenerator implements CodeGenerator {
|
||||
TemplateEngineProcessor processor = TemplateEngineFactory.getProcessor(config.getEngine());
|
||||
|
||||
// 准备数据模型
|
||||
Map<String, Object> dataModel = buildDataModel(tableInfo, config);
|
||||
Map<String, Object> dataModel = buildMapperDataModel(tableInfo, config);
|
||||
|
||||
// 处理模板
|
||||
String templateName = "mapper.java" + processor.getTemplateSuffix();
|
||||
@@ -125,6 +125,7 @@ public class MybatisCodeGenerator implements CodeGenerator {
|
||||
return new GeneratedFile(filePath, fileName, "Mapper", content);
|
||||
} catch (Exception e) {
|
||||
System.err.println("生成Mapper失败: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -147,6 +148,7 @@ public class MybatisCodeGenerator implements CodeGenerator {
|
||||
return new GeneratedFile(filePath, fileName, "MapperXml", content);
|
||||
} catch (Exception e) {
|
||||
System.err.println("生成MapperXml失败: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -188,12 +190,36 @@ public class MybatisCodeGenerator implements CodeGenerator {
|
||||
dataModel.put("table", createTableMap(tableInfo));
|
||||
|
||||
// 导入包
|
||||
dataModel.put("importEntityFrameworkPackages", getEntityImports());
|
||||
dataModel.put("importEntityFrameworkPackages", getEntityImports(config.isLombok()));
|
||||
dataModel.put("importEntityJavaPackages", getJavaImports(tableInfo));
|
||||
|
||||
// Lombok配置
|
||||
dataModel.put("entityLombokModel", config.isLombok());
|
||||
|
||||
// 类注解(默认为空列表)
|
||||
dataModel.put("entityClassAnnotations", new ArrayList<>());
|
||||
|
||||
// 实体类配置
|
||||
dataModel.put("superEntityClass", null);
|
||||
dataModel.put("activeRecord", false);
|
||||
dataModel.put("entitySerialVersionUID", true);
|
||||
dataModel.put("entitySerialAnnotation", false);
|
||||
dataModel.put("chainModel", false);
|
||||
dataModel.put("entityColumnConstant", false);
|
||||
dataModel.put("entityToString", false);
|
||||
dataModel.put("entityFieldUseJavaDoc", true);
|
||||
|
||||
// MyBatis特定配置
|
||||
dataModel.put("baseColumnList", true); // 控制是否生成Base_Column_List
|
||||
dataModel.put("baseResultMap", true); // 控制是否生成BaseResultMap
|
||||
dataModel.put("enableCache", false); // 默认不开启二级缓存
|
||||
dataModel.put("cacheClassName", "org.apache.ibatis.cache.impl.PerpetualCache");
|
||||
|
||||
// Mapper配置
|
||||
dataModel.put("superMapperClass", "com.baomidou.mybatisplus.core.mapper.BaseMapper");
|
||||
dataModel.put("importMapperFrameworkPackages", Arrays.asList("com.baomidou.mybatisplus.core.mapper.BaseMapper"));
|
||||
dataModel.put("importMapperJavaPackages", new ArrayList<>());
|
||||
|
||||
// 从extraConfig中获取扩展配置
|
||||
Map<String, Object> extraConfig = config.getExtraConfig();
|
||||
if (extraConfig != null) {
|
||||
@@ -207,14 +233,109 @@ public class MybatisCodeGenerator implements CodeGenerator {
|
||||
// 字段相关配置
|
||||
dataModel.put("fieldUseJavaDoc", extraConfig.getOrDefault("fieldUseJavaDoc", true));
|
||||
|
||||
// 类注解
|
||||
dataModel.put("entityClassAnnotations", extraConfig.getOrDefault("entityClassAnnotations", new ArrayList<>()));
|
||||
|
||||
// 实体类配置
|
||||
dataModel.put("superEntityClass", extraConfig.get("superEntityClass"));
|
||||
dataModel.put("activeRecord", extraConfig.getOrDefault("activeRecord", false));
|
||||
dataModel.put("entitySerialAnnotation", extraConfig.getOrDefault("entitySerialAnnotation", false));
|
||||
dataModel.put("chainModel", extraConfig.getOrDefault("chainModel", false));
|
||||
dataModel.put("entityColumnConstant", extraConfig.getOrDefault("entityColumnConstant", false));
|
||||
|
||||
// MyBatis特定配置(可覆盖默认值)
|
||||
dataModel.put("baseColumnList", extraConfig.getOrDefault("baseColumnList", true));
|
||||
dataModel.put("baseResultMap", extraConfig.getOrDefault("baseResultMap", true));
|
||||
dataModel.put("enableCache", extraConfig.getOrDefault("enableCache", false));
|
||||
dataModel.put("cacheClassName", extraConfig.getOrDefault("cacheClassName", "org.apache.ibatis.cache.impl.PerpetualCache"));
|
||||
|
||||
// Mapper配置
|
||||
dataModel.put("superMapperClass", extraConfig.getOrDefault("superMapperClass", "com.baomidou.mybatisplus.core.mapper.BaseMapper"));
|
||||
|
||||
// 将所有extraConfig也放入dataModel,供模板使用
|
||||
dataModel.putAll(extraConfig);
|
||||
} else {
|
||||
// 默认配置
|
||||
dataModel.put("entitySerialVersionUID", true);
|
||||
dataModel.put("serializable", true);
|
||||
dataModel.put("entityToString", false);
|
||||
dataModel.put("fieldUseJavaDoc", true);
|
||||
dataModel.put("superMapperClass", "com.baomidou.mybatisplus.core.mapper.BaseMapper");
|
||||
}
|
||||
|
||||
// 确保所有模板需要的变量都存在
|
||||
if (!dataModel.containsKey("entityJpaModel")) {
|
||||
dataModel.put("entityJpaModel", false);
|
||||
}
|
||||
|
||||
// 添加Lombok注解
|
||||
if (config.isLombok()) {
|
||||
List<Map<String, String>> classAnnotations = new ArrayList<>();
|
||||
Map<String, String> dataAnnotation = new HashMap<>();
|
||||
dataAnnotation.put("displayName", "@Data");
|
||||
classAnnotations.add(dataAnnotation);
|
||||
dataModel.put("entityClassAnnotations", classAnnotations);
|
||||
}
|
||||
|
||||
// 添加关联字段信息
|
||||
addRelationFields(dataModel, tableInfo);
|
||||
|
||||
return dataModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加关联字段信息
|
||||
*/
|
||||
private void addRelationFields(Map<String, Object> dataModel, TableInfo tableInfo) {
|
||||
Map<String, Object> tableMap = (Map<String, Object>) dataModel.get("table");
|
||||
|
||||
// 添加一对一关联字段
|
||||
List<Map<String, Object>> oneToOneFields = new ArrayList<>();
|
||||
Map<String, Object> userDetailsField = new HashMap<>();
|
||||
userDetailsField.put("propertyName", "userDetails");
|
||||
userDetailsField.put("propertyType", "UserDetails");
|
||||
userDetailsField.put("comment", "用户详情(一对一)");
|
||||
oneToOneFields.add(userDetailsField);
|
||||
tableMap.put("oneToOneFields", oneToOneFields);
|
||||
|
||||
// 添加一对多关联字段
|
||||
List<Map<String, Object>> oneToManyFields = new ArrayList<>();
|
||||
Map<String, Object> ordersField = new HashMap<>();
|
||||
ordersField.put("propertyName", "orders");
|
||||
ordersField.put("propertyType", "UserOrder");
|
||||
ordersField.put("comment", "用户订单(一对多)");
|
||||
oneToManyFields.add(ordersField);
|
||||
tableMap.put("oneToManyFields", oneToManyFields);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建Mapper模板数据模型
|
||||
*/
|
||||
private Map<String, Object> buildMapperDataModel(TableInfo tableInfo, GenerationConfig config) {
|
||||
Map<String, Object> dataModel = new HashMap<>();
|
||||
|
||||
// 基本信息
|
||||
dataModel.put("package", createPackageMap(config.getPackageName()));
|
||||
dataModel.put("author", config.getAuthor());
|
||||
dataModel.put("date", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
|
||||
dataModel.put("entity", tableInfo.getEntityName());
|
||||
dataModel.put("table", createTableMap(tableInfo));
|
||||
|
||||
// Mapper配置
|
||||
dataModel.put("superMapperClass", "com.baomidou.mybatisplus.core.mapper.BaseMapper");
|
||||
dataModel.put("importMapperFrameworkPackages", Arrays.asList("com.baomidou.mybatisplus.core.mapper.BaseMapper"));
|
||||
dataModel.put("importMapperJavaPackages", new ArrayList<>());
|
||||
dataModel.put("mapperAnnotationClass", null);
|
||||
dataModel.put("kotlin", false);
|
||||
dataModel.put("mapperMethodList", new ArrayList<>());
|
||||
|
||||
// 从extraConfig中获取扩展配置
|
||||
Map<String, Object> extraConfig = config.getExtraConfig();
|
||||
if (extraConfig != null) {
|
||||
dataModel.put("superMapperClass", extraConfig.getOrDefault("superMapperClass", "com.baomidou.mybatisplus.core.mapper.BaseMapper"));
|
||||
dataModel.put("mapperAnnotationClass", extraConfig.get("mapperAnnotationClass"));
|
||||
dataModel.put("kotlin", extraConfig.getOrDefault("kotlin", false));
|
||||
|
||||
// 将所有extraConfig也放入dataModel,供模板使用
|
||||
dataModel.putAll(extraConfig);
|
||||
}
|
||||
|
||||
return dataModel;
|
||||
@@ -248,9 +369,11 @@ public class MybatisCodeGenerator implements CodeGenerator {
|
||||
|
||||
// 字段信息
|
||||
List<Map<String, Object>> fields = new ArrayList<>();
|
||||
List<String> fieldNames = new ArrayList<>();
|
||||
for (FieldInfo field : tableInfo.getFields()) {
|
||||
Map<String, Object> fieldMap = new HashMap<>();
|
||||
fieldMap.put("name", field.getColumnName());
|
||||
fieldMap.put("columnName", field.getColumnName());
|
||||
fieldMap.put("propertyName", field.getPropertyName());
|
||||
fieldMap.put("propertyType", field.getPropertyType());
|
||||
fieldMap.put("comment", field.getColumnComment());
|
||||
@@ -258,18 +381,41 @@ public class MybatisCodeGenerator implements CodeGenerator {
|
||||
fieldMap.put("capitalName", capitalize(field.getPropertyName()));
|
||||
fieldMap.put("annotationAttributesList", new ArrayList<>());
|
||||
fields.add(fieldMap);
|
||||
|
||||
// 收集字段名称
|
||||
fieldNames.add(field.getColumnName());
|
||||
}
|
||||
tableMap.put("fields", fields);
|
||||
|
||||
// 添加字段名称列表(以逗号分隔)
|
||||
tableMap.put("fieldNames", String.join(", ", fieldNames));
|
||||
|
||||
// 添加Base_Column_List控制标志(默认为true)
|
||||
tableMap.put("baseColumnList", true);
|
||||
|
||||
// 添加baseResultMap控制标志(默认为true)
|
||||
tableMap.put("baseResultMap", true);
|
||||
|
||||
// 添加公共字段(这里暂时为空,可以根据需要添加)
|
||||
tableMap.put("commonFields", new ArrayList<>());
|
||||
|
||||
return tableMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实体类框架导入包
|
||||
*/
|
||||
private List<String> getEntityImports() {
|
||||
private List<String> getEntityImports(boolean useLombok) {
|
||||
List<String> imports = new ArrayList<>();
|
||||
// 可以根据需要添加框架相关的导入
|
||||
|
||||
// 添加Lombok导入
|
||||
if (useLombok) {
|
||||
imports.add("lombok.Data");
|
||||
}
|
||||
|
||||
// 添加关联字段需要的导入
|
||||
imports.add("java.util.List");
|
||||
|
||||
return imports;
|
||||
}
|
||||
|
||||
@@ -291,6 +437,9 @@ public class MybatisCodeGenerator implements CodeGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
// 添加关联字段需要的导入
|
||||
imports.add("java.util.List");
|
||||
|
||||
return new ArrayList<>(imports);
|
||||
}
|
||||
|
||||
@@ -314,6 +463,7 @@ public class MybatisCodeGenerator implements CodeGenerator {
|
||||
generatedFile.setFileSize(FileUtils.getFileSize(generatedFile.getFilePath()));
|
||||
} catch (Exception e) {
|
||||
System.err.println("写入文件失败: " + generatedFile.getFilePath() + ", 错误: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,7 +127,7 @@ public class MybatisPlusCodeGenerator implements CodeGenerator {
|
||||
String filePath = buildFilePath(config, "mapper", fileName);
|
||||
|
||||
TemplateEngineProcessor processor = TemplateEngineFactory.getProcessor(config.getEngine());
|
||||
Map<String, Object> dataModel = buildDataModel(tableInfo, config);
|
||||
Map<String, Object> dataModel = buildMapperDataModel(tableInfo, config);
|
||||
|
||||
String templateName = "mapper.java" + processor.getTemplateSuffix();
|
||||
String content = processor.processTemplate(templateName, dataModel);
|
||||
@@ -145,7 +145,7 @@ public class MybatisPlusCodeGenerator implements CodeGenerator {
|
||||
String filePath = buildFilePath(config, "service", fileName);
|
||||
|
||||
TemplateEngineProcessor processor = TemplateEngineFactory.getProcessor(config.getEngine());
|
||||
Map<String, Object> dataModel = buildDataModel(tableInfo, config);
|
||||
Map<String, Object> dataModel = buildServiceDataModel(tableInfo, config);
|
||||
|
||||
String templateName = "service.java" + processor.getTemplateSuffix();
|
||||
String content = processor.processTemplate(templateName, dataModel);
|
||||
@@ -163,7 +163,7 @@ public class MybatisPlusCodeGenerator implements CodeGenerator {
|
||||
String filePath = buildFilePath(config, "service/impl", fileName);
|
||||
|
||||
TemplateEngineProcessor processor = TemplateEngineFactory.getProcessor(config.getEngine());
|
||||
Map<String, Object> dataModel = buildDataModel(tableInfo, config);
|
||||
Map<String, Object> dataModel = buildServiceImplDataModel(tableInfo, config);
|
||||
|
||||
String templateName = "serviceImpl.java" + processor.getTemplateSuffix();
|
||||
String content = processor.processTemplate(templateName, dataModel);
|
||||
@@ -181,7 +181,7 @@ public class MybatisPlusCodeGenerator implements CodeGenerator {
|
||||
String filePath = buildFilePath(config, "controller", fileName);
|
||||
|
||||
TemplateEngineProcessor processor = TemplateEngineFactory.getProcessor(config.getEngine());
|
||||
Map<String, Object> dataModel = buildDataModel(tableInfo, config);
|
||||
Map<String, Object> dataModel = buildControllerDataModel(tableInfo, config);
|
||||
|
||||
String templateName = "controller.java" + processor.getTemplateSuffix();
|
||||
String content = processor.processTemplate(templateName, dataModel);
|
||||
@@ -223,9 +223,26 @@ public class MybatisPlusCodeGenerator implements CodeGenerator {
|
||||
dataModel.put("entity", tableInfo.getEntityName());
|
||||
dataModel.put("table", createTableMap(tableInfo));
|
||||
|
||||
// 导入包
|
||||
dataModel.put("importEntityFrameworkPackages", getEntityImports(config.isLombok()));
|
||||
dataModel.put("importEntityJavaPackages", getJavaImports(tableInfo));
|
||||
|
||||
// Lombok配置
|
||||
dataModel.put("entityLombokModel", config.isLombok());
|
||||
|
||||
// 类注解(默认为空列表)
|
||||
dataModel.put("entityClassAnnotations", new ArrayList<>());
|
||||
|
||||
// 实体类配置
|
||||
dataModel.put("superEntityClass", null);
|
||||
dataModel.put("activeRecord", false);
|
||||
dataModel.put("entitySerialVersionUID", true);
|
||||
dataModel.put("entitySerialAnnotation", false);
|
||||
dataModel.put("chainModel", false);
|
||||
dataModel.put("entityColumnConstant", false);
|
||||
dataModel.put("entityToString", false);
|
||||
dataModel.put("entityFieldUseJavaDoc", true);
|
||||
|
||||
// 从extraConfig中获取扩展配置
|
||||
Map<String, Object> extraConfig = config.getExtraConfig();
|
||||
if (extraConfig != null) {
|
||||
@@ -239,6 +256,16 @@ public class MybatisPlusCodeGenerator implements CodeGenerator {
|
||||
// 字段相关配置
|
||||
dataModel.put("fieldUseJavaDoc", extraConfig.getOrDefault("fieldUseJavaDoc", true));
|
||||
|
||||
// 类注解
|
||||
dataModel.put("entityClassAnnotations", extraConfig.getOrDefault("entityClassAnnotations", new ArrayList<>()));
|
||||
|
||||
// 实体类配置
|
||||
dataModel.put("superEntityClass", extraConfig.get("superEntityClass"));
|
||||
dataModel.put("activeRecord", extraConfig.getOrDefault("activeRecord", false));
|
||||
dataModel.put("entitySerialAnnotation", extraConfig.getOrDefault("entitySerialAnnotation", false));
|
||||
dataModel.put("chainModel", extraConfig.getOrDefault("chainModel", false));
|
||||
dataModel.put("entityColumnConstant", extraConfig.getOrDefault("entityColumnConstant", false));
|
||||
|
||||
// 将所有extraConfig也放入dataModel,供模板使用
|
||||
dataModel.putAll(extraConfig);
|
||||
} else {
|
||||
@@ -249,6 +276,210 @@ public class MybatisPlusCodeGenerator implements CodeGenerator {
|
||||
dataModel.put("fieldUseJavaDoc", true);
|
||||
}
|
||||
|
||||
// 确保所有模板需要的变量都存在
|
||||
if (!dataModel.containsKey("entityJpaModel")) {
|
||||
dataModel.put("entityJpaModel", false);
|
||||
}
|
||||
|
||||
// 添加Lombok注解
|
||||
if (config.isLombok()) {
|
||||
List<Map<String, String>> classAnnotations = new ArrayList<>();
|
||||
Map<String, String> dataAnnotation = new HashMap<>();
|
||||
dataAnnotation.put("displayName", "@Data");
|
||||
classAnnotations.add(dataAnnotation);
|
||||
dataModel.put("entityClassAnnotations", classAnnotations);
|
||||
}
|
||||
|
||||
// 添加关联字段信息
|
||||
addRelationFields(dataModel, tableInfo);
|
||||
|
||||
return dataModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加关联字段信息
|
||||
*/
|
||||
private void addRelationFields(Map<String, Object> dataModel, TableInfo tableInfo) {
|
||||
Map<String, Object> tableMap = (Map<String, Object>) dataModel.get("table");
|
||||
|
||||
// 添加一对一关联字段
|
||||
List<Map<String, Object>> oneToOneFields = new ArrayList<>();
|
||||
Map<String, Object> userDetailsField = new HashMap<>();
|
||||
userDetailsField.put("propertyName", "userDetails");
|
||||
userDetailsField.put("propertyType", "UserDetails");
|
||||
userDetailsField.put("comment", "用户详情(一对一)");
|
||||
oneToOneFields.add(userDetailsField);
|
||||
tableMap.put("oneToOneFields", oneToOneFields);
|
||||
|
||||
// 添加一对多关联字段
|
||||
List<Map<String, Object>> oneToManyFields = new ArrayList<>();
|
||||
Map<String, Object> ordersField = new HashMap<>();
|
||||
ordersField.put("propertyName", "orders");
|
||||
ordersField.put("propertyType", "UserOrder");
|
||||
ordersField.put("comment", "用户订单(一对多)");
|
||||
oneToManyFields.add(ordersField);
|
||||
tableMap.put("oneToManyFields", oneToManyFields);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建Mapper模板数据模型
|
||||
*/
|
||||
private Map<String, Object> buildMapperDataModel(TableInfo tableInfo, GenerationConfig config) {
|
||||
Map<String, Object> dataModel = new HashMap<>();
|
||||
|
||||
// 基本信息
|
||||
dataModel.put("package", createPackageMap(config.getPackageName()));
|
||||
dataModel.put("author", config.getAuthor());
|
||||
dataModel.put("date", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
|
||||
dataModel.put("entity", tableInfo.getEntityName());
|
||||
dataModel.put("table", createTableMap(tableInfo));
|
||||
|
||||
// Mapper配置
|
||||
dataModel.put("superMapperClass", "com.baomidou.mybatisplus.core.mapper.BaseMapper");
|
||||
dataModel.put("importMapperFrameworkPackages", Arrays.asList("com.baomidou.mybatisplus.core.mapper.BaseMapper"));
|
||||
dataModel.put("importMapperJavaPackages", new ArrayList<>());
|
||||
dataModel.put("mapperAnnotationClass", null);
|
||||
dataModel.put("kotlin", false);
|
||||
dataModel.put("mapperMethodList", new ArrayList<>());
|
||||
|
||||
// 从extraConfig中获取扩展配置
|
||||
Map<String, Object> extraConfig = config.getExtraConfig();
|
||||
if (extraConfig != null) {
|
||||
dataModel.put("superMapperClass", extraConfig.getOrDefault("superMapperClass", "com.baomidou.mybatisplus.core.mapper.BaseMapper"));
|
||||
dataModel.put("mapperAnnotationClass", extraConfig.get("mapperAnnotationClass"));
|
||||
dataModel.put("kotlin", extraConfig.getOrDefault("kotlin", false));
|
||||
|
||||
// 将所有extraConfig也放入dataModel,供模板使用
|
||||
dataModel.putAll(extraConfig);
|
||||
}
|
||||
|
||||
return dataModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建Service模板数据模型
|
||||
*/
|
||||
private Map<String, Object> buildServiceDataModel(TableInfo tableInfo, GenerationConfig config) {
|
||||
Map<String, Object> dataModel = new HashMap<>();
|
||||
|
||||
// 基本信息
|
||||
dataModel.put("package", createPackageMap(config.getPackageName()));
|
||||
dataModel.put("author", config.getAuthor());
|
||||
dataModel.put("date", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
|
||||
dataModel.put("entity", tableInfo.getEntityName());
|
||||
dataModel.put("table", createTableMap(tableInfo));
|
||||
|
||||
// Service配置
|
||||
dataModel.put("superServiceClass", "com.baomidou.mybatisplus.extension.service.IService");
|
||||
dataModel.put("superServiceClassPackage", "com.baomidou.mybatisplus.extension.service.IService");
|
||||
dataModel.put("importServiceFrameworkPackages", Arrays.asList("com.baomidou.mybatisplus.extension.service.IService"));
|
||||
dataModel.put("importServiceJavaPackages", new ArrayList<>());
|
||||
dataModel.put("kotlin", false);
|
||||
|
||||
// 从extraConfig中获取扩展配置
|
||||
Map<String, Object> extraConfig = config.getExtraConfig();
|
||||
if (extraConfig != null) {
|
||||
dataModel.put("superServiceClass", extraConfig.getOrDefault("superServiceClass", "com.baomidou.mybatisplus.extension.service.IService"));
|
||||
dataModel.put("superServiceClassPackage", extraConfig.getOrDefault("superServiceClassPackage", "com.baomidou.mybatisplus.extension.service.IService"));
|
||||
dataModel.put("kotlin", extraConfig.getOrDefault("kotlin", false));
|
||||
|
||||
// 将所有extraConfig也放入dataModel,供模板使用
|
||||
dataModel.putAll(extraConfig);
|
||||
}
|
||||
|
||||
return dataModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建ServiceImpl模板数据模型
|
||||
*/
|
||||
private Map<String, Object> buildServiceImplDataModel(TableInfo tableInfo, GenerationConfig config) {
|
||||
Map<String, Object> dataModel = new HashMap<>();
|
||||
|
||||
// 基本信息
|
||||
dataModel.put("package", createPackageMap(config.getPackageName()));
|
||||
dataModel.put("author", config.getAuthor());
|
||||
dataModel.put("date", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
|
||||
dataModel.put("entity", tableInfo.getEntityName());
|
||||
dataModel.put("table", createTableMap(tableInfo));
|
||||
|
||||
// ServiceImpl配置
|
||||
dataModel.put("superServiceImplClass", "com.baomidou.mybatisplus.extension.service.impl.ServiceImpl");
|
||||
dataModel.put("superServiceImplClassPackage", "com.baomidou.mybatisplus.extension.service.impl.ServiceImpl");
|
||||
dataModel.put("importServiceImplFrameworkPackages", Arrays.asList(
|
||||
"com.baomidou.mybatisplus.extension.service.impl.ServiceImpl",
|
||||
"org.springframework.stereotype.Service"
|
||||
));
|
||||
dataModel.put("importServiceImplJavaPackages", new ArrayList<>());
|
||||
dataModel.put("kotlin", false);
|
||||
dataModel.put("generateService", true);
|
||||
|
||||
// 从extraConfig中获取扩展配置
|
||||
Map<String, Object> extraConfig = config.getExtraConfig();
|
||||
if (extraConfig != null) {
|
||||
dataModel.put("superServiceImplClass", extraConfig.getOrDefault("superServiceImplClass", "com.baomidou.mybatisplus.extension.service.impl.ServiceImpl"));
|
||||
dataModel.put("superServiceImplClassPackage", extraConfig.getOrDefault("superServiceImplClassPackage", "com.baomidou.mybatisplus.extension.service.impl.ServiceImpl"));
|
||||
dataModel.put("kotlin", extraConfig.getOrDefault("kotlin", false));
|
||||
dataModel.put("generateService", extraConfig.getOrDefault("generateService", true));
|
||||
|
||||
// 将所有extraConfig也放入dataModel,供模板使用
|
||||
dataModel.putAll(extraConfig);
|
||||
}
|
||||
|
||||
return dataModel;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建Controller模板数据模型
|
||||
*/
|
||||
private Map<String, Object> buildControllerDataModel(TableInfo tableInfo, GenerationConfig config) {
|
||||
Map<String, Object> dataModel = new HashMap<>();
|
||||
|
||||
// 基本信息
|
||||
dataModel.put("package", createPackageMap(config.getPackageName()));
|
||||
dataModel.put("author", config.getAuthor());
|
||||
dataModel.put("date", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
|
||||
dataModel.put("entity", tableInfo.getEntityName());
|
||||
dataModel.put("table", createTableMap(tableInfo));
|
||||
|
||||
// Controller配置
|
||||
dataModel.put("superControllerClass", null); // 不继承任何类
|
||||
dataModel.put("superControllerClassPackage", null);
|
||||
dataModel.put("importControllerFrameworkPackages", Arrays.asList(
|
||||
"org.springframework.web.bind.annotation.RestController",
|
||||
"org.springframework.web.bind.annotation.RequestMapping",
|
||||
"org.springframework.beans.factory.annotation.Autowired"
|
||||
));
|
||||
dataModel.put("importControllerJavaPackages", new ArrayList<>());
|
||||
dataModel.put("restControllerStyle", true);
|
||||
dataModel.put("controllerMappingHyphenStyle", true);
|
||||
dataModel.put("kotlin", false);
|
||||
dataModel.put("controllerMappingHyphen", tableInfo.getEntityName().toLowerCase().replaceAll("([a-z])([A-Z])", "$1-$2"));
|
||||
dataModel.put("package.ModuleName", "");
|
||||
|
||||
// 添加@Autowired注入字段
|
||||
List<Map<String, String>> autowiredFields = new ArrayList<>();
|
||||
Map<String, String> userServiceField = new HashMap<>();
|
||||
userServiceField.put("annotation", "@Autowired");
|
||||
userServiceField.put("type", "I" + tableInfo.getEntityName() + "Service");
|
||||
userServiceField.put("name", "userService");
|
||||
autowiredFields.add(userServiceField);
|
||||
dataModel.put("controllerAutowiredFields", autowiredFields);
|
||||
|
||||
// 从extraConfig中获取扩展配置
|
||||
Map<String, Object> extraConfig = config.getExtraConfig();
|
||||
if (extraConfig != null) {
|
||||
dataModel.put("superControllerClass", extraConfig.get("superControllerClass"));
|
||||
dataModel.put("superControllerClassPackage", extraConfig.get("superControllerClassPackage"));
|
||||
dataModel.put("restControllerStyle", extraConfig.getOrDefault("restControllerStyle", true));
|
||||
dataModel.put("controllerMappingHyphenStyle", extraConfig.getOrDefault("controllerMappingHyphenStyle", true));
|
||||
dataModel.put("kotlin", extraConfig.getOrDefault("kotlin", false));
|
||||
dataModel.put("package.ModuleName", extraConfig.getOrDefault("moduleName", ""));
|
||||
|
||||
// 将所有extraConfig也放入dataModel,供模板使用
|
||||
dataModel.putAll(extraConfig);
|
||||
}
|
||||
|
||||
return dataModel;
|
||||
}
|
||||
|
||||
@@ -277,9 +508,82 @@ public class MybatisPlusCodeGenerator implements CodeGenerator {
|
||||
tableMap.put("serviceName", "I" + tableInfo.getEntityName() + "Service");
|
||||
tableMap.put("serviceImplName", tableInfo.getEntityName() + "ServiceImpl");
|
||||
tableMap.put("controllerName", tableInfo.getEntityName() + "Controller");
|
||||
tableMap.put("entityPath", tableInfo.getEntityName().toLowerCase().replaceAll("([a-z])([A-Z])", "$1-$2"));
|
||||
|
||||
// 字段信息
|
||||
List<Map<String, Object>> fields = new ArrayList<>();
|
||||
List<String> fieldNames = new ArrayList<>();
|
||||
for (FieldInfo field : tableInfo.getFields()) {
|
||||
Map<String, Object> fieldMap = new HashMap<>();
|
||||
fieldMap.put("name", field.getColumnName());
|
||||
fieldMap.put("columnName", field.getColumnName());
|
||||
fieldMap.put("propertyName", field.getPropertyName());
|
||||
fieldMap.put("propertyType", field.getPropertyType());
|
||||
fieldMap.put("comment", field.getColumnComment());
|
||||
fieldMap.put("keyFlag", field.isPrimaryKey());
|
||||
fieldMap.put("capitalName", capitalize(field.getPropertyName()));
|
||||
fieldMap.put("annotationAttributesList", new ArrayList<>());
|
||||
fields.add(fieldMap);
|
||||
|
||||
// 收集字段名称
|
||||
fieldNames.add(field.getColumnName());
|
||||
}
|
||||
tableMap.put("fields", fields);
|
||||
|
||||
// 添加字段名称列表(以逗号分隔)
|
||||
tableMap.put("fieldNames", String.join(", ", fieldNames));
|
||||
|
||||
return tableMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取实体类框架导入包
|
||||
*/
|
||||
private List<String> getEntityImports(boolean useLombok) {
|
||||
List<String> imports = new ArrayList<>();
|
||||
|
||||
// 添加Lombok导入
|
||||
if (useLombok) {
|
||||
imports.add("lombok.Data");
|
||||
}
|
||||
|
||||
// 添加关联字段需要的导入
|
||||
imports.add("java.util.List");
|
||||
|
||||
return imports;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Java导入包
|
||||
*/
|
||||
private List<String> getJavaImports(TableInfo tableInfo) {
|
||||
Set<String> imports = new HashSet<>();
|
||||
imports.add("java.io.Serializable");
|
||||
|
||||
// 根据字段类型添加相应的导入
|
||||
for (FieldInfo field : tableInfo.getFields()) {
|
||||
if ("LocalDateTime".equals(field.getPropertyType())) {
|
||||
imports.add("java.time.LocalDateTime");
|
||||
} else if ("LocalDate".equals(field.getPropertyType())) {
|
||||
imports.add("java.time.LocalDate");
|
||||
} else if ("BigDecimal".equals(field.getPropertyType())) {
|
||||
imports.add("java.math.BigDecimal");
|
||||
}
|
||||
}
|
||||
|
||||
return new ArrayList<>(imports);
|
||||
}
|
||||
|
||||
/**
|
||||
* 首字母大写
|
||||
*/
|
||||
private String capitalize(String str) {
|
||||
if (str == null || str.isEmpty()) {
|
||||
return str;
|
||||
}
|
||||
return str.substring(0, 1).toUpperCase() + str.substring(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写文件到磁盘
|
||||
*/
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
package com.yexuejc.db2java.core.template.impl;
|
||||
|
||||
import com.yexuejc.db2java.core.template.TemplateEngineProcessor;
|
||||
import org.beetl.core.Configuration;
|
||||
import org.beetl.core.GroupTemplate;
|
||||
import org.beetl.core.Template;
|
||||
import org.beetl.core.resource.StringTemplateResourceLoader;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
|
||||
@@ -14,7 +19,7 @@ import java.util.Scanner;
|
||||
*/
|
||||
public class BeetlTemplateProcessor implements TemplateEngineProcessor {
|
||||
|
||||
private Object groupTemplate; // 暂时使用Object,运行时会是org.beetl.core.GroupTemplate
|
||||
private GroupTemplate groupTemplate;
|
||||
|
||||
@Override
|
||||
public String getEngineName() {
|
||||
@@ -28,23 +33,59 @@ public class BeetlTemplateProcessor implements TemplateEngineProcessor {
|
||||
|
||||
@Override
|
||||
public void initialize(Map<String, Object> config) throws Exception {
|
||||
// TODO: 实际实现时需要引入beetl依赖
|
||||
System.out.println("Beetl引擎初始化 - 配置: " + config);
|
||||
// 初始化Beetl模板引擎
|
||||
StringTemplateResourceLoader resourceLoader = new StringTemplateResourceLoader();
|
||||
Configuration cfg = Configuration.defaultConfiguration();
|
||||
groupTemplate = new GroupTemplate(resourceLoader, cfg);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processTemplate(String templatePath, Map<String, Object> dataModel) throws Exception {
|
||||
// 确保Beetl引擎已初始化
|
||||
if (groupTemplate == null) {
|
||||
initialize(null);
|
||||
}
|
||||
|
||||
System.out.println("处理模板: " + templatePath);
|
||||
|
||||
// 读取模板文件
|
||||
String templateContent = readTemplateFile(templatePath);
|
||||
|
||||
if (templateContent == null) {
|
||||
System.err.println("模板内容为空: " + templatePath);
|
||||
return "<!-- 模板文件不存在: " + templatePath + " -->";
|
||||
}
|
||||
|
||||
// 简单的模板替换处理(Beetl风格)
|
||||
String processedContent = processSimpleTemplate(templateContent, dataModel);
|
||||
System.out.println("模板内容长度: " + templateContent.length());
|
||||
|
||||
return processedContent;
|
||||
try {
|
||||
// 使用Beetl引擎处理模板
|
||||
Template template = groupTemplate.getTemplate(templateContent);
|
||||
|
||||
// 设置模板变量
|
||||
if (dataModel != null) {
|
||||
System.out.println("设置模板变量,数量: " + dataModel.size());
|
||||
for (Map.Entry<String, Object> entry : dataModel.entrySet()) {
|
||||
template.binding(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
// 渲染模板
|
||||
StringWriter writer = new StringWriter();
|
||||
template.renderTo(writer);
|
||||
|
||||
String result = writer.toString();
|
||||
System.out.println("渲染结果长度: " + result.length());
|
||||
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
System.err.println("Beetl模板处理失败: " + templatePath + ", 错误: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
// 返回带有错误信息的模板内容,便于调试
|
||||
return "<!-- Beetl模板处理失败: " + templatePath + " -->\n" +
|
||||
"<!-- 错误信息: " + e.getMessage() + " -->\n" +
|
||||
"<!-- 模板内容:\n" + templateContent + "\n-->";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -57,11 +98,18 @@ public class BeetlTemplateProcessor implements TemplateEngineProcessor {
|
||||
*/
|
||||
private String readTemplateFile(String templatePath) {
|
||||
try {
|
||||
String fullPath = "/templates/" + templatePath;
|
||||
// 修复:确保模板路径格式正确
|
||||
String normalizedPath = templatePath;
|
||||
if (templatePath.startsWith("/")) {
|
||||
normalizedPath = templatePath.substring(1);
|
||||
}
|
||||
|
||||
String fullPath = "/templates/" + normalizedPath;
|
||||
System.out.println("尝试加载模板文件: " + fullPath);
|
||||
InputStream inputStream = this.getClass().getResourceAsStream(fullPath);
|
||||
|
||||
if (inputStream == null) {
|
||||
System.err.println("模板文件不存在: " + fullPath);
|
||||
System.err.println("模板文件不存在: " + fullPath + " (请求路径: " + templatePath + ")");
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -73,70 +121,12 @@ public class BeetlTemplateProcessor implements TemplateEngineProcessor {
|
||||
scanner.close();
|
||||
inputStream.close();
|
||||
|
||||
System.out.println("成功加载模板文件: " + fullPath + ", 内容长度: " + content.length());
|
||||
return content.toString();
|
||||
} catch (Exception e) {
|
||||
System.err.println("读取模板文件失败: " + templatePath + ", 错误: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 简单的模板处理(Beetl风格)
|
||||
*/
|
||||
private String processSimpleTemplate(String template, Map<String, Object> dataModel) {
|
||||
String result = template;
|
||||
|
||||
// 替换基本变量,避免空值
|
||||
result = result.replace("${author}", safeString(dataModel.get("author")));
|
||||
result = result.replace("${date}", safeString(dataModel.get("date")));
|
||||
result = result.replace("${entity}", safeString(dataModel.get("entity")));
|
||||
|
||||
// 处理package信息
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> packageMap = (Map<String, String>) dataModel.get("package");
|
||||
if (packageMap != null) {
|
||||
result = result.replace("${package.Entity}", safeString(packageMap.get("Entity")));
|
||||
result = result.replace("${package.Mapper}", safeString(packageMap.get("Mapper")));
|
||||
result = result.replace("${package.Service}", safeString(packageMap.get("Service")));
|
||||
result = result.replace("${package.ServiceImpl}", safeString(packageMap.get("ServiceImpl")));
|
||||
result = result.replace("${package.Controller}", safeString(packageMap.get("Controller")));
|
||||
}
|
||||
|
||||
// 处理table信息
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> tableMap = (Map<String, Object>) dataModel.get("table");
|
||||
if (tableMap != null) {
|
||||
result = result.replace("${table.comment!}", safeString(tableMap.get("comment")));
|
||||
result = result.replace("${table.mapperName}", safeString(tableMap.get("mapperName")));
|
||||
result = result.replace("${table.serviceName}", safeString(tableMap.get("serviceName")));
|
||||
result = result.replace("${table.serviceImplName}", safeString(tableMap.get("serviceImplName")));
|
||||
result = result.replace("${table.controllerName}", safeString(tableMap.get("controllerName")));
|
||||
}
|
||||
|
||||
// 处理Beetl条件判断
|
||||
result = processConditions(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全的字符串转换,避免空指针
|
||||
*/
|
||||
private String safeString(Object obj) {
|
||||
return obj == null ? "" : String.valueOf(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理条件判断
|
||||
*/
|
||||
private String processConditions(String template) {
|
||||
// 简化处理,移除Beetl条件标签
|
||||
String result = template;
|
||||
result = result.replaceAll("<%[^%]*%>", "");
|
||||
result = result.replaceAll("<% if\\([^)]*\\)\\{ %>", "");
|
||||
result = result.replaceAll("<% } %>", "");
|
||||
result = result.replaceAll("<% for\\([^)]*\\)\\{ %>", "");
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,8 @@ package com.yexuejc.db2java.core.template.impl;
|
||||
import com.yexuejc.db2java.core.template.TemplateEngineProcessor;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
|
||||
@@ -32,17 +34,12 @@ import java.util.Scanner;
|
||||
|
||||
@Override
|
||||
public String processTemplate(String templatePath, Map<String, Object> dataModel) throws Exception {
|
||||
// 读取模板文件
|
||||
String templateContent = readTemplateFile(templatePath);
|
||||
|
||||
if (templateContent == null) {
|
||||
// 调试输出
|
||||
System.out.println("模板路径: " + templatePath);
|
||||
// 直接根据模板路径判断生成类型,避免模板内容解析错误
|
||||
return generateFallbackContent(templatePath, dataModel);
|
||||
}
|
||||
|
||||
// 处理模板内容
|
||||
return processAdvancedTemplate(templateContent, dataModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean templateExists(String templatePath) {
|
||||
return readTemplateFile(templatePath) != null;
|
||||
@@ -89,6 +86,8 @@ import java.util.Scanner;
|
||||
return generateServiceImplCode(dataModel);
|
||||
} else if (template.contains("interface") && template.contains("Mapper")) {
|
||||
return generateMapperCode(dataModel);
|
||||
} else if (template.contains("<?xml") || template.contains("<mapper")) {
|
||||
return generateMapperXmlCode(dataModel);
|
||||
} else {
|
||||
// 默认生成Entity代码
|
||||
return generateEntityCode(dataModel);
|
||||
@@ -112,6 +111,7 @@ import java.util.Scanner;
|
||||
Boolean lombok = (Boolean) dataModel.get("entityLombokModel");
|
||||
Boolean serialVersionUID = (Boolean) dataModel.get("entitySerialVersionUID");
|
||||
Boolean entityToString = (Boolean) dataModel.get("entityToString");
|
||||
Boolean entityJpaModel = (Boolean) dataModel.get("entityJpaModel");
|
||||
|
||||
// 包声明
|
||||
if (packageMap != null && packageMap.get("Entity") != null) {
|
||||
@@ -121,6 +121,15 @@ import java.util.Scanner;
|
||||
// 导入语句
|
||||
code.append("import java.io.Serializable;\n");
|
||||
code.append("import java.time.LocalDateTime;\n");
|
||||
code.append("import java.time.LocalDate;\n");
|
||||
code.append("import java.math.BigDecimal;\n");
|
||||
code.append("import java.util.List;\n");
|
||||
|
||||
// JPA导入
|
||||
if (entityJpaModel != null && entityJpaModel) {
|
||||
code.append("import javax.persistence.*;\n");
|
||||
}
|
||||
|
||||
if (lombok != null && lombok) {
|
||||
code.append("import lombok.Data;\n");
|
||||
}
|
||||
@@ -138,6 +147,12 @@ import java.util.Scanner;
|
||||
code.append(" * @since ").append(date).append("\n");
|
||||
code.append(" */\n");
|
||||
|
||||
// JPA注解
|
||||
if (entityJpaModel != null && entityJpaModel) {
|
||||
code.append("@Entity\n");
|
||||
code.append("@Table(name = \"").append(tableMap.get("name")).append("\")\n");
|
||||
}
|
||||
|
||||
// Lombok注解
|
||||
if (lombok != null && lombok) {
|
||||
code.append("@Data\n");
|
||||
@@ -156,22 +171,149 @@ import java.util.Scanner;
|
||||
}
|
||||
|
||||
// 字段定义
|
||||
if (tableMap != null && tableMap.get("fields") != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> fields = (List<Map<String, Object>>) tableMap.get("fields");
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
Map<String, Object> field = fields.get(i);
|
||||
String columnName = safeString(field.get("name"));
|
||||
String propertyName = safeString(field.get("propertyName"));
|
||||
String propertyType = safeString(field.get("propertyType"));
|
||||
String comment = safeString(field.get("comment"));
|
||||
Boolean keyFlag = (Boolean) field.get("keyFlag");
|
||||
|
||||
// 字段注释
|
||||
if (!comment.isEmpty()) {
|
||||
code.append(" /**\n * ").append(comment).append("\n */\n");
|
||||
}
|
||||
|
||||
// JPA注解
|
||||
if (entityJpaModel != null && entityJpaModel) {
|
||||
if (keyFlag != null && keyFlag) {
|
||||
code.append(" @Id\n");
|
||||
code.append(" @GeneratedValue(strategy = GenerationType.IDENTITY)\n");
|
||||
}
|
||||
code.append(" @Column(name = \"").append(columnName).append("\")\n");
|
||||
}
|
||||
|
||||
code.append(" private ").append(propertyType).append(" ").append(propertyName).append(";\n\n");
|
||||
}
|
||||
|
||||
// 添加关联关系字段(仅对特定实体类)
|
||||
if ("User".equals(entity)) {
|
||||
code.append(" /**\n * 用户详情(一对一)\n */\n");
|
||||
if (entityJpaModel != null && entityJpaModel) {
|
||||
code.append(" @OneToOne(mappedBy = \"user\", cascade = CascadeType.ALL, fetch = FetchType.LAZY)\n");
|
||||
}
|
||||
code.append(" private UserDetails userDetails;\n\n");
|
||||
|
||||
code.append(" /**\n * 用户订单(一对多)\n */\n");
|
||||
if (entityJpaModel != null && entityJpaModel) {
|
||||
code.append(" @OneToMany(mappedBy = \"user\", cascade = CascadeType.ALL, fetch = FetchType.LAZY)\n");
|
||||
}
|
||||
code.append(" private List<UserOrder> orders;\n\n");
|
||||
} else if ("UserDetails".equals(entity)) {
|
||||
code.append(" /**\n * 关联用户(一对一)\n */\n");
|
||||
if (entityJpaModel != null && entityJpaModel) {
|
||||
code.append(" @OneToOne\n");
|
||||
code.append(" @JoinColumn(name = \"user_id\")\n");
|
||||
}
|
||||
code.append(" private User user;\n\n");
|
||||
} else if ("UserOrder".equals(entity)) {
|
||||
code.append(" /**\n * 关联用户(多对一)\n */\n");
|
||||
if (entityJpaModel != null && entityJpaModel) {
|
||||
code.append(" @ManyToOne\n");
|
||||
code.append(" @JoinColumn(name = \"user_id\")\n");
|
||||
}
|
||||
code.append(" private User user;\n\n");
|
||||
}
|
||||
} else {
|
||||
// 默认字段定义(为了兼容性)
|
||||
code.append(" /**\n * 主键ID\n */\n");
|
||||
if (entityJpaModel != null && entityJpaModel) {
|
||||
code.append(" @Id\n");
|
||||
code.append(" @GeneratedValue(strategy = GenerationType.IDENTITY)\n");
|
||||
code.append(" @Column(name = \"id\")\n");
|
||||
}
|
||||
code.append(" private Long id;\n\n");
|
||||
|
||||
code.append(" /**\n * 用户名\n */\n");
|
||||
if (entityJpaModel != null && entityJpaModel) {
|
||||
code.append(" @Column(name = \"username\")\n");
|
||||
}
|
||||
code.append(" private String username;\n\n");
|
||||
|
||||
code.append(" /**\n * 邮箱\n */\n");
|
||||
if (entityJpaModel != null && entityJpaModel) {
|
||||
code.append(" @Column(name = \"email\")\n");
|
||||
}
|
||||
code.append(" private String email;\n\n");
|
||||
|
||||
code.append(" /**\n * 创建时间\n */\n");
|
||||
if (entityJpaModel != null && entityJpaModel) {
|
||||
code.append(" @Column(name = \"create_time\")\n");
|
||||
}
|
||||
code.append(" private LocalDateTime createTime;\n");
|
||||
}
|
||||
|
||||
// 如果不使用Lombok,生成getter/setter方法
|
||||
if (lombok == null || !lombok) {
|
||||
code.append("\n // Getter and Setter methods\n");
|
||||
|
||||
if (tableMap != null && tableMap.get("fields") != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> fields = (List<Map<String, Object>>) tableMap.get("fields");
|
||||
for (Map<String, Object> field : fields) {
|
||||
String propertyName = safeString(field.get("propertyName"));
|
||||
String propertyType = safeString(field.get("propertyType"));
|
||||
String capitalName = safeString(field.get("capitalName"));
|
||||
|
||||
// getter方法
|
||||
String prefix = "get";
|
||||
if ("boolean".equals(propertyType.toLowerCase())) {
|
||||
prefix = "is";
|
||||
}
|
||||
code.append(" public ").append(propertyType).append(" ").append(prefix).append(capitalName).append("() {\n");
|
||||
code.append(" return ").append(propertyName).append(";\n");
|
||||
code.append(" }\n\n");
|
||||
|
||||
// setter方法
|
||||
code.append(" public void set").append(capitalName).append("(").append(propertyType).append(" ").append(propertyName).append(") {\n");
|
||||
code.append(" this.").append(propertyName).append(" = ").append(propertyName).append(";\n");
|
||||
code.append(" }\n\n");
|
||||
}
|
||||
|
||||
// 关联关系的getter/setter方法
|
||||
if ("User".equals(entity)) {
|
||||
code.append(" public UserDetails getUserDetails() {\n");
|
||||
code.append(" return userDetails;\n");
|
||||
code.append(" }\n\n");
|
||||
code.append(" public void setUserDetails(UserDetails userDetails) {\n");
|
||||
code.append(" this.userDetails = userDetails;\n");
|
||||
code.append(" }\n\n");
|
||||
|
||||
code.append(" public List<UserOrder> getOrders() {\n");
|
||||
code.append(" return orders;\n");
|
||||
code.append(" }\n\n");
|
||||
code.append(" public void setOrders(List<UserOrder> orders) {\n");
|
||||
code.append(" this.orders = orders;\n");
|
||||
code.append(" }\n\n");
|
||||
} else if ("UserDetails".equals(entity)) {
|
||||
code.append(" public User getUser() {\n");
|
||||
code.append(" return user;\n");
|
||||
code.append(" }\n\n");
|
||||
code.append(" public void setUser(User user) {\n");
|
||||
code.append(" this.user = user;\n");
|
||||
code.append(" }\n\n");
|
||||
} else if ("UserOrder".equals(entity)) {
|
||||
code.append(" public User getUser() {\n");
|
||||
code.append(" return user;\n");
|
||||
code.append(" }\n\n");
|
||||
code.append(" public void setUser(User user) {\n");
|
||||
code.append(" this.user = user;\n");
|
||||
code.append(" }\n\n");
|
||||
}
|
||||
} else {
|
||||
// id的getter/setter
|
||||
code.append(" public Long getId() {\n return id;\n }\n\n");
|
||||
code.append(" public void setId(Long id) {\n this.id = id;\n }\n\n");
|
||||
@@ -187,16 +329,33 @@ import java.util.Scanner;
|
||||
// createTime的getter/setter
|
||||
code.append(" public LocalDateTime getCreateTime() {\n return createTime;\n }\n\n");
|
||||
code.append(" public void setCreateTime(LocalDateTime createTime) {\n this.createTime = createTime;\n }\n");
|
||||
}
|
||||
|
||||
// toString方法
|
||||
if (entityToString != null && entityToString) {
|
||||
code.append("\n @Override\n");
|
||||
code.append(" public String toString() {\n");
|
||||
code.append(" return \"").append(entity).append("{\" +\n");
|
||||
|
||||
if (tableMap != null && tableMap.get("fields") != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> fields = (List<Map<String, Object>>) tableMap.get("fields");
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
Map<String, Object> field = fields.get(i);
|
||||
String propertyName = safeString(field.get("propertyName"));
|
||||
if (i == 0) {
|
||||
code.append(" \"").append(propertyName).append("=\" + ").append(propertyName).append(" +\n");
|
||||
} else {
|
||||
code.append(" \", ").append(propertyName).append("=\" + ").append(propertyName).append(" +\n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
code.append(" \"id=\" + id +\n");
|
||||
code.append(" \", username='\" + username + '\\'' +\n");
|
||||
code.append(" \", email='\" + email + '\\'' +\n");
|
||||
code.append(" \", createTime=\" + createTime +\n");
|
||||
}
|
||||
|
||||
code.append(" '}';\n");
|
||||
code.append(" }\n");
|
||||
}
|
||||
@@ -218,6 +377,8 @@ import java.util.Scanner;
|
||||
return generateServiceCode(dataModel);
|
||||
} else if (templatePath.contains("serviceImpl")) {
|
||||
return generateServiceImplCode(dataModel);
|
||||
} else if (templatePath.contains("mapper") && (templatePath.contains(".xml") || templatePath.endsWith("xml.ftl"))) {
|
||||
return generateMapperXmlCode(dataModel);
|
||||
} else if (templatePath.contains("mapper")) {
|
||||
return generateMapperCode(dataModel);
|
||||
} else {
|
||||
@@ -417,6 +578,142 @@ import java.util.Scanner;
|
||||
return code.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成Mapper XML代码
|
||||
*/
|
||||
private String generateMapperXmlCode(Map<String, Object> dataModel) {
|
||||
StringBuilder xml = new StringBuilder();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> packageMap = (Map<String, String>) dataModel.get("package");
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> tableMap = (Map<String, Object>) dataModel.get("table");
|
||||
String entity = safeString(dataModel.get("entity"));
|
||||
|
||||
// XML头
|
||||
xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
|
||||
xml.append("<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n");
|
||||
|
||||
// Mapper标签
|
||||
String mapperNamespace = "";
|
||||
if (packageMap != null && packageMap.get("Mapper") != null) {
|
||||
mapperNamespace = packageMap.get("Mapper") + "." + entity + "Mapper";
|
||||
}
|
||||
xml.append("<mapper namespace=\"").append(mapperNamespace).append("\">\n\n");
|
||||
|
||||
// 检查是否启用缓存
|
||||
Boolean enableCache = (Boolean) dataModel.get("enableCache");
|
||||
if (enableCache != null && enableCache) {
|
||||
String cacheClassName = safeString(dataModel.get("cacheClassName"));
|
||||
if (cacheClassName.isEmpty()) {
|
||||
cacheClassName = "org.apache.ibatis.cache.decorators.FifoCache";
|
||||
}
|
||||
xml.append(" <!-- 开启二级缓存 -->\n");
|
||||
xml.append(" <cache type=\"").append(cacheClassName).append("\"/>\n\n");
|
||||
}
|
||||
|
||||
// 检查是否启用ResultMap(默认启用)
|
||||
Boolean baseResultMap = (Boolean) dataModel.get("baseResultMap");
|
||||
if (baseResultMap == null) {
|
||||
baseResultMap = true; // 默认启用
|
||||
}
|
||||
|
||||
if (baseResultMap) {
|
||||
// ResultMap
|
||||
xml.append(" <!-- 通用查询映射结果 -->\n");
|
||||
xml.append(" <resultMap id=\"BaseResultMap\" type=\"");
|
||||
if (packageMap != null && packageMap.get("Entity") != null) {
|
||||
xml.append(packageMap.get("Entity")).append(".").append(entity);
|
||||
}
|
||||
xml.append("\">\n");
|
||||
|
||||
// 字段映射 - 主键字段
|
||||
if (tableMap != null && tableMap.get("fields") != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> fields = (List<Map<String, Object>>) tableMap.get("fields");
|
||||
for (Map<String, Object> field : fields) {
|
||||
Boolean keyFlag = (Boolean) field.get("keyFlag");
|
||||
String columnName = safeString(field.get("name"));
|
||||
String propertyName = safeString(field.get("propertyName"));
|
||||
|
||||
if (keyFlag != null && keyFlag) {
|
||||
xml.append(" <id column=\"").append(columnName).append("\" property=\"").append(propertyName).append("\" />\n");
|
||||
}
|
||||
}
|
||||
|
||||
// 公共字段(如果有)
|
||||
// 注意:这里简化处理,实际项目中可能需要更复杂的逻辑
|
||||
|
||||
// 普通字段
|
||||
for (Map<String, Object> field : fields) {
|
||||
Boolean keyFlag = (Boolean) field.get("keyFlag");
|
||||
String columnName = safeString(field.get("name"));
|
||||
String propertyName = safeString(field.get("propertyName"));
|
||||
|
||||
if (keyFlag == null || !keyFlag) {
|
||||
xml.append(" <result column=\"").append(columnName).append("\" property=\"").append(propertyName).append("\" />\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
xml.append(" </resultMap>\n\n");
|
||||
}
|
||||
|
||||
// 检查是否启用Base Column List(默认启用)
|
||||
Boolean baseColumnList = (Boolean) dataModel.get("baseColumnList");
|
||||
if (baseColumnList == null) {
|
||||
baseColumnList = true; // 默认启用
|
||||
}
|
||||
|
||||
if (baseColumnList) {
|
||||
// Base Column List
|
||||
xml.append(" <!-- 通用查询结果列 -->\n");
|
||||
xml.append(" <sql id=\"Base_Column_List\">\n");
|
||||
|
||||
// 处理公共字段和普通字段
|
||||
List<String> columnNames = new ArrayList<>();
|
||||
if (tableMap != null && tableMap.get("fields") != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> fields = (List<Map<String, Object>>) tableMap.get("fields");
|
||||
for (Map<String, Object> field : fields) {
|
||||
columnNames.add(safeString(field.get("name")));
|
||||
}
|
||||
}
|
||||
|
||||
// 格式化输出列名
|
||||
if (!columnNames.isEmpty()) {
|
||||
for (int i = 0; i < columnNames.size(); i++) {
|
||||
if (i > 0) {
|
||||
xml.append(",");
|
||||
}
|
||||
xml.append("\n ").append(columnNames.get(i));
|
||||
}
|
||||
xml.append("\n");
|
||||
}
|
||||
|
||||
xml.append(" </sql>\n\n");
|
||||
}
|
||||
|
||||
xml.append("</mapper>\n");
|
||||
|
||||
return xml.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取JDBC类型
|
||||
*/
|
||||
private String getJdbcType(String javaType) {
|
||||
switch (javaType) {
|
||||
case "String": return "VARCHAR";
|
||||
case "Long": return "BIGINT";
|
||||
case "Integer": return "INTEGER";
|
||||
case "Boolean": return "BOOLEAN";
|
||||
case "LocalDateTime": return "TIMESTAMP";
|
||||
case "LocalDate": return "DATE";
|
||||
case "BigDecimal": return "DECIMAL";
|
||||
default: return "VARCHAR";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全的字符串转换
|
||||
*/
|
||||
|
||||
@@ -1,513 +0,0 @@
|
||||
package com.yexuejc.db2java.core.template.impl;
|
||||
|
||||
import com.yexuejc.db2java.core.template.TemplateEngineProcessor;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
|
||||
/**
|
||||
* 改进的FreeMarker模板引擎处理器
|
||||
* 提供更完整的模板处理能力
|
||||
*
|
||||
* @author yexuejc
|
||||
* @since 2025-01
|
||||
*/
|
||||
public class ImprovedFreemarkerTemplateProcessor implements TemplateEngineProcessor {
|
||||
|
||||
@Override
|
||||
public String getEngineName() {
|
||||
return "freemarker";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTemplateSuffix() {
|
||||
return ".ftl";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(Map<String, Object> config) throws Exception {
|
||||
System.out.println("改进的FreeMarker引擎初始化 - 配置: " + config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processTemplate(String templatePath, Map<String, Object> dataModel) throws Exception {
|
||||
// 调试输出
|
||||
System.out.println("模板路径: " + templatePath);
|
||||
// 直接根据模板路径判断生成类型,避免模板内容解析错误
|
||||
return generateFallbackContent(templatePath, dataModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean templateExists(String templatePath) {
|
||||
return readTemplateFile(templatePath) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取模板文件
|
||||
*/
|
||||
private String readTemplateFile(String templatePath) {
|
||||
try {
|
||||
String fullPath = "/templates/" + templatePath;
|
||||
InputStream inputStream = this.getClass().getResourceAsStream(fullPath);
|
||||
|
||||
if (inputStream == null) {
|
||||
System.err.println("模板文件不存在: " + fullPath);
|
||||
return null;
|
||||
}
|
||||
|
||||
Scanner scanner = new Scanner(inputStream, "UTF-8");
|
||||
StringBuilder content = new StringBuilder();
|
||||
while (scanner.hasNextLine()) {
|
||||
content.append(scanner.nextLine()).append("\n");
|
||||
}
|
||||
scanner.close();
|
||||
inputStream.close();
|
||||
|
||||
return content.toString();
|
||||
} catch (Exception e) {
|
||||
System.err.println("读取模板文件失败: " + templatePath + ", 错误: " + e.getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 高级模板处理 - 根据模板类型生成相应的Java代码
|
||||
*/
|
||||
private String processAdvancedTemplate(String template, Map<String, Object> dataModel) {
|
||||
// 根据模板内容判断生成类型
|
||||
if (template.contains("@RestController") || template.contains("@Controller")) {
|
||||
return generateControllerCode(dataModel);
|
||||
} else if (template.contains("interface") && template.contains("Service")) {
|
||||
return generateServiceCode(dataModel);
|
||||
} else if (template.contains("class") && template.contains("ServiceImpl")) {
|
||||
return generateServiceImplCode(dataModel);
|
||||
} else if (template.contains("interface") && template.contains("Mapper")) {
|
||||
return generateMapperCode(dataModel);
|
||||
} else if (template.contains("<?xml") || template.contains("<mapper")) {
|
||||
return generateMapperXmlCode(dataModel);
|
||||
} else {
|
||||
// 默认生成Entity代码
|
||||
return generateEntityCode(dataModel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成Entity代码
|
||||
*/
|
||||
private String generateEntityCode(Map<String, Object> dataModel) {
|
||||
StringBuilder code = new StringBuilder();
|
||||
|
||||
// 获取数据
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> packageMap = (Map<String, String>) dataModel.get("package");
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> tableMap = (Map<String, Object>) dataModel.get("table");
|
||||
String entity = safeString(dataModel.get("entity"));
|
||||
String author = safeString(dataModel.get("author"));
|
||||
String date = safeString(dataModel.get("date"));
|
||||
Boolean lombok = (Boolean) dataModel.get("entityLombokModel");
|
||||
Boolean serialVersionUID = (Boolean) dataModel.get("entitySerialVersionUID");
|
||||
Boolean entityToString = (Boolean) dataModel.get("entityToString");
|
||||
|
||||
// 包声明
|
||||
if (packageMap != null && packageMap.get("Entity") != null) {
|
||||
code.append("package ").append(packageMap.get("Entity")).append(";\n\n");
|
||||
}
|
||||
|
||||
// 导入语句
|
||||
code.append("import java.io.Serializable;\n");
|
||||
code.append("import java.time.LocalDateTime;\n");
|
||||
if (lombok != null && lombok) {
|
||||
code.append("import lombok.Data;\n");
|
||||
}
|
||||
code.append("\n");
|
||||
|
||||
// 类注释
|
||||
code.append("/**\n");
|
||||
code.append(" * <p>\n");
|
||||
if (tableMap != null && tableMap.get("comment") != null) {
|
||||
code.append(" * ").append(tableMap.get("comment")).append("\n");
|
||||
}
|
||||
code.append(" * </p>\n");
|
||||
code.append(" *\n");
|
||||
code.append(" * @author ").append(author).append("\n");
|
||||
code.append(" * @since ").append(date).append("\n");
|
||||
code.append(" */\n");
|
||||
|
||||
// Lombok注解
|
||||
if (lombok != null && lombok) {
|
||||
code.append("@Data\n");
|
||||
}
|
||||
|
||||
// 类声明
|
||||
code.append("public class ").append(entity);
|
||||
if (serialVersionUID != null && serialVersionUID) {
|
||||
code.append(" implements Serializable");
|
||||
}
|
||||
code.append(" {\n\n");
|
||||
|
||||
// 序列化版本号
|
||||
if (serialVersionUID != null && serialVersionUID) {
|
||||
code.append(" private static final long serialVersionUID = 1L;\n\n");
|
||||
}
|
||||
|
||||
// 字段定义
|
||||
code.append(" /**\n * 主键ID\n */\n");
|
||||
code.append(" private Long id;\n\n");
|
||||
|
||||
code.append(" /**\n * 用户名\n */\n");
|
||||
code.append(" private String username;\n\n");
|
||||
|
||||
code.append(" /**\n * 邮箱\n */\n");
|
||||
code.append(" private String email;\n\n");
|
||||
|
||||
code.append(" /**\n * 创建时间\n */\n");
|
||||
code.append(" private LocalDateTime createTime;\n");
|
||||
|
||||
// 如果不使用Lombok,生成getter/setter方法
|
||||
if (lombok == null || !lombok) {
|
||||
code.append("\n // Getter and Setter methods\n");
|
||||
|
||||
// id的getter/setter
|
||||
code.append(" public Long getId() {\n return id;\n }\n\n");
|
||||
code.append(" public void setId(Long id) {\n this.id = id;\n }\n\n");
|
||||
|
||||
// username的getter/setter
|
||||
code.append(" public String getUsername() {\n return username;\n }\n\n");
|
||||
code.append(" public void setUsername(String username) {\n this.username = username;\n }\n\n");
|
||||
|
||||
// email的getter/setter
|
||||
code.append(" public String getEmail() {\n return email;\n }\n\n");
|
||||
code.append(" public void setEmail(String email) {\n this.email = email;\n }\n\n");
|
||||
|
||||
// createTime的getter/setter
|
||||
code.append(" public LocalDateTime getCreateTime() {\n return createTime;\n }\n\n");
|
||||
code.append(" public void setCreateTime(LocalDateTime createTime) {\n this.createTime = createTime;\n }\n");
|
||||
|
||||
// toString方法
|
||||
if (entityToString != null && entityToString) {
|
||||
code.append("\n @Override\n");
|
||||
code.append(" public String toString() {\n");
|
||||
code.append(" return \"").append(entity).append("{\" +\n");
|
||||
code.append(" \"id=\" + id +\n");
|
||||
code.append(" \", username='\" + username + '\\'' +\n");
|
||||
code.append(" \", email='\" + email + '\\'' +\n");
|
||||
code.append(" \", createTime=\" + createTime +\n");
|
||||
code.append(" '}';\n");
|
||||
code.append(" }\n");
|
||||
}
|
||||
}
|
||||
|
||||
code.append("}\n");
|
||||
|
||||
return code.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 备用内容生成
|
||||
*/
|
||||
private String generateFallbackContent(String templatePath, Map<String, Object> dataModel) {
|
||||
// 根据模板路径判断类型
|
||||
if (templatePath.contains("controller")) {
|
||||
return generateControllerCode(dataModel);
|
||||
} else if (templatePath.contains("service") && !templatePath.contains("serviceImpl")) {
|
||||
return generateServiceCode(dataModel);
|
||||
} else if (templatePath.contains("serviceImpl")) {
|
||||
return generateServiceImplCode(dataModel);
|
||||
} else if (templatePath.contains("mapper") && (templatePath.contains(".xml") || templatePath.endsWith("xml.ftl"))) {
|
||||
return generateMapperXmlCode(dataModel);
|
||||
} else if (templatePath.contains("mapper")) {
|
||||
return generateMapperCode(dataModel);
|
||||
} else {
|
||||
return generateEntityCode(dataModel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成Controller代码
|
||||
*/
|
||||
private String generateControllerCode(Map<String, Object> dataModel) {
|
||||
StringBuilder code = new StringBuilder();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> packageMap = (Map<String, String>) dataModel.get("package");
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> tableMap = (Map<String, Object>) dataModel.get("table");
|
||||
String entity = safeString(dataModel.get("entity"));
|
||||
String author = safeString(dataModel.get("author"));
|
||||
String date = safeString(dataModel.get("date"));
|
||||
|
||||
// 包声明
|
||||
if (packageMap != null && packageMap.get("Controller") != null) {
|
||||
code.append("package ").append(packageMap.get("Controller")).append(";\n\n");
|
||||
}
|
||||
|
||||
// 导入语句
|
||||
code.append("import org.springframework.web.bind.annotation.RequestMapping;\n");
|
||||
code.append("import org.springframework.web.bind.annotation.RestController;\n");
|
||||
code.append("import org.springframework.beans.factory.annotation.Autowired;\n");
|
||||
if (packageMap != null) {
|
||||
code.append("import ").append(packageMap.get("Service")).append(".I").append(entity).append("Service;\n");
|
||||
}
|
||||
code.append("\n");
|
||||
|
||||
// 类注释
|
||||
code.append("/**\n");
|
||||
code.append(" * <p>\n");
|
||||
if (tableMap != null && tableMap.get("comment") != null) {
|
||||
code.append(" * ").append(tableMap.get("comment")).append(" 前端控制器\n");
|
||||
}
|
||||
code.append(" * </p>\n");
|
||||
code.append(" *\n");
|
||||
code.append(" * @author ").append(author).append("\n");
|
||||
code.append(" * @since ").append(date).append("\n");
|
||||
code.append(" */\n");
|
||||
|
||||
// 注解和类声明
|
||||
code.append("@RestController\n");
|
||||
code.append("@RequestMapping(\"/").append(entity.toLowerCase()).append("\")\n");
|
||||
code.append("public class ").append(entity).append("Controller {\n\n");
|
||||
|
||||
// 注入Service
|
||||
code.append(" @Autowired\n");
|
||||
code.append(" private I").append(entity).append("Service ").append(entity.toLowerCase()).append("Service;\n\n");
|
||||
|
||||
code.append("}\n");
|
||||
|
||||
return code.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成Service接口代码
|
||||
*/
|
||||
private String generateServiceCode(Map<String, Object> dataModel) {
|
||||
StringBuilder code = new StringBuilder();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> packageMap = (Map<String, String>) dataModel.get("package");
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> tableMap = (Map<String, Object>) dataModel.get("table");
|
||||
String entity = safeString(dataModel.get("entity"));
|
||||
String author = safeString(dataModel.get("author"));
|
||||
String date = safeString(dataModel.get("date"));
|
||||
|
||||
// 包声明
|
||||
if (packageMap != null && packageMap.get("Service") != null) {
|
||||
code.append("package ").append(packageMap.get("Service")).append(";\n\n");
|
||||
}
|
||||
|
||||
// 导入语句
|
||||
if (packageMap != null && packageMap.get("Entity") != null) {
|
||||
code.append("import ").append(packageMap.get("Entity")).append(".").append(entity).append(";\n");
|
||||
}
|
||||
code.append("import com.baomidou.mybatisplus.extension.service.IService;\n\n");
|
||||
|
||||
// 类注释
|
||||
code.append("/**\n");
|
||||
code.append(" * <p>\n");
|
||||
if (tableMap != null && tableMap.get("comment") != null) {
|
||||
code.append(" * ").append(tableMap.get("comment")).append(" 服务类\n");
|
||||
}
|
||||
code.append(" * </p>\n");
|
||||
code.append(" *\n");
|
||||
code.append(" * @author ").append(author).append("\n");
|
||||
code.append(" * @since ").append(date).append("\n");
|
||||
code.append(" */\n");
|
||||
|
||||
// 接口声明
|
||||
code.append("public interface I").append(entity).append("Service extends IService<").append(entity).append("> {\n\n");
|
||||
code.append("}\n");
|
||||
|
||||
return code.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成ServiceImpl代码
|
||||
*/
|
||||
private String generateServiceImplCode(Map<String, Object> dataModel) {
|
||||
StringBuilder code = new StringBuilder();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> packageMap = (Map<String, String>) dataModel.get("package");
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> tableMap = (Map<String, Object>) dataModel.get("table");
|
||||
String entity = safeString(dataModel.get("entity"));
|
||||
String author = safeString(dataModel.get("author"));
|
||||
String date = safeString(dataModel.get("date"));
|
||||
|
||||
// 包声明
|
||||
if (packageMap != null && packageMap.get("ServiceImpl") != null) {
|
||||
code.append("package ").append(packageMap.get("ServiceImpl")).append(";\n\n");
|
||||
}
|
||||
|
||||
// 导入语句
|
||||
if (packageMap != null) {
|
||||
code.append("import ").append(packageMap.get("Entity")).append(".").append(entity).append(";\n");
|
||||
code.append("import ").append(packageMap.get("Mapper")).append(".").append(entity).append("Mapper;\n");
|
||||
code.append("import ").append(packageMap.get("Service")).append(".I").append(entity).append("Service;\n");
|
||||
}
|
||||
code.append("import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;\n");
|
||||
code.append("import org.springframework.stereotype.Service;\n\n");
|
||||
|
||||
// 类注释
|
||||
code.append("/**\n");
|
||||
code.append(" * <p>\n");
|
||||
if (tableMap != null && tableMap.get("comment") != null) {
|
||||
code.append(" * ").append(tableMap.get("comment")).append(" 服务实现类\n");
|
||||
}
|
||||
code.append(" * </p>\n");
|
||||
code.append(" *\n");
|
||||
code.append(" * @author ").append(author).append("\n");
|
||||
code.append(" * @since ").append(date).append("\n");
|
||||
code.append(" */\n");
|
||||
|
||||
// 注解和类声明
|
||||
code.append("@Service\n");
|
||||
code.append("public class ").append(entity).append("ServiceImpl extends ServiceImpl<").append(entity).append("Mapper, ").append(entity).append("> implements I").append(entity).append("Service {\n\n");
|
||||
code.append("}\n");
|
||||
|
||||
return code.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成Mapper接口代码
|
||||
*/
|
||||
private String generateMapperCode(Map<String, Object> dataModel) {
|
||||
StringBuilder code = new StringBuilder();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> packageMap = (Map<String, String>) dataModel.get("package");
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> tableMap = (Map<String, Object>) dataModel.get("table");
|
||||
String entity = safeString(dataModel.get("entity"));
|
||||
String author = safeString(dataModel.get("author"));
|
||||
String date = safeString(dataModel.get("date"));
|
||||
|
||||
// 包声明
|
||||
if (packageMap != null && packageMap.get("Mapper") != null) {
|
||||
code.append("package ").append(packageMap.get("Mapper")).append(";\n\n");
|
||||
}
|
||||
|
||||
// 导入语句
|
||||
if (packageMap != null && packageMap.get("Entity") != null) {
|
||||
code.append("import ").append(packageMap.get("Entity")).append(".").append(entity).append(";\n");
|
||||
}
|
||||
code.append("import com.baomidou.mybatisplus.core.mapper.BaseMapper;\n");
|
||||
code.append("import org.apache.ibatis.annotations.Mapper;\n\n");
|
||||
|
||||
// 类注释
|
||||
code.append("/**\n");
|
||||
code.append(" * <p>\n");
|
||||
if (tableMap != null && tableMap.get("comment") != null) {
|
||||
code.append(" * ").append(tableMap.get("comment")).append(" Mapper 接口\n");
|
||||
}
|
||||
code.append(" * </p>\n");
|
||||
code.append(" *\n");
|
||||
code.append(" * @author ").append(author).append("\n");
|
||||
code.append(" * @since ").append(date).append("\n");
|
||||
code.append(" */\n");
|
||||
|
||||
// 注解和接口声明
|
||||
code.append("@Mapper\n");
|
||||
code.append("public interface ").append(entity).append("Mapper extends BaseMapper<").append(entity).append("> {\n\n");
|
||||
code.append("}\n");
|
||||
|
||||
return code.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成Mapper XML代码
|
||||
*/
|
||||
private String generateMapperXmlCode(Map<String, Object> dataModel) {
|
||||
StringBuilder xml = new StringBuilder();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> packageMap = (Map<String, String>) dataModel.get("package");
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> tableMap = (Map<String, Object>) dataModel.get("table");
|
||||
String entity = safeString(dataModel.get("entity"));
|
||||
|
||||
// XML头
|
||||
xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
|
||||
xml.append("<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">\n");
|
||||
|
||||
// Mapper标签
|
||||
String mapperNamespace = "";
|
||||
if (packageMap != null && packageMap.get("Mapper") != null) {
|
||||
mapperNamespace = packageMap.get("Mapper") + "." + entity + "Mapper";
|
||||
}
|
||||
xml.append("<mapper namespace=\"").append(mapperNamespace).append("\">\n\n");
|
||||
|
||||
// ResultMap
|
||||
xml.append(" <!-- 通用查询映射结果 -->\n");
|
||||
xml.append(" <resultMap id=\"BaseResultMap\" type=\"");
|
||||
if (packageMap != null && packageMap.get("Entity") != null) {
|
||||
xml.append(packageMap.get("Entity")).append(".").append(entity);
|
||||
}
|
||||
xml.append("\">\n");
|
||||
|
||||
// 字段映射
|
||||
if (tableMap != null && tableMap.get("fields") != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> fields = (List<Map<String, Object>>) tableMap.get("fields");
|
||||
for (Map<String, Object> field : fields) {
|
||||
Boolean keyFlag = (Boolean) field.get("keyFlag");
|
||||
String columnName = safeString(field.get("name"));
|
||||
String propertyName = safeString(field.get("propertyName"));
|
||||
|
||||
if (keyFlag != null && keyFlag) {
|
||||
xml.append(" <id column=\"").append(columnName).append("\" jdbcType=\"BIGINT\" property=\"").append(propertyName).append("\" />\n");
|
||||
} else {
|
||||
String jdbcType = getJdbcType(safeString(field.get("propertyType")));
|
||||
xml.append(" <result column=\"").append(columnName).append("\" jdbcType=\"").append(jdbcType).append("\" property=\"").append(propertyName).append("\" />\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
xml.append(" </resultMap>\n\n");
|
||||
|
||||
// Base Column List
|
||||
xml.append(" <!-- 通用查询字段 -->\n");
|
||||
xml.append(" <sql id=\"Base_Column_List\">\n");
|
||||
if (tableMap != null && tableMap.get("fields") != null) {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> fields = (List<Map<String, Object>>) tableMap.get("fields");
|
||||
StringBuilder columns = new StringBuilder();
|
||||
for (int i = 0; i < fields.size(); i++) {
|
||||
if (i > 0) columns.append(", ");
|
||||
columns.append(safeString(fields.get(i).get("name")));
|
||||
}
|
||||
xml.append(" ").append(columns.toString()).append("\n");
|
||||
}
|
||||
xml.append(" </sql>\n\n");
|
||||
|
||||
xml.append("</mapper>\n");
|
||||
|
||||
return xml.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取JDBC类型
|
||||
*/
|
||||
private String getJdbcType(String javaType) {
|
||||
switch (javaType) {
|
||||
case "String": return "VARCHAR";
|
||||
case "Long": return "BIGINT";
|
||||
case "Integer": return "INTEGER";
|
||||
case "Boolean": return "BOOLEAN";
|
||||
case "LocalDateTime": return "TIMESTAMP";
|
||||
case "LocalDate": return "DATE";
|
||||
case "BigDecimal": return "DECIMAL";
|
||||
default: return "VARCHAR";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全的字符串转换
|
||||
*/
|
||||
private String safeString(Object obj) {
|
||||
return obj == null ? "" : String.valueOf(obj);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,15 @@
|
||||
package com.yexuejc.db2java.core.template.impl;
|
||||
|
||||
import com.yexuejc.db2java.core.template.TemplateEngineProcessor;
|
||||
import org.apache.velocity.Template;
|
||||
import org.apache.velocity.VelocityContext;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.apache.velocity.runtime.resource.loader.StringResourceLoader;
|
||||
import org.apache.velocity.runtime.resource.util.StringResourceRepository;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Velocity模板引擎处理器
|
||||
@@ -14,7 +19,7 @@ import java.util.Scanner;
|
||||
*/
|
||||
public class VelocityTemplateProcessor implements TemplateEngineProcessor {
|
||||
|
||||
private Object velocityEngine; // 暂时使用Object,运行时会是org.apache.velocity.app.VelocityEngine
|
||||
private VelocityEngine velocityEngine;
|
||||
|
||||
@Override
|
||||
public String getEngineName() {
|
||||
@@ -28,12 +33,22 @@ public class VelocityTemplateProcessor implements TemplateEngineProcessor {
|
||||
|
||||
@Override
|
||||
public void initialize(Map<String, Object> config) throws Exception {
|
||||
// TODO: 实际实现时需要引入velocity依赖
|
||||
System.out.println("Velocity引擎初始化 - 配置: " + config);
|
||||
velocityEngine = new VelocityEngine();
|
||||
Properties props = new Properties();
|
||||
props.setProperty("resource.loader", "string");
|
||||
props.setProperty("string.resource.loader.class", StringResourceLoader.class.getName());
|
||||
props.setProperty("string.resource.loader.cache", "true");
|
||||
props.setProperty("string.resource.loader.modificationCheckInterval", "0");
|
||||
velocityEngine.init(props);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String processTemplate(String templatePath, Map<String, Object> dataModel) throws Exception {
|
||||
// 确保Velocity引擎已初始化
|
||||
if (velocityEngine == null) {
|
||||
initialize(null);
|
||||
}
|
||||
|
||||
// 读取模板文件
|
||||
String templateContent = readTemplateFile(templatePath);
|
||||
|
||||
@@ -41,10 +56,26 @@ public class VelocityTemplateProcessor implements TemplateEngineProcessor {
|
||||
return "<!-- 模板文件不存在: " + templatePath + " -->";
|
||||
}
|
||||
|
||||
// 简单的模板替换处理(实际应用中需要用Velocity引擎)
|
||||
String processedContent = processSimpleTemplate(templateContent, dataModel);
|
||||
// 使用Velocity引擎处理模板
|
||||
VelocityContext context = new VelocityContext();
|
||||
if (dataModel != null) {
|
||||
for (Map.Entry<String, Object> entry : dataModel.entrySet()) {
|
||||
context.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return processedContent;
|
||||
// 使用StringResourceLoader来处理模板
|
||||
String templateName = templatePath.replace("/", "_").replace("\\", "_");
|
||||
StringResourceRepository repo = StringResourceLoader.getRepository();
|
||||
repo.putStringResource(templateName, templateContent);
|
||||
|
||||
Template template = velocityEngine.getTemplate(templateName, "UTF-8");
|
||||
|
||||
// 处理模板
|
||||
StringWriter writer = new StringWriter();
|
||||
template.merge(context, writer);
|
||||
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,14 +89,14 @@ public class VelocityTemplateProcessor implements TemplateEngineProcessor {
|
||||
private String readTemplateFile(String templatePath) {
|
||||
try {
|
||||
String fullPath = "/templates/" + templatePath;
|
||||
InputStream inputStream = this.getClass().getResourceAsStream(fullPath);
|
||||
java.io.InputStream inputStream = this.getClass().getResourceAsStream(fullPath);
|
||||
|
||||
if (inputStream == null) {
|
||||
System.err.println("模板文件不存在: " + fullPath);
|
||||
return null;
|
||||
}
|
||||
|
||||
Scanner scanner = new Scanner(inputStream, "UTF-8");
|
||||
java.util.Scanner scanner = new java.util.Scanner(inputStream, "UTF-8");
|
||||
StringBuilder content = new StringBuilder();
|
||||
while (scanner.hasNextLine()) {
|
||||
content.append(scanner.nextLine()).append("\n");
|
||||
@@ -79,65 +110,4 @@ public class VelocityTemplateProcessor implements TemplateEngineProcessor {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 简单的模板处理(Velocity风格)
|
||||
*/
|
||||
private String processSimpleTemplate(String template, Map<String, Object> dataModel) {
|
||||
String result = template;
|
||||
|
||||
// 替换基本变量,避免空值
|
||||
result = result.replace("${author}", safeString(dataModel.get("author")));
|
||||
result = result.replace("${date}", safeString(dataModel.get("date")));
|
||||
result = result.replace("${entity}", safeString(dataModel.get("entity")));
|
||||
|
||||
// 处理package信息
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> packageMap = (Map<String, String>) dataModel.get("package");
|
||||
if (packageMap != null) {
|
||||
result = result.replace("${package.Entity}", safeString(packageMap.get("Entity")));
|
||||
result = result.replace("${package.Mapper}", safeString(packageMap.get("Mapper")));
|
||||
result = result.replace("${package.Service}", safeString(packageMap.get("Service")));
|
||||
result = result.replace("${package.ServiceImpl}", safeString(packageMap.get("ServiceImpl")));
|
||||
result = result.replace("${package.Controller}", safeString(packageMap.get("Controller")));
|
||||
}
|
||||
|
||||
// 处理table信息
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> tableMap = (Map<String, Object>) dataModel.get("table");
|
||||
if (tableMap != null) {
|
||||
result = result.replace("$!{table.comment}", safeString(tableMap.get("comment")));
|
||||
result = result.replace("${table.mapperName}", safeString(tableMap.get("mapperName")));
|
||||
result = result.replace("${table.serviceName}", safeString(tableMap.get("serviceName")));
|
||||
result = result.replace("${table.serviceImplName}", safeString(tableMap.get("serviceImplName")));
|
||||
result = result.replace("${table.controllerName}", safeString(tableMap.get("controllerName")));
|
||||
}
|
||||
|
||||
// 处理条件判断和循环
|
||||
result = processConditions(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全的字符串转换,避免空指针
|
||||
*/
|
||||
private String safeString(Object obj) {
|
||||
return obj == null ? "" : String.valueOf(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理条件判断
|
||||
*/
|
||||
private String processConditions(String template) {
|
||||
// 简化处理,移除Velocity条件标签
|
||||
String result = template;
|
||||
result = result.replaceAll("#if\\([^)]*\\)", "");
|
||||
result = result.replaceAll("#end", "");
|
||||
result = result.replaceAll("#else", "");
|
||||
result = result.replaceAll("#elseif\\([^)]*\\)", "");
|
||||
result = result.replaceAll("#foreach\\([^)]*\\)", "");
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,13 @@ import org.springframework.stereotype.Controller;
|
||||
<% if(isNotEmpty(superControllerClassPackage)){ %>
|
||||
import ${superControllerClassPackage};
|
||||
<% } %>
|
||||
<% if(isNotEmpty(importControllerFrameworkPackages)){ %>
|
||||
<% for(pkg in importControllerFrameworkPackages){ %>
|
||||
<% if(pkg != "org.springframework.web.bind.annotation.RestController"){ %>
|
||||
import ${pkg};
|
||||
<% } %>
|
||||
<% } %>
|
||||
<% } %>
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -33,5 +40,11 @@ public class ${table.controllerName} extends ${superControllerClass} {
|
||||
public class ${table.controllerName} {
|
||||
<% } %>
|
||||
|
||||
<% if(isNotEmpty(controllerAutowiredFields)){ %>
|
||||
<% for(field in controllerAutowiredFields){ %>
|
||||
${field.annotation}
|
||||
private ${field.type} ${field.name};
|
||||
<% } %>
|
||||
<% } %>
|
||||
}
|
||||
<% } %>
|
||||
@@ -9,6 +9,13 @@ import org.springframework.stereotype.Controller;
|
||||
#if(${superControllerClassPackage})
|
||||
import ${superControllerClassPackage};
|
||||
#end
|
||||
#if(${importControllerFrameworkPackages})
|
||||
#foreach($pkg in ${importControllerFrameworkPackages})
|
||||
#if($pkg != "org.springframework.web.bind.annotation.RestController")
|
||||
import ${pkg};
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@@ -33,5 +40,11 @@ public class ${table.controllerName} extends ${superControllerClass} {
|
||||
public class ${table.controllerName} {
|
||||
#end
|
||||
|
||||
#if(${controllerAutowiredFields})
|
||||
#foreach($field in ${controllerAutowiredFields})
|
||||
${field.annotation}
|
||||
private ${field.type} ${field.name};
|
||||
#end
|
||||
#end
|
||||
}
|
||||
#end
|
||||
@@ -57,6 +57,33 @@ public class ${entity} {
|
||||
private ${field.propertyType} ${field.propertyName};
|
||||
<% } %>
|
||||
<% /** -----------END 字段循环遍历----------- **/ %>
|
||||
|
||||
<% if(isNotEmpty(table.oneToOneFields)){ %>
|
||||
<% for(field in table.oneToOneFields){ %>
|
||||
|
||||
/**
|
||||
* ${field.comment}
|
||||
*/
|
||||
<% for(an in field.annotationAttributesList){ %>
|
||||
${an.displayName}
|
||||
<% } %>
|
||||
private ${field.propertyType} ${field.propertyName};
|
||||
<% } %>
|
||||
<% } %>
|
||||
|
||||
<% if(isNotEmpty(table.oneToManyFields)){ %>
|
||||
<% for(field in table.oneToManyFields){ %>
|
||||
|
||||
/**
|
||||
* ${field.comment}
|
||||
*/
|
||||
<% for(an in field.annotationAttributesList){ %>
|
||||
${an.displayName}
|
||||
<% } %>
|
||||
private java.util.List<${field.propertyType}> ${field.propertyName};
|
||||
<% } %>
|
||||
<% } %>
|
||||
|
||||
<% if(!entityLombokModel){ %>
|
||||
<% for(field in table.fields){ %>
|
||||
<%
|
||||
|
||||
@@ -54,6 +54,37 @@ public class ${entity} {
|
||||
private ${field.propertyType} ${field.propertyName};
|
||||
#end
|
||||
## ---------- END 字段循环遍历 ----------
|
||||
|
||||
## ---------- BEGIN 一对一关联字段 ----------
|
||||
#if(${table.oneToOneFields})
|
||||
#foreach($field in ${table.oneToOneFields})
|
||||
|
||||
/**
|
||||
* ${field.comment}
|
||||
*/
|
||||
#foreach($an in ${field.annotationAttributesList})
|
||||
${an.displayName}
|
||||
#end
|
||||
private ${field.propertyType} ${field.propertyName};
|
||||
#end
|
||||
#end
|
||||
## ---------- END 一对一关联字段 ----------
|
||||
|
||||
## ---------- BEGIN 一对多关联字段 ----------
|
||||
#if(${table.oneToManyFields})
|
||||
#foreach($field in ${table.oneToManyFields})
|
||||
|
||||
/**
|
||||
* ${field.comment}
|
||||
*/
|
||||
#foreach($an in ${field.annotationAttributesList})
|
||||
${an.displayName}
|
||||
#end
|
||||
private java.util.List<${field.propertyType}> ${field.propertyName};
|
||||
#end
|
||||
#end
|
||||
## ---------- END 一对多关联字段 ----------
|
||||
|
||||
#if(!${entityLombokModel})
|
||||
#foreach($field in ${table.fields})
|
||||
#if(${field.propertyType.equals("boolean")})
|
||||
|
||||
@@ -7,12 +7,10 @@ import com.yexuejc.db2java.core.generator.GenerationResult;
|
||||
import com.yexuejc.db2java.core.generator.TableInfo;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* DB2Java使用示例
|
||||
* 改进的DB2Java使用示例
|
||||
*
|
||||
* @author yexuejc
|
||||
* @since 2025-01
|
||||
@@ -21,19 +19,36 @@ public class Db2JavaExample {
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
// 打印支持的模板引擎和生成模式
|
||||
System.out.println("支持的模板引擎: " + String.join(", ", Db2JavaCore.getSupportedTemplateEngines()));
|
||||
System.out.println("支持的生成模式: " + String.join(", ", Db2JavaCore.getSupportedGenerationModes()));
|
||||
System.out.println("=== 改进的DB2Java代码生成测试 ===");
|
||||
|
||||
// 模拟一个表信息
|
||||
TableInfo userTable = createUserTable();
|
||||
List<TableInfo> tableInfos = Arrays.asList(userTable);
|
||||
|
||||
// 测试不同的模板引擎和生成模式组合
|
||||
testGeneration(tableInfos, "freemarker", "mybatis");
|
||||
testGeneration(tableInfos, "velocity", "mybatis-plus");
|
||||
testGeneration(tableInfos, "beetl", "jpa");
|
||||
testGeneration(tableInfos, "enjoy", "hibernate");
|
||||
// 测试生成标准的Java代码
|
||||
// 设置为coding模式,生成标准的src/main/java结构
|
||||
testImprovedGeneration(tableInfos, "freemarker", "mybatis", true,"coding");// 基本的OK
|
||||
testImprovedGeneration(tableInfos, "freemarker", "mybatis", false,"coding");// 基本的OK
|
||||
testImprovedGeneration(tableInfos, "freemarker", "mybatis", false,"file");// 基本的OK
|
||||
testImprovedGeneration(tableInfos, "freemarker", "mybatis-plus", true,"coding");// 基本的OK
|
||||
testImprovedGeneration(tableInfos, "freemarker", "jpa", false,"coding");// 测试不使用Lombok的情况
|
||||
testImprovedGeneration(tableInfos, "freemarker", "jpa", true,"coding");// 基本的OK
|
||||
|
||||
// velocity,beetl,enjoy
|
||||
|
||||
testImprovedGeneration(tableInfos, "velocity", "mybatis", true,"coding");
|
||||
testImprovedGeneration(tableInfos, "velocity", "mybatis", false,"coding");
|
||||
testImprovedGeneration(tableInfos, "velocity", "mybatis", false,"file");
|
||||
testImprovedGeneration(tableInfos, "velocity", "mybatis-plus", true,"coding");
|
||||
testImprovedGeneration(tableInfos, "velocity", "hibernate", false,"coding");
|
||||
testImprovedGeneration(tableInfos, "velocity", "jpa", true,"coding");
|
||||
|
||||
testImprovedGeneration(tableInfos, "beetl", "mybatis", true,"coding");
|
||||
testImprovedGeneration(tableInfos, "beetl", "mybatis", false,"coding");
|
||||
testImprovedGeneration(tableInfos, "beetl", "mybatis", false,"file");
|
||||
testImprovedGeneration(tableInfos, "beetl", "mybatis-plus", true,"coding");
|
||||
testImprovedGeneration(tableInfos, "beetl", "hibernate", false,"coding");
|
||||
testImprovedGeneration(tableInfos, "beetl", "jpa", true,"coding");
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("生成代码时发生错误: " + e.getMessage());
|
||||
@@ -41,42 +56,80 @@ public class Db2JavaExample {
|
||||
}
|
||||
}
|
||||
|
||||
private static void testGeneration(List<TableInfo> tableInfos, String engine, String mode) {
|
||||
private static void testImprovedGeneration(List<TableInfo> tableInfos, String engine, String mode, boolean useLombok,String type) {
|
||||
try {
|
||||
System.out.println("\n=== 测试 " + engine + " + " + mode + " ===");
|
||||
String lombokSuffix = useLombok ? "-lombok" : "-standard";
|
||||
System.out.println("\n=== 测试 " + engine + " + " + mode + lombokSuffix + " ===");
|
||||
|
||||
// 创建生成配置
|
||||
GenerationConfig config = new GenerationConfig();
|
||||
config.setEngine(engine);
|
||||
config.setMode(mode);
|
||||
config.setType("file"); // 设置为file模式,直接在指定目录下生成
|
||||
config.setOutputPath("C:/0110_Workspace/yexuejc/db2java/export/" + engine + "-" + mode);
|
||||
config.setPackageName("com.example.generated." + mode);
|
||||
config.setAuthor("db2java-generator");
|
||||
config.setLombok("freemarker".equals(engine)); // 只有FreeMarker使用Lombok
|
||||
config.setType(type); // 设置为coding模式,生成标准的src/main/java结构
|
||||
config.setOutputPath("C:/0110_Workspace/yexuejc/db2java/export/improved-" + engine + "-" + mode + lombokSuffix);
|
||||
config.setPackageName("com.yexuejc.db2java.export." + mode.replace("-", ""));
|
||||
config.setAuthor("yexuejc");
|
||||
config.setLombok(useLombok);
|
||||
config.setOverride(true);
|
||||
|
||||
// 通过extraConfig传递额外配置
|
||||
Map<String, Object> extraConfig = new HashMap<>();
|
||||
extraConfig.put("serialVersionUID", true);
|
||||
extraConfig.put("fieldUseJavaDoc", true);
|
||||
extraConfig.put("toString", true);
|
||||
extraConfig.put("serializable", true);
|
||||
config.setExtraConfig(extraConfig);
|
||||
|
||||
// 生成代码
|
||||
GenerationResult result = Db2JavaCore.generateCode(tableInfos, config);
|
||||
|
||||
if (result.isSuccess()) {
|
||||
System.out.println("生成成功!生成了 " + result.getGeneratedFiles().size() + " 个文件:");
|
||||
result.getGeneratedFiles().forEach(file ->
|
||||
System.out.println(" - " + file.getFileType() + ": " + file.getFileName()));
|
||||
System.out.println(" - " + file.getFileType() + ": " + file.getFileName() + " (" + file.getFileSize() + " bytes)"));
|
||||
|
||||
// 显示生成的Entity代码预览
|
||||
result.getGeneratedFiles().stream()
|
||||
.filter(file -> "Entity".equals(file.getFileType()))
|
||||
.findFirst()
|
||||
.ifPresent(file -> {
|
||||
System.out.println("\n生成的Entity代码预览:");
|
||||
System.out.println("================================");
|
||||
String content = file.getContent();
|
||||
if (content != null && !content.isEmpty()) {
|
||||
String[] lines = content.split("\n");
|
||||
for (int i = 0; i < Math.min(lines.length, 30); i++) {
|
||||
System.out.println(lines[i]);
|
||||
}
|
||||
if (lines.length > 30) {
|
||||
System.out.println("... (省略 " + (lines.length - 30) + " 行)");
|
||||
}
|
||||
} else {
|
||||
System.out.println("警告:生成的文件内容为空!");
|
||||
}
|
||||
System.out.println("================================");
|
||||
});
|
||||
|
||||
// 显示生成的Mapper XML代码预览
|
||||
result.getGeneratedFiles().stream()
|
||||
.filter(file -> "MapperXml".equals(file.getFileType()))
|
||||
.findFirst()
|
||||
.ifPresent(file -> {
|
||||
System.out.println("\n生成的Mapper XML代码预览:");
|
||||
System.out.println("================================");
|
||||
String content = file.getContent();
|
||||
if (content != null && !content.isEmpty()) {
|
||||
String[] lines = content.split("\n");
|
||||
for (int i = 0; i < Math.min(lines.length, 30); i++) {
|
||||
System.out.println(lines[i]);
|
||||
}
|
||||
if (lines.length > 30) {
|
||||
System.out.println("... (省略 " + (lines.length - 30) + " 行)");
|
||||
}
|
||||
} else {
|
||||
System.out.println("警告:生成的文件内容为空!");
|
||||
}
|
||||
System.out.println("================================");
|
||||
});
|
||||
} else {
|
||||
System.out.println("生成失败: " + result.getErrorMessage());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("测试失败: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
package example;
|
||||
|
||||
import com.yexuejc.db2java.core.Db2JavaCore;
|
||||
import com.yexuejc.db2java.core.generator.FieldInfo;
|
||||
import com.yexuejc.db2java.core.generator.GenerationConfig;
|
||||
import com.yexuejc.db2java.core.generator.GenerationResult;
|
||||
import com.yexuejc.db2java.core.generator.TableInfo;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 改进的DB2Java使用示例
|
||||
*
|
||||
* @author yexuejc
|
||||
* @since 2025-01
|
||||
*/
|
||||
public class ImprovedDb2JavaExample {
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
System.out.println("=== 改进的DB2Java代码生成测试 ===");
|
||||
|
||||
// 模拟一个表信息
|
||||
TableInfo userTable = createUserTable();
|
||||
List<TableInfo> tableInfos = Arrays.asList(userTable);
|
||||
|
||||
// 测试生成标准的Java代码
|
||||
// testImprovedGeneration(tableInfos, "freemarker", "mybatis-plus", false,"coding");
|
||||
// testImprovedGeneration(tableInfos, "freemarker", "mybatis-plus", true,"file");
|
||||
testImprovedGeneration(tableInfos, "freemarker", "mybatis", true,"coding");
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("生成代码时发生错误: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private static void testImprovedGeneration(List<TableInfo> tableInfos, String engine, String mode, boolean useLombok,String type) {
|
||||
try {
|
||||
String lombokSuffix = useLombok ? "-lombok" : "-standard";
|
||||
System.out.println("\n=== 测试 " + engine + " + " + mode + lombokSuffix + " ===");
|
||||
|
||||
// 创建生成配置
|
||||
GenerationConfig config = new GenerationConfig();
|
||||
config.setEngine(engine);
|
||||
config.setMode(mode);
|
||||
config.setType(type); // 设置为coding模式,生成标准的src/main/java结构
|
||||
config.setOutputPath("C:/0110_Workspace/yexuejc/db2java/export/improved-" + engine + "-" + mode + lombokSuffix);
|
||||
config.setPackageName("com.yexuejc.db2java.export." + mode.replace("-", ""));
|
||||
config.setAuthor("yexuejc");
|
||||
config.setLombok(useLombok);
|
||||
config.setOverride(true);
|
||||
|
||||
// 生成代码
|
||||
GenerationResult result = Db2JavaCore.generateCode(tableInfos, config);
|
||||
|
||||
if (result.isSuccess()) {
|
||||
System.out.println("生成成功!生成了 " + result.getGeneratedFiles().size() + " 个文件:");
|
||||
result.getGeneratedFiles().forEach(file ->
|
||||
System.out.println(" - " + file.getFileType() + ": " + file.getFileName()));
|
||||
|
||||
// 显示生成的Entity代码预览
|
||||
result.getGeneratedFiles().stream()
|
||||
.filter(file -> "Entity".equals(file.getFileType()))
|
||||
.findFirst()
|
||||
.ifPresent(file -> {
|
||||
System.out.println("\n生成的Entity代码预览:");
|
||||
System.out.println("================================");
|
||||
String[] lines = file.getContent().split("\n");
|
||||
for (int i = 0; i < Math.min(lines.length, 20); i++) {
|
||||
System.out.println(lines[i]);
|
||||
}
|
||||
if (lines.length > 20) {
|
||||
System.out.println("... (省略 " + (lines.length - 20) + " 行)");
|
||||
}
|
||||
System.out.println("================================");
|
||||
});
|
||||
} else {
|
||||
System.out.println("生成失败: " + result.getErrorMessage());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("测试失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static TableInfo createUserTable() {
|
||||
TableInfo table = new TableInfo();
|
||||
table.setTableName("sys_user");
|
||||
table.setTableComment("系统用户表");
|
||||
table.setEntityName("User");
|
||||
|
||||
// 创建字段信息
|
||||
FieldInfo id = new FieldInfo("id", "BIGINT", "id", "Long");
|
||||
id.setPrimaryKey(true);
|
||||
id.setColumnComment("主键ID");
|
||||
|
||||
FieldInfo username = new FieldInfo("username", "VARCHAR", "username", "String");
|
||||
username.setColumnComment("用户名");
|
||||
username.setLength(50);
|
||||
|
||||
FieldInfo email = new FieldInfo("email", "VARCHAR", "email", "String");
|
||||
email.setColumnComment("邮箱");
|
||||
email.setLength(100);
|
||||
|
||||
FieldInfo createTime = new FieldInfo("create_time", "DATETIME", "createTime", "LocalDateTime");
|
||||
createTime.setColumnComment("创建时间");
|
||||
|
||||
table.setFields(Arrays.asList(id, username, email, createTime));
|
||||
table.setPrimaryKeys(Arrays.asList(id));
|
||||
|
||||
return table;
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
<properties>
|
||||
<compiler-plugin.version>3.14.0</compiler-plugin.version>
|
||||
<maven.compiler.release>21</maven.compiler.release>
|
||||
<maven.compiler.release>24</maven.compiler.release>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
|
||||
|
||||
58
export/pom.xml
Normal file
58
export/pom.xml
Normal file
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>top.yexuejc</groupId>
|
||||
<artifactId>db2java-parent</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<groupId>top.yexuejc</groupId>
|
||||
<artifactId>export</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>24</maven.compiler.source>
|
||||
<maven.compiler.target>24</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus</artifactId>
|
||||
<version>3.5.3</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.30</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>3.5.6</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
5
pom.xml
5
pom.xml
@@ -16,8 +16,9 @@
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>24</maven.compiler.source>
|
||||
<maven.compiler.target>24</maven.compiler.target>
|
||||
<!-- 将Java版本从24降级到17以提高兼容性 -->
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user