
com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine Maven / Gradle / Ivy
/*
* Copyright (c) 2011-2023, baomidou ([email protected]).
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.baomidou.mybatisplus.generator.engine;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
import com.baomidou.mybatisplus.generator.config.builder.CustomFile;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.util.FileUtils;
import com.baomidou.mybatisplus.generator.util.RuntimeUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
/**
* 模板引擎抽象类
*
* @author hubin
* @since 2018-01-10
*/
public abstract class AbstractTemplateEngine {
protected final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
/**
* 配置信息
*/
private ConfigBuilder configBuilder;
/**
* 模板引擎初始化
*/
@NotNull
public abstract AbstractTemplateEngine init(@NotNull ConfigBuilder configBuilder);
/**
* 输出自定义模板文件
*
* @param customFiles 自定义模板文件列表
* @param tableInfo 表信息
* @param objectMap 渲染数据
* @since 3.5.3
*/
protected void outputCustomFile(@NotNull List customFiles, @NotNull TableInfo tableInfo, @NotNull Map objectMap) {
String entityName = tableInfo.getEntityName();
String parentPath = getPathInfo(OutputFile.parent);
customFiles.forEach(file -> {
String filePath = StringUtils.isNotBlank(file.getFilePath()) ? file.getFilePath() : parentPath;
if (StringUtils.isNotBlank(file.getPackageName())) {
filePath = filePath + File.separator + file.getPackageName().replaceAll("\\.", StringPool.BACK_SLASH + File.separator);
}
Function formatNameFunction = file.getFormatNameFunction();
String fileName = filePath + File.separator + (null != formatNameFunction ? formatNameFunction.apply(tableInfo) : entityName) + file.getFileName();
outputFile(new File(fileName), objectMap, file.getTemplatePath(), file.isFileOverride());
});
}
/**
* 输出实体文件
*
* @param tableInfo 表信息
* @param objectMap 渲染数据
* @since 3.5.0
*/
protected void outputEntity(@NotNull TableInfo tableInfo, @NotNull Map objectMap) {
String entityName = tableInfo.getEntityName();
String entityPath = getPathInfo(OutputFile.entity);
if (StringUtils.isNotBlank(entityName) && StringUtils.isNotBlank(entityPath)) {
getTemplateFilePath(template -> template.getEntity(getConfigBuilder().getGlobalConfig().isKotlin())).ifPresent((entity) -> {
String entityFile = String.format((entityPath + File.separator + "%s" + suffixJavaOrKt()), entityName);
outputFile(getOutputFile(entityFile, OutputFile.entity), objectMap, entity, getConfigBuilder().getStrategyConfig().entity().isFileOverride());
});
}
}
protected File getOutputFile(String filePath, OutputFile outputFile) {
return getConfigBuilder().getStrategyConfig().getOutputFile().createFile(filePath, outputFile);
}
/**
* 输出Mapper文件(含xml)
*
* @param tableInfo 表信息
* @param objectMap 渲染数据
* @since 3.5.0
*/
protected void outputMapper(@NotNull TableInfo tableInfo, @NotNull Map objectMap) {
// MpMapper.java
String entityName = tableInfo.getEntityName();
String mapperPath = getPathInfo(OutputFile.mapper);
if (StringUtils.isNotBlank(tableInfo.getMapperName()) && StringUtils.isNotBlank(mapperPath)) {
getTemplateFilePath(TemplateConfig::getMapper).ifPresent(mapper -> {
String mapperFile = String.format((mapperPath + File.separator + tableInfo.getMapperName() + suffixJavaOrKt()), entityName);
outputFile(getOutputFile(mapperFile, OutputFile.mapper), objectMap, mapper, getConfigBuilder().getStrategyConfig().mapper().isFileOverride());
});
}
// MpMapper.xml
String xmlPath = getPathInfo(OutputFile.xml);
if (StringUtils.isNotBlank(tableInfo.getXmlName()) && StringUtils.isNotBlank(xmlPath)) {
getTemplateFilePath(TemplateConfig::getXml).ifPresent(xml -> {
String xmlFile = String.format((xmlPath + File.separator + tableInfo.getXmlName() + ConstVal.XML_SUFFIX), entityName);
outputFile(getOutputFile(xmlFile, OutputFile.xml), objectMap, xml, getConfigBuilder().getStrategyConfig().mapper().isFileOverride());
});
}
}
/**
* 输出service文件
*
* @param tableInfo 表信息
* @param objectMap 渲染数据
* @since 3.5.0
*/
protected void outputService(@NotNull TableInfo tableInfo, @NotNull Map objectMap) {
// IMpService.java
String entityName = tableInfo.getEntityName();
// 判断是否要生成service接口
if (tableInfo.isServiceInterface()) {
String servicePath = getPathInfo(OutputFile.service);
if (StringUtils.isNotBlank(tableInfo.getServiceName()) && StringUtils.isNotBlank(servicePath)) {
getTemplateFilePath(TemplateConfig::getService).ifPresent(service -> {
String serviceFile = String.format((servicePath + File.separator + tableInfo.getServiceName() + suffixJavaOrKt()), entityName);
outputFile(getOutputFile(serviceFile, OutputFile.service), objectMap, service, getConfigBuilder().getStrategyConfig().service().isFileOverride());
});
}
}
// MpServiceImpl.java
String serviceImplPath = getPathInfo(OutputFile.serviceImpl);
if (StringUtils.isNotBlank(tableInfo.getServiceImplName()) && StringUtils.isNotBlank(serviceImplPath)) {
getTemplateFilePath(TemplateConfig::getServiceImpl).ifPresent(serviceImpl -> {
String implFile = String.format((serviceImplPath + File.separator + tableInfo.getServiceImplName() + suffixJavaOrKt()), entityName);
outputFile(getOutputFile(implFile, OutputFile.serviceImpl), objectMap, serviceImpl, getConfigBuilder().getStrategyConfig().service().isFileOverride());
});
}
}
/**
* 输出controller文件
*
* @param tableInfo 表信息
* @param objectMap 渲染数据
* @since 3.5.0
*/
protected void outputController(@NotNull TableInfo tableInfo, @NotNull Map objectMap) {
// MpController.java
String controllerPath = getPathInfo(OutputFile.controller);
if (StringUtils.isNotBlank(tableInfo.getControllerName()) && StringUtils.isNotBlank(controllerPath)) {
getTemplateFilePath(TemplateConfig::getController).ifPresent(controller -> {
String entityName = tableInfo.getEntityName();
String controllerFile = String.format((controllerPath + File.separator + tableInfo.getControllerName() + suffixJavaOrKt()), entityName);
outputFile(getOutputFile(controllerFile, OutputFile.controller), objectMap, controller, getConfigBuilder().getStrategyConfig().controller().isFileOverride());
});
}
}
/**
* 输出文件
*
* @param file 文件
* @param objectMap 渲染信息
* @param templatePath 模板路径
* @param fileOverride 是否覆盖已有文件
* @since 3.5.2
*/
protected void outputFile(@NotNull File file, @NotNull Map objectMap, @NotNull String templatePath, boolean fileOverride) {
if (isCreate(file, fileOverride)) {
try {
// 全局判断【默认】
boolean exist = file.exists();
if (!exist) {
File parentFile = file.getParentFile();
FileUtils.forceMkdir(parentFile);
}
writer(objectMap, templatePath, file);
} catch (Exception exception) {
throw new RuntimeException(exception);
}
}
}
/**
* 获取模板路径
*
* @param function function
* @return 模板路径
* @since 3.5.0
*/
@NotNull
protected Optional getTemplateFilePath(@NotNull Function function) {
TemplateConfig templateConfig = getConfigBuilder().getTemplateConfig();
String filePath = function.apply(templateConfig);
if (StringUtils.isNotBlank(filePath)) {
return Optional.of(templateFilePath(filePath));
}
return Optional.empty();
}
/**
* 获取路径信息
*
* @param outputFile 输出文件
* @return 路径信息
*/
@Nullable
protected String getPathInfo(@NotNull OutputFile outputFile) {
return getConfigBuilder().getPathInfo().get(outputFile);
}
/**
* 批量输出 java xml 文件
*/
@NotNull
public AbstractTemplateEngine batchOutput() {
try {
ConfigBuilder config = this.getConfigBuilder();
List tableInfoList = config.getTableInfoList();
tableInfoList.forEach(tableInfo -> {
Map objectMap = this.getObjectMap(config, tableInfo);
Optional.ofNullable(config.getInjectionConfig()).ifPresent(t -> {
// 添加自定义属性
t.beforeOutputFile(tableInfo, objectMap);
// 输出自定义文件
outputCustomFile(t.getCustomFiles(), tableInfo, objectMap);
});
// 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;
}
/**
* 将模板转化成为文件
*
* @param objectMap 渲染对象 MAP 信息
* @param templatePath 模板文件
* @param outputFile 文件生成的目录
* @throws Exception 异常
* @since 3.5.0
*/
@NotNull
public abstract void writer(@NotNull Map objectMap, @NotNull String templatePath, @NotNull File outputFile) throws Exception;
/**
* 打开输出目录
*/
public void open() {
String outDir = getConfigBuilder().getGlobalConfig().getOutputDir();
if (StringUtils.isBlank(outDir) || !new File(outDir).exists()) {
System.err.println("未找到输出目录:" + outDir);
} else if (getConfigBuilder().getGlobalConfig().isOpen()) {
try {
RuntimeUtils.openDir(outDir);
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
}
}
}
/**
* 渲染对象 MAP 信息
*
* @param config 配置信息
* @param tableInfo 表信息对象
* @return ignore
*/
@NotNull
public Map getObjectMap(@NotNull ConfigBuilder config, @NotNull TableInfo tableInfo) {
StrategyConfig strategyConfig = config.getStrategyConfig();
Map controllerData = strategyConfig.controller().renderData(tableInfo);
Map objectMap = new HashMap<>(controllerData);
Map mapperData = strategyConfig.mapper().renderData(tableInfo);
objectMap.putAll(mapperData);
Map serviceData = strategyConfig.service().renderData(tableInfo);
objectMap.putAll(serviceData);
Map entityData = strategyConfig.entity().renderData(tableInfo);
objectMap.putAll(entityData);
objectMap.put("config", config);
objectMap.put("package", config.getPackageConfig().getPackageInfo());
GlobalConfig globalConfig = config.getGlobalConfig();
objectMap.put("author", globalConfig.getAuthor());
objectMap.put("kotlin", globalConfig.isKotlin());
objectMap.put("swagger", globalConfig.isSwagger());
objectMap.put("springdoc", globalConfig.isSpringdoc());
objectMap.put("date", globalConfig.getCommentDate());
// 启用 schema 处理逻辑
String schemaName = "";
if (strategyConfig.isEnableSchema()) {
// 存在 schemaName 设置拼接 . 组合表名
schemaName = config.getDataSourceConfig().getSchemaName();
if (StringUtils.isNotBlank(schemaName)) {
schemaName += ".";
tableInfo.setConvert(true);
}
}
objectMap.put("schemaName", schemaName);
objectMap.put("table", tableInfo);
objectMap.put("entity", tableInfo.getEntityName());
return objectMap;
}
/**
* 模板真实文件路径
*
* @param filePath 文件路径
* @return ignore
*/
@NotNull
public abstract String templateFilePath(@NotNull String filePath);
/**
* 检查文件是否创建文件
*
* @param file 文件
* @param fileOverride 是否覆盖已有文件
* @return 是否创建文件
* @since 3.5.2
*/
protected boolean isCreate(@NotNull File file, boolean fileOverride) {
if (file.exists() && !fileOverride) {
LOGGER.warn("文件[{}]已存在,且未开启文件覆盖配置,需要开启配置可到策略配置中设置!!!", file.getName());
}
return !file.exists() || fileOverride;
}
/**
* 文件后缀
*/
protected String suffixJavaOrKt() {
return getConfigBuilder().getGlobalConfig().isKotlin() ? ConstVal.KT_SUFFIX : ConstVal.JAVA_SUFFIX;
}
@NotNull
public ConfigBuilder getConfigBuilder() {
return configBuilder;
}
@NotNull
public AbstractTemplateEngine setConfigBuilder(@NotNull ConfigBuilder configBuilder) {
this.configBuilder = configBuilder;
return this;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy