我们在3.基于SpringBoot3集成MybatisPlus中讲到自定义代码生成器,但是往往遗留代码生成的类格式或者命名不符合要求,需要手工修改,但是当表很多时就比较头痛,所以我们自定义模板在进行代码生成
1. 新建MyTemplateEngine.java类
里面大多实现直接拷贝自VelocityTemplateEngine.java, 只是增加了反射,修改包名,搜索修改地方即可找到两处位置
public class MyTemplateEngine extends AbstractTemplateEngine {
/**
* 批量输出 java xml 文件
*/
@NotNull
public AbstractTemplateEngine batchOutput() {
try {
ConfigBuilder config = this.getConfigBuilder();
List<TableInfo> tableInfoList = config.getTableInfoList();
tableInfoList.forEach(tableInfo -> {
Map<String, Object> objectMap = this.getObjectMap(config, tableInfo);
// 修改地方一:通过反射修改属性值,替换不需要的前缀
Class<? extends TableInfo> clazz = tableInfo.getClass();
try {
Field name = clazz.getDeclaredField("name");
name.setAccessible(true);
name.set(tableInfo, tableInfo.getName().replaceFirst("tb_", ""));
Field entityName = clazz.getDeclaredField("entityName");
entityName.setAccessible(true);
entityName.set(tableInfo, tableInfo.getEntityName().replaceFirst("Tb", ""));
Field mapperName = clazz.getDeclaredField("mapperName");
mapperName.setAccessible(true);
mapperName.set(tableInfo, tableInfo.getMapperName().replaceFirst("Tb", ""));
Field xmlName = clazz.getDeclaredField("xmlName");
xmlName.setAccessible(true);
xmlName.set(tableInfo, tableInfo.getXmlName().replaceFirst("Tb", ""));
Field serviceName = clazz.getDeclaredField("serviceName");
serviceName.setAccessible(true);
serviceName.set(tableInfo, tableInfo.getServiceName().replaceFirst("ITb", ""));
Field serviceImplName = clazz.getDeclaredField("serviceImplName");
serviceImplName.setAccessible(true);
serviceImplName.set(tableInfo, tableInfo.getServiceImplName().replaceFirst("Tb", ""));
Field controllerName = clazz.getDeclaredField("controllerName");
controllerName.setAccessible(true);
controllerName.set(tableInfo, tableInfo.getControllerName().replaceFirst("Tb", ""));
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
Optional.ofNullable(config.getInjectionConfig()).ifPresent(t -> {
// 添加自定义属性
t.beforeOutputFile(tableInfo, objectMap);
// 输出自定义文件
outputCustomFile(t.getCustomFiles(), tableInfo, objectMap);
});
// 修改地方二
objectMap.put("entity", String.valueOf(objectMap.get("entity")).replaceFirst("Tb", ""));
// entity
outputEntity(tableInfo, objectMap);
// mapper and xml
outputMapper(tableInfo, objectMap);
// service
outputService(tableInfo, objectMap);
// controller
outputController(tableInfo, objectMap);
});
} catch (Exception e) {
throw new RuntimeException("无法创建文件,请检查配置信息!", e);
}
return this;
}
private VelocityEngine velocityEngine;
{
try {
Class.forName("org.apache.velocity.util.DuckType");
} catch (ClassNotFoundException e) {
// velocity1.x的生成格式错乱 https://github.com/baomidou/generator/issues/5
LOGGER.warn("Velocity 1.x is outdated, please upgrade to 2.x or later.");
}
}
@Override
public @NotNull MyTemplateEngine init(@NotNull ConfigBuilder configBuilder) {
if (null == velocityEngine) {
Properties p = new Properties();
p.setProperty(ConstVal.VM_LOAD_PATH_KEY, ConstVal.VM_LOAD_PATH_VALUE);
p.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, StringPool.EMPTY);
p.setProperty(Velocity.ENCODING_DEFAULT, ConstVal.UTF8);
p.setProperty(Velocity.INPUT_ENCODING, ConstVal.UTF8);
p.setProperty("file.resource.loader.unicode", StringPool.TRUE);
velocityEngine = new VelocityEngine(p);
}
return this;
}
@Override
public void writer(@NotNull Map<String, Object> objectMap, @NotNull String templatePath, @NotNull File outputFile) throws Exception {
Template template = velocityEngine.getTemplate(templatePath, ConstVal.UTF8);
try (FileOutputStream fos = new FileOutputStream(outputFile);
OutputStreamWriter ow = new OutputStreamWriter(fos, ConstVal.UTF8);
BufferedWriter writer = new BufferedWriter(ow)) {
template.merge(new VelocityContext(objectMap), writer);
}
LOGGER.debug("模板:" + templatePath + "; 文件:" + outputFile);
}
@Override
public @NotNull String templateFilePath(@NotNull String filePath) {
final String dotVm = ".vm";
return filePath.endsWith(dotVm) ? filePath : filePath + dotVm;
}
}
2. 模板文件替换修改
IDEA全局搜索需要的下图文件,拷贝至resources/templates下,然后把里面的内容根据自己需求进行模板调整
3. 代码生成类
之前是Swagger注解,我们调整为Springdoc注解,并对实体不额外添加后缀%s
public class FastAutoGeneratorTest {
public static void main(String[] args) {
DataSourceConfig.Builder dataSourceConfig = new DataSourceConfig.Builder("jdbc:mysql://XXXX:3306/yy_dev?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai","root","Gensci@123");
FastAutoGenerator.create(dataSourceConfig)
// 全局配置
.globalConfig((scanner, builder) -> builder.enableSpringdoc().author(scanner.apply("请输入作者名称?")))
// 包配置
.packageConfig((scanner, builder) -> builder.parent(scanner.apply("请输入包名?")))
// 策略配置
.templateEngine(new MyTemplateEngine())
.strategyConfig((scanner, builder) -> builder.addInclude(getTables(scanner.apply("请输入表名,多个英文逗号分隔?所有输入 all")))
.controllerBuilder().enableRestStyle().enableHyphenStyle()
.entityBuilder().enableLombok().enableTableFieldAnnotation().idType(IdType.INPUT).formatFileName("%s").build())
.execute();
}
// 处理 all 情况
protected static List<String> getTables(String tables) {
return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
}
}