123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- /**
- * Copyright (c) 2011-2020, hubin (jobob@qq.com).
- * <p>
- * 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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;
- import java.io.BufferedWriter;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.OutputStreamWriter;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Properties;
- import org.apache.ibatis.logging.Log;
- import org.apache.ibatis.logging.LogFactory;
- import org.apache.velocity.Template;
- import org.apache.velocity.VelocityContext;
- import org.apache.velocity.app.Velocity;
- import org.apache.velocity.app.VelocityEngine;
- import com.baomidou.mybatisplus.generator.config.ConstVal;
- import com.baomidou.mybatisplus.generator.config.FileOutConfig;
- import com.baomidou.mybatisplus.generator.config.TemplateConfig;
- import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
- import com.baomidou.mybatisplus.generator.config.po.TableField;
- import com.baomidou.mybatisplus.generator.config.po.TableInfo;
- import com.baomidou.mybatisplus.toolkit.CollectionUtils;
- import com.baomidou.mybatisplus.toolkit.StringUtils;
- /**
- * 生成文件
- *
- * @author YangHu, tangguo
- * @since 2016-08-30
- */
- public class AutoGenerator extends AbstractGenerator {
- private static final Log logger = LogFactory.getLog(AutoGenerator.class);
- /**
- * velocity引擎
- */
- private VelocityEngine engine;
- /**
- * 生成代码
- */
- public void execute() {
- logger.debug("==========================准备生成文件...==========================");
- // 初始化配置
- initConfig();
- // 创建输出文件路径
- mkdirs(config.getPathInfo());
- // 获取上下文
- Map<String, VelocityContext> ctxData = analyzeData(config);
- // 循环生成文件
- for (Map.Entry<String, VelocityContext> ctx : ctxData.entrySet()) {
- batchOutput(ctx.getKey(), ctx.getValue());
- }
- // 打开输出目录
- if (config.getGlobalConfig().isOpen()) {
- try {
- String osName = System.getProperty("os.name");
- if (osName != null) {
- if (osName.contains("Mac")) {
- Runtime.getRuntime().exec("open " + config.getGlobalConfig().getOutputDir());
- } else if (osName.contains("Windows")) {
- Runtime.getRuntime().exec("cmd /c start " + config.getGlobalConfig().getOutputDir());
- } else {
- logger.debug("文件输出目录:" + config.getGlobalConfig().getOutputDir());
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- logger.debug("==========================文件生成完成!!!==========================");
- }
- /**
- * <p>
- * 开放表信息、预留子类重写
- * </p>
- *
- * @param config 配置信息
- * @return
- */
- protected List<TableInfo> getAllTableInfoList(ConfigBuilder config) {
- return config.getTableInfoList();
- }
- /**
- * 分析数据
- *
- * @param config 总配置信息
- * @return 解析数据结果集
- */
- private Map<String, VelocityContext> analyzeData(ConfigBuilder config) {
- List<TableInfo> tableList = this.getAllTableInfoList(config);
- Map<String, String> packageInfo = config.getPackageInfo();
- Map<String, VelocityContext> ctxData = new HashMap<>();
- String superEntityClass = getSuperClassName(config.getSuperEntityClass());
- String superMapperClass = getSuperClassName(config.getSuperMapperClass());
- String superServiceClass = getSuperClassName(config.getSuperServiceClass());
- String superServiceImplClass = getSuperClassName(config.getSuperServiceImplClass());
- String superControllerClass = getSuperClassName(config.getSuperControllerClass());
- String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
- VelocityContext ctx;
- for (TableInfo tableInfo : tableList) {
- ctx = new VelocityContext();
- if (null != injectionConfig) {
- /**
- * 注入自定义配置
- */
- injectionConfig.initMap();
- ctx.put("cfg", injectionConfig.getMap());
- }
- /* ---------- 添加导入包 ---------- */
- if (config.getGlobalConfig().isActiveRecord()) {
- // 开启 ActiveRecord 模式
- tableInfo.setImportPackages("com.baomidou.mybatisplus.activerecord.Model");
- }
- if (tableInfo.isConvert()) {
- // 表注解
- tableInfo.setImportPackages("com.baomidou.mybatisplus.annotations.TableName");
- }
- if (tableInfo.isLogicDelete(config.getGlobalConfig().getLogicDeletePropertyName())) {
- // 逻辑删除注解
- tableInfo.setImportPackages("com.baomidou.mybatisplus.annotations.TableLogic");
- }
- if (StringUtils.isNotEmpty(config.getSuperEntityClass())) {
- // 父实体
- tableInfo.setImportPackages(config.getSuperEntityClass());
- } else {
- tableInfo.setImportPackages("java.io.Serializable");
- }
- // Boolean类型is前缀处理
- if (config.getStrategyConfig().isEntityBooleanColumnRemoveIsPrefix()) {
- for (TableField field : tableInfo.getFields()) {
- if (field.getPropertyType().equalsIgnoreCase("boolean")) {
- if (field.getPropertyName().indexOf("is") != -1) {
- String noIsPropertyName = field.getPropertyName().substring(2, field.getPropertyName().length());
- String firstChar = noIsPropertyName.substring(0, 1).toLowerCase();
- String afterChar = noIsPropertyName.substring(1, noIsPropertyName.length());
- field.setPropertyName(config.getStrategyConfig(), firstChar + afterChar);
- }
- }
- }
- }
- // RequestMapping 连字符风格 user-info
- if (config.getStrategyConfig().isControllerMappingHyphenStyle()) {
- ctx.put("controllerMappingHyphenStyle", config.getStrategyConfig().isControllerMappingHyphenStyle());
- ctx.put("controllerMappingHyphen", StringUtils.camelToHyphen(tableInfo.getEntityPath()));
- }
- ctx.put("restControllerStyle", config.getStrategyConfig().isRestControllerStyle());
- ctx.put("package", packageInfo);
- ctx.put("author", config.getGlobalConfig().getAuthor());
- ctx.put("logicDeletePropertyName", config.getGlobalConfig().getLogicDeletePropertyName());
- ctx.put("activeRecord", config.getGlobalConfig().isActiveRecord());
- ctx.put("date", date);
- ctx.put("table", tableInfo);
- ctx.put("enableCache", config.getGlobalConfig().isEnableCache());
- ctx.put("baseResultMap", config.getGlobalConfig().isBaseResultMap());
- ctx.put("baseColumnList", config.getGlobalConfig().isBaseColumnList());
- ctx.put("entity", tableInfo.getEntityName());
- ctx.put("entityColumnConstant", config.getStrategyConfig().isEntityColumnConstant());
- ctx.put("entityBuilderModel", config.getStrategyConfig().isEntityBuilderModel());
- ctx.put("entityLombokModel", config.getStrategyConfig().isEntityLombokModel());
- ctx.put("entityBooleanColumnRemoveIsPrefix", config.getStrategyConfig().isEntityBooleanColumnRemoveIsPrefix());
- ctx.put("superEntityClass", superEntityClass);
- ctx.put("superMapperClassPackage", config.getSuperMapperClass());
- ctx.put("superMapperClass", superMapperClass);
- ctx.put("superServiceClassPackage", config.getSuperServiceClass());
- ctx.put("superServiceClass", superServiceClass);
- ctx.put("superServiceImplClassPackage", config.getSuperServiceImplClass());
- ctx.put("superServiceImplClass", superServiceImplClass);
- ctx.put("superControllerClassPackage", config.getSuperControllerClass());
- ctx.put("superControllerClass", superControllerClass);
- ctxData.put(tableInfo.getEntityName(), ctx);
- }
- return ctxData;
- }
- /**
- * 获取类名
- *
- * @param classPath
- * @return
- */
- private String getSuperClassName(String classPath) {
- if (StringUtils.isEmpty(classPath))
- return null;
- return classPath.substring(classPath.lastIndexOf(".") + 1);
- }
- /**
- * 处理输出目录
- *
- * @param pathInfo 路径信息
- */
- private void mkdirs(Map<String, String> pathInfo) {
- for (Map.Entry<String, String> entry : pathInfo.entrySet()) {
- File dir = new File(entry.getValue());
- if (!dir.exists()) {
- boolean result = dir.mkdirs();
- if (result) {
- logger.debug("创建目录: [" + entry.getValue() + "]");
- }
- }
- }
- }
- /**
- * 合成上下文与模板
- *
- * @param context vm上下文
- */
- private void batchOutput(String entityName, VelocityContext context) {
- try {
- TableInfo tableInfo = (TableInfo) context.get("table");
- Map<String, String> pathInfo = config.getPathInfo();
- String entityFile = String.format((pathInfo.get(ConstVal.ENTITY_PATH) + ConstVal.ENTITY_NAME), entityName);
- String mapperFile = String.format((pathInfo.get(ConstVal.MAPPER_PATH) + File.separator + tableInfo.getMapperName() + ConstVal.JAVA_SUFFIX), entityName);
- String xmlFile = String.format((pathInfo.get(ConstVal.XML_PATH) + File.separator + tableInfo.getXmlName() + ConstVal.XML_SUFFIX), entityName);
- String serviceFile = String.format((pathInfo.get(ConstVal.SERIVCE_PATH) + File.separator + tableInfo.getServiceName() + ConstVal.JAVA_SUFFIX), entityName);
- String implFile = String.format((pathInfo.get(ConstVal.SERVICEIMPL_PATH) + File.separator + tableInfo.getServiceImplName() + ConstVal.JAVA_SUFFIX), entityName);
- String controllerFile = String.format((pathInfo.get(ConstVal.CONTROLLER_PATH) + File.separator + tableInfo.getControllerName() + ConstVal.JAVA_SUFFIX), entityName);
- TemplateConfig template = config.getTemplate();
- // 根据override标识来判断是否需要创建文件
- if (isCreate(entityFile)) {
- vmToFile(context, template.getEntity(), entityFile);
- }
- if (isCreate(mapperFile)) {
- vmToFile(context, template.getMapper(), mapperFile);
- }
- if (isCreate(xmlFile)) {
- vmToFile(context, template.getXml(), xmlFile);
- }
- if (isCreate(serviceFile)) {
- vmToFile(context, template.getService(), serviceFile);
- }
- if (isCreate(implFile)) {
- vmToFile(context, template.getServiceImpl(), implFile);
- }
- if (isCreate(controllerFile)) {
- vmToFile(context, template.getController(), controllerFile);
- }
- if (injectionConfig != null) {
- /**
- * 输出自定义文件内容
- */
- List<FileOutConfig> focList = injectionConfig.getFileOutConfigList();
- if (CollectionUtils.isNotEmpty(focList)) {
- for (FileOutConfig foc : focList) {
- vmToFile(context, foc.getTemplatePath(), foc.outputFile(tableInfo));
- }
- }
- }
- } catch (IOException e) {
- logger.error("无法创建文件,请检查配置信息!", e);
- }
- }
- /**
- * 将模板转化成为文件
- *
- * @param context 内容对象
- * @param templatePath 模板文件
- * @param outputFile 文件生成的目录
- */
- private void vmToFile(VelocityContext context, String templatePath, String outputFile) throws IOException {
- if (StringUtils.isEmpty(templatePath)) {
- return;
- }
- VelocityEngine velocity = getVelocityEngine();
- Template template = velocity.getTemplate(templatePath, ConstVal.UTF8);
- File file = new File(outputFile);
- if (!file.getParentFile().exists()) {
- // 如果文件所在的目录不存在,则创建目录
- if (!file.getParentFile().mkdirs()) {
- logger.debug("创建文件所在的目录失败!");
- return;
- }
- }
- FileOutputStream fos = new FileOutputStream(outputFile);
- BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(fos, ConstVal.UTF8));
- template.merge(context, writer);
- writer.close();
- logger.debug("模板:" + templatePath + "; 文件:" + outputFile);
- }
- /**
- * 设置模版引擎,主要指向获取模版路径
- */
- private VelocityEngine getVelocityEngine() {
- if (engine == null) {
- Properties p = new Properties();
- p.setProperty(ConstVal.VM_LOADPATH_KEY, ConstVal.VM_LOADPATH_VALUE);
- p.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, "");
- p.setProperty(Velocity.ENCODING_DEFAULT, ConstVal.UTF8);
- p.setProperty(Velocity.INPUT_ENCODING, ConstVal.UTF8);
- p.setProperty(Velocity.OUTPUT_ENCODING, ConstVal.UTF8);
- p.setProperty("file.resource.loader.unicode", "true");
- engine = new VelocityEngine(p);
- }
- return engine;
- }
- /**
- * 检测文件是否存在
- *
- * @return 是否
- */
- private boolean isCreate(String filePath) {
- File file = new File(filePath);
- return !file.exists() || config.getGlobalConfig().isFileOverride();
- }
- }
|