瀏覽代碼

freemarker生成.

聂秋荣 7 年之前
父節點
當前提交
e1518268c5

+ 3 - 2
build.gradle

@@ -35,7 +35,8 @@ ext {
 			"spring-tx":"org.springframework:spring-tx:${springVersion}",
 			"druid":"com.alibaba:druid:1.0.29",
 			"fastjson":"com.alibaba:fastjson:1.2.37",
-			"tomcatjdbc":"org.apache.tomcat:tomcat-jdbc:9.0.2"
+			"tomcatjdbc":"org.apache.tomcat:tomcat-jdbc:9.0.2",
+			"freemarker":"org.freemarker:freemarker:2.3.23"
 	]
 }
 
@@ -77,7 +78,7 @@ subprojects{
 	}
 
 	repositories {
-		mavenLocal()
+//		mavenLocal()
 		maven { url "http://maven.aliyun.com/nexus/content/groups/public/" }
 		maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
 		maven { url "http://www.cameliatk.jp/maven2/repository/thirdparty"}

+ 1 - 0
mybatis-plus-generate/build.gradle

@@ -1,6 +1,7 @@
 dependencies {
 	compile project(":mybatis-plus-support")
 	provided rootProject.ext.dependencies["velocity"]
+	provided rootProject.ext.dependencies["freemarker"]
 	testCompile rootProject.ext.dependencies["sqlserver"]
 	testCompile rootProject.ext.dependencies["postgresql"]
 	testCompile rootProject.ext.dependencies["oracle"]

+ 173 - 0
mybatis-plus-generate/src/main/java/com/baomidou/mybatisplus/generator/engine/FreemarkerTemplateEngine.java

@@ -0,0 +1,173 @@
+package com.baomidou.mybatisplus.generator.engine;
+
+import com.baomidou.mybatisplus.generator.config.ConstVal;
+import com.baomidou.mybatisplus.generator.config.FileOutConfig;
+import com.baomidou.mybatisplus.generator.config.GlobalConfig;
+import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
+import com.baomidou.mybatisplus.generator.config.po.TableInfo;
+import com.baomidou.mybatisplus.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.toolkit.StringUtils;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author nieqiurong 2018/1/11.
+ */
+public class FreemarkerTemplateEngine extends AbstractTemplateEngine {
+    
+    private Configuration configuration;
+    
+    @Override
+    public AbstractTemplateEngine batchOutput() {
+        try {
+            configuration = new Configuration(Configuration.VERSION_2_3_0);
+            configuration.setDefaultEncoding(ConstVal.UTF8);
+            configuration.setClassForTemplateLoading(FreemarkerTemplateEngine.class, "/");
+            List<TableInfo> tableInfoList = this.getConfigBuilder().getTableInfoList();
+            for (TableInfo tableInfo : tableInfoList) {
+                Map<String,Object> objectMap = this.getVelocityContextInfo(tableInfo);
+                String entityName = tableInfo.getEntityName();
+                Map<String, String> pathInfo = this.getConfigBuilder().getPathInfo();
+                String entityFile = String.format((pathInfo.get(ConstVal.ENTITY_PATH) + File.separator + "%s" + this.suffixJavaOrKt()), entityName);
+                String mapperFile = String.format((pathInfo.get(ConstVal.MAPPER_PATH) + File.separator + tableInfo.getMapperName() + this.suffixJavaOrKt()), 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() + this.suffixJavaOrKt()), entityName);
+                String implFile = String.format((pathInfo.get(ConstVal.SERVICEIMPL_PATH) + File.separator + tableInfo.getServiceImplName() + this.suffixJavaOrKt()), entityName);
+                String controllerFile = String.format((pathInfo.get(ConstVal.CONTROLLER_PATH) + File.separator + tableInfo.getControllerName() + this.suffixJavaOrKt()), entityName);
+                if (isCreate(entityFile)) {
+                    if(this.getConfigBuilder().getGlobalConfig().isKotlin()){
+                        this.writer(configuration.getTemplate(templateFilePath(ConstVal.TEMPLATE_ENTITY_KT)),objectMap,entityFile);
+                    }else{
+                        this.writer(configuration.getTemplate(templateFilePath(ConstVal.TEMPLATE_ENTITY_JAVA)),objectMap,entityFile);
+                    }
+                }
+                if (isCreate(mapperFile)) {
+                    this.writer(configuration.getTemplate(templateFilePath(ConstVal.TEMPLATE_MAPPER)),objectMap,mapperFile);
+                }
+                if (isCreate(xmlFile)) {
+                    this.writer(configuration.getTemplate(templateFilePath(ConstVal.TEMPLATE_XML)),objectMap,xmlFile);
+                }
+                if (isCreate(serviceFile)) {
+                    this.writer(configuration.getTemplate(templateFilePath(ConstVal.TEMPLATE_SERVICE)),objectMap,serviceFile);
+                }
+                if (isCreate(implFile)) {
+                    this.writer(configuration.getTemplate(templateFilePath(ConstVal.TEMPLATE_SERVICEIMPL)),objectMap,implFile);
+                }
+                if (isCreate(controllerFile)) {
+                    this.writer(configuration.getTemplate(templateFilePath(ConstVal.TEMPLATE_CONTROLLER)),objectMap,controllerFile);
+                }
+                if (this.getConfigBuilder().getInjectionConfig() != null) {
+                    List<FileOutConfig> focList = this.getConfigBuilder().getInjectionConfig().getFileOutConfigList();
+                    if (CollectionUtils.isNotEmpty(focList)) {
+                        for (FileOutConfig foc : focList) {
+                            if (isCreate(foc.outputFile(tableInfo))) {
+                                this.writer(configuration.getTemplate(foc.getTemplatePath()),objectMap,foc.outputFile(tableInfo));
+                            }
+                        }
+                    }
+                }
+            
+            }
+        } catch (IOException e) {
+            logger.error("无法创建文件,请检查配置信息!", e);
+        } catch (TemplateException e) {
+            e.printStackTrace();
+        }
+        return this;
+    }
+    
+    /**
+     * 获取模板引擎渲染上下文信息
+     * @param tableInfo 表信息对象
+     * @return
+     */
+    public Map<String,Object> getVelocityContextInfo(TableInfo tableInfo) {
+        Map<String,Object>  objectMap = new HashMap<>();
+        ConfigBuilder config = this.getConfigBuilder();
+        if (config.getStrategyConfig().isControllerMappingHyphenStyle()) {
+            objectMap.put("controllerMappingHyphenStyle", config.getStrategyConfig().isControllerMappingHyphenStyle());
+            objectMap.put("controllerMappingHyphen", StringUtils.camelToHyphen(tableInfo.getEntityPath()));
+        }
+        objectMap.put("restControllerStyle", config.getStrategyConfig().isRestControllerStyle());
+        objectMap.put("package", config.getPackageInfo());
+        GlobalConfig globalConfig = config.getGlobalConfig();
+        objectMap.put("author", globalConfig.getAuthor());
+        objectMap.put("idType", globalConfig.getIdType() == null ? null : globalConfig.getIdType().toString());
+        objectMap.put("logicDeleteFieldName", config.getStrategyConfig().getLogicDeleteFieldName());
+        objectMap.put("versionFieldName", config.getStrategyConfig().getVersionFieldName());
+        objectMap.put("activeRecord", globalConfig.isActiveRecord());
+        objectMap.put("kotlin", globalConfig.isKotlin());
+        objectMap.put("date", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
+        objectMap.put("table", tableInfo);
+        objectMap.put("enableCache", globalConfig.isEnableCache());
+        objectMap.put("baseResultMap", globalConfig.isBaseResultMap());
+        objectMap.put("baseColumnList", globalConfig.isBaseColumnList());
+        objectMap.put("entity", tableInfo.getEntityName());
+        objectMap.put("entityColumnConstant", config.getStrategyConfig().isEntityColumnConstant());
+        objectMap.put("entityBuilderModel", config.getStrategyConfig().isEntityBuilderModel());
+        objectMap.put("entityLombokModel", config.getStrategyConfig().isEntityLombokModel());
+        objectMap.put("entityBooleanColumnRemoveIsPrefix", config.getStrategyConfig().isEntityBooleanColumnRemoveIsPrefix());
+        objectMap.put("superEntityClass", this.getSuperClassName(config.getSuperEntityClass()));
+        objectMap.put("superMapperClassPackage", config.getSuperMapperClass());
+        objectMap.put("superMapperClass", this.getSuperClassName(config.getSuperMapperClass()));
+        objectMap.put("superServiceClassPackage", config.getSuperServiceClass());
+        objectMap.put("superServiceClass", this.getSuperClassName(config.getSuperServiceClass()));
+        objectMap.put("superServiceImplClassPackage", config.getSuperServiceImplClass());
+        objectMap.put("superServiceImplClass", this.getSuperClassName(config.getSuperServiceImplClass()));
+        objectMap.put("superControllerClassPackage", config.getSuperControllerClass());
+        objectMap.put("superControllerClass", this.getSuperClassName(config.getSuperControllerClass()));
+        return objectMap;
+    }
+    
+    
+    /**
+     * 获取类名
+     * @param classPath
+     * @return
+     */
+    private String getSuperClassName(String classPath) {
+        if (StringUtils.isEmpty(classPath)) {
+            return null;
+        }
+        return classPath.substring(classPath.lastIndexOf(".") + 1);
+    }
+    
+    /**
+     * 文件写出
+     * @param template
+     * @param dataModel
+     * @param fileName
+     * @throws IOException
+     * @throws TemplateException
+     */
+    private void writer(Template template, Object dataModel, String fileName) throws IOException, TemplateException {
+        File file = new File(fileName);
+        Writer writer = new OutputStreamWriter(new FileOutputStream(file), ConstVal.UTF8);
+        template.process(dataModel, writer);
+    }
+    
+    /**
+     * <p>
+     * 模板真实文件路径加上.ftl
+     * </p>
+     * @param filePath 文件路径
+     * @return
+     */
+    protected String templateFilePath(String filePath) {
+        StringBuilder fp = new StringBuilder();
+        fp.append(filePath).append(".ftl");
+        return fp.toString();
+    }
+}

+ 39 - 0
mybatis-plus-generate/src/main/resources/templates/controller.java.ftl

@@ -0,0 +1,39 @@
+package ${package.Controller};
+
+
+import org.springframework.web.bind.annotation.RequestMapping;
+
+<#if restControllerStyle>
+import org.springframework.web.bind.annotation.RestController;
+<#else>
+import org.springframework.stereotype.Controller;
+</#if>
+<#if superControllerClassPackage??>
+import ${superControllerClassPackage};
+</#if>
+
+/**
+ * <p>
+ * ${table.comment} 前端控制器
+ * </p>
+ *
+ * @author ${author}
+ * @since ${date}
+ */
+<#if restControllerStyle>
+@RestController
+<#else>
+@Controller
+</#if>
+@RequestMapping("<#if package.ModuleName??>/${package.ModuleName}</#if>/<#if controllerMappingHyphenStyle??>)${controllerMappingHyphen??}<#else>${table.entityPath}</#if>")
+<#if kotlin>
+class ${table.controllerName}<#if superControllerClass??> : ${superControllerClass}()</#if>
+<#else>
+<#if superControllerClass??>
+public class ${table.controllerName} extends ${superControllerClass} {
+<#else>
+public class ${table.controllerName} {
+
+}
+</#if>
+</#if>

+ 143 - 0
mybatis-plus-generate/src/main/resources/templates/entity.java.ftl

@@ -0,0 +1,143 @@
+package ${package.Entity};
+
+<#list table.importPackages as pkg>
+import ${pkg};
+</#list>
+<#if entityLombokModel>
+
+
+
+import com.baomidou.mybatisplus.annotations.Version;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+</#if>
+
+/**
+ * <p>
+ * ${table.comment}
+ * </p>
+ *
+ * @author ${author}
+ * @since ${date}
+ */
+<#if entityLombokModel>
+@Data
+@EqualsAndHashCode(callSuper = true)
+@Accessors(chain = true)
+</#if>
+<#if table.convert>
+@TableName("${table.name}")
+</#if>
+<#if superEntityClass??>
+public class ${entity} extends ${superEntityClass}<#if activeRecord><${entity}></#if> {
+<#elseif activeRecord>
+public class ${entity} extends Model<${entity}> {
+<#else>
+public class ${entity} implements Serializable {
+</#if>
+
+    private static final long serialVersionUID = 1L;
+
+<#-- ----------  BEGIN 字段循环遍历  ---------->
+<#list table.fields as field>
+<#if field.keyFlag>
+<#assign keyPropertyName="${field.propertyName}"/>
+</#if>
+
+<#if field.comment??>
+    /**
+     * ${field.comment}
+     */
+</#if>
+<#if field.keyFlag>
+<#-- 主键 -->
+<#if field.keyIdentityFlag>
+    @TableId(value = "${field.name}", type = IdType.AUTO)
+<#elseif idType!>
+    @TableId(value = "${field.name}", type = IdType.${idType})
+<#elseif field.convert>
+    @TableId("${field.name}")
+</#if>
+
+<#-- 普通字段 -->
+<#elseif field.fill??>
+<#-- -----   存在字段填充设置   ----->
+<#if field.convert>
+    @TableField(value = "${field.name}", fill = FieldFill.${field.fill})
+<#else>
+    @TableField(fill = FieldFill.${field.fill})
+</#if>
+<#elseif field.convert>
+    @TableField("${field.name}")
+</#if>
+<#-- 乐观锁注解 -->
+<#if versionFieldName!"" == field.name>
+    @Version
+</#if>
+<#-- 逻辑删除注解 -->
+<#if logicDeleteFieldName!"" == field.name>
+    @TableLogic
+</#if>
+    private ${field.propertyType} ${field.propertyName};
+
+</#list>
+<#------------  END 字段循环遍历  ---------->
+
+<#if !entityLombokModel>
+<#list table.fields as field>
+<#if field.propertyType == "boolean">
+    <#assign getprefix="is"/>
+<#else>
+    <#assign getprefix="get"/>
+</#if>
+    public ${field.propertyType} ${getprefix}${field.capitalName}() {
+        return ${field.propertyName};
+    }
+
+<#if entityBuilderModel>
+    public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
+<#else>
+    public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
+</#if>
+        this.${field.propertyName} = ${field.propertyName};
+<#if entityBuilderModel>
+        return this;
+</#if>
+    }
+</#list>
+</#if>
+
+<#if entityColumnConstant>
+<#list table.fields as field>
+    public static final String ${field.name.toUpperCase()} = "${field.name}";
+
+</#list>
+</#if>
+<#if activeRecord>
+    @Override
+    protected Serializable pkVal() {
+<#if keyPropertyName??>
+        return this.${keyPropertyName};
+<#else>
+        return this.id;
+</#if>
+    }
+
+</#if>
+<#if !entityLombokModel>
+    @Override
+    public String toString() {
+        return "${entity}{" +
+<#list table.fields as field>
+<#if field_index==0>
+        "${field.propertyName}=" + ${field.propertyName} +
+<#else>
+        ", ${field.propertyName}=" + ${field.propertyName} +
+</#if>
+</#list>
+        "}";
+    }
+</#if>
+}

+ 100 - 0
mybatis-plus-generate/src/main/resources/templates/entity.kt.ftl

@@ -0,0 +1,100 @@
+package ${package.Entity};
+
+<#list table.importPackages as pkg>
+import ${pkg};
+</#list>
+
+/**
+ * <p>
+ * ${table.comment}
+ * </p>
+ *
+ * @author ${author}
+ * @since ${date}
+ */
+<#if table.convert>
+@TableName("${table.name}")
+</#if>
+<#if superEntityClass??>
+class ${entity} : ${superEntityClass}<#if activeRecord><${entity}></#if> {
+<#elseif activeRecord>
+class ${entity} : Model<${entity}>() {
+<#else>
+class ${entity} : Serializable {
+</#if>
+
+<#-- ----------  BEGIN 字段循环遍历  ---------->
+<#list table.fields as field>
+<#if field.keyFlag>
+    <#assign keyPropertyName="${field.propertyName}"/>
+</#if>
+<#if field.comment??>
+    /**
+     * ${field.comment}
+     */
+</#if>
+<#if field.keyFlag>
+<#-- 主键 -->
+<#if field.keyIdentityFlag>
+    @TableId(value = "${field.name}", type = IdType.AUTO)
+<#elseif idType ??>
+    @TableId(value = "${field.name}", type = IdType.${idType})
+<#elseif field.convert>
+    @TableId("${field.name}")
+</#if>
+<#-- 普通字段 -->
+<#elseif field.fill??>
+<#-- -----   存在字段填充设置   ----->
+<#if field.convert>
+    @TableField(value = "${field.name}", fill = FieldFill.${field.fill})
+<#else>
+    @TableField(fill = FieldFill.${field.fill})
+</#if>
+<#elseif field.convert>
+    @TableField("${field.name}")
+</#if>
+<#-- 乐观锁注解 -->
+<#if versionFieldName!"" == field.name>
+    @Version
+</#if>
+<#-- 逻辑删除注解 -->
+<#if logicDeleteFieldName!"" == field.name>
+    @TableLogic
+</#if>
+    var ${field.propertyName}: ${field.propertyType}? = null
+</#list>
+<#-- ----------  END 字段循环遍历  ---------->
+
+
+<#if entityColumnConstant>
+    companion object {
+<#list table.fields as field>
+
+        const val ${field.name.toUpperCase()} : String = "${field.name}"
+
+</#list>
+    }
+
+</#if>
+<#if activeRecord>
+    override fun pkVal(): Serializable {
+<#if keyPropertyName??>
+        return ${keyPropertyName}!!
+<#else>
+        return id!!
+</#if>
+    }
+
+</#if>
+    override fun toString(): String {
+        return "${entity}{" +
+<#list table.fields as field>
+<#if field_index==0>
+        "${field.propertyName}=" + ${field.propertyName} +
+<#else>
+        ", ${field.propertyName}=" + ${field.propertyName} +
+</#if>
+</#list>
+        "}"
+    }
+}

+ 20 - 0
mybatis-plus-generate/src/main/resources/templates/mapper.java.ftl

@@ -0,0 +1,20 @@
+package ${package.Mapper};
+
+import ${package.Entity}.${entity};
+import ${superMapperClassPackage};
+
+/**
+ * <p>
+ * ${table.comment} Mapper 接口
+ * </p>
+ *
+ * @author ${author}
+ * @since ${date}
+ */
+<#if kotlin>
+interface ${table.mapperName} : ${superMapperClass}<${entity}>
+<#else>
+public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {
+
+}
+</#if>

+ 39 - 0
mybatis-plus-generate/src/main/resources/templates/mapper.xml.ftl

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="${package.Mapper}.${table.mapperName}">
+
+<#if enableCache>
+    <!-- 开启二级缓存 -->
+    <cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
+
+</#if>
+<#if baseResultMap>
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
+<#list table.fields as field>
+<#if field.keyFlag><#--生成主键排在第一位-->
+        <id column="${field.name}" property="${field.propertyName}" />
+</#if>
+</#list>
+<#list table.commonFields as field><#--生成公共字段 -->
+    <result column="${field.name}" property="${field.propertyName}" />
+</#list>
+<#list table.fields as field>
+<#if !field.keyFlag><#--生成普通字段 -->
+        <result column="${field.name}" property="${field.propertyName}" />
+</#if>
+</#list>
+    </resultMap>
+
+</#if>
+<#if baseColumnList>
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+<#list table.commonFields as field>
+    <#if field.name == field.propertyName>${field.name}<#else>${field.name} AS ${field.propertyName}</#if>,
+</#list>
+        ${table.fieldNames}
+    </sql>
+
+</#if>
+</mapper>

+ 20 - 0
mybatis-plus-generate/src/main/resources/templates/service.java.ftl

@@ -0,0 +1,20 @@
+package ${package.Service};
+
+import ${package.Entity}.${entity};
+import ${superServiceClassPackage};
+
+/**
+ * <p>
+ * ${table.comment} 服务类
+ * </p>
+ *
+ * @author ${author}
+ * @since ${date}
+ */
+<#if kotlin>
+interface ${table.serviceName} : ${superServiceClass}<${entity}>
+<#else>
+public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {
+
+}
+</#if>

+ 26 - 0
mybatis-plus-generate/src/main/resources/templates/serviceImpl.java.ftl

@@ -0,0 +1,26 @@
+package ${package.ServiceImpl};
+
+import ${package.Entity}.${entity};
+import ${package.Mapper}.${table.mapperName};
+import ${package.Service}.${table.serviceName};
+import ${superServiceImplClassPackage};
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ * ${table.comment} 服务实现类
+ * </p>
+ *
+ * @author ${author}
+ * @since ${date}
+ */
+@Service
+<#if kotlin>
+open class ${table.serviceImplName} : ${superServiceImplClass}<${table.mapperName}, ${entity}>(), ${table.serviceName} {
+
+}
+<#else>
+public class ${table.serviceImplName} extends ${superServiceImplClass}<${table.mapperName}, ${entity}> implements ${table.serviceName} {
+
+}
+</#if>