freemarker,velocity,beetl引擎生成代码完成

This commit is contained in:
2025-10-18 10:29:25 +08:00
parent 00248728bf
commit cd421afc6c
18 changed files with 1541 additions and 868 deletions

View File

@@ -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>

View File

@@ -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);
}
/**
* 写文件到磁盘
*/

View File

@@ -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);
}
/**
* 写文件到磁盘
*/

View File

@@ -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();
}
}
}

View File

@@ -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);
}
/**
* 写文件到磁盘
*/

View File

@@ -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;
}
}

View File

@@ -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";
}
}
/**
* 安全的字符串转换
*/

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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};
<% } %>
<% } %>
}
<% } %>

View File

@@ -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

View File

@@ -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){ %>
<%

View File

@@ -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")})

View File

@@ -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();
}
}

View File

@@ -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;
}
}

View File

@@ -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
View 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>

View File

@@ -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>