freemarker生成.

This commit is contained in:
聂秋荣 2018-01-11 13:22:37 +08:00
parent 470b2bfb14
commit e1518268c5
10 changed files with 564 additions and 2 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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