Mybatis-Plus代码生成器-FreeMarker引擎

代码生成操作步骤

  1. 引入依赖
  2. 添加配置
  3. ftl文件
  4. 编写配置类

配置类编写内容

  • new 代码生成器AutoGenerator
  • 全局配置GlobalConfig
  • 数据源配置DataSourceConfig
  • 包配置PackageConfig
  • 模板配置TemplateConfig
  • 策略配置StrategyConfig
  • 切面配置InjectionConfig(可不要,配置额外输出文件。如:SpringCloud的Feign接口)
  • FreeMarker引擎配置
  • execute执行

FreeMarker模板介绍

Free Marker模板对象属性
对象属性/方法作用用法
packagepackage.Entity获取包名package ${package.Entity};
package.Mapper获取Mapper包名package ${package.Mapper};
package.Controller${package.Controller}
tabletable.importPackages
table.comment表描述${table.comment!}
table.convert
table.name表名${table.name}
table.mapperNamemapper名称${table.mapperName}
table.controllerName${table.controllerName}
table.fields表字段list${table.fields}
superMapperClassmapper父类${superMapperClass}
superMapperClassPackagemapper父类包import ${superMapperClassPackage}
entity实体类名${entity}
date日期${date}
author作者${author}
fieldfield.comment字段描述${field.comment}
field.keyFlag
field.keyIdentityFlag
field.name字段名${field.name}
field.convert
field.propertyType字段属性
field.capitalName
field.propertyName字段属性名
FreeMarker模板控制语句
语句条件用法
if为类,要加??

<#if superControllerClass??>

    public class ${table.controllerName} extends ${superControllerClass} {

<#else>

为Boolean值

<#if kotlin>

    interface ${table.mapperName} : ${superMapperClass}<${entity}>

<#else>

字符串

<#if (logicDeleteFieldName!"") == field.name>

    @TableLogic

</#if>

数字类型

<#if field_index==0>

    "${field.propertyName}=" + ${field.propertyName} +

<#else>

assign定义变量

<#assign getprefix="get"/> // 定义

${getprefix} // 使用

list遍历list

<#list table.fields as field>

    <#if field_index==0>

        "${field.propertyName}=" + ${field.propertyName} +

    <#else>

        ", ${field.propertyName}=" + ${field.propertyName} +

    </#if>

</#list>

其他函数
名称介绍用例
upper_case转大写${field.name?upper_case}
length字符串长度

<#if field.comment!?length gt 0>

    /** * ${field.comment} */

</#if>

gt大于

<#if field.comment!?length gt 0>

    /** * ${field.comment} */

</#if>

uncap_first首字母小写private ${table.serviceName} ${table.serviceName?uncap_first};
cap_first首字母大写

ftl配置文件

package ${cfg.appService};

import ${package.Entity}.${entity};
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
/**
 * <p>
 * ${table.comment!} dubbo接口类
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
<#if kotlin>
interface ${cfg.appServiceName}
<#else>
public interface ${cfg.appServiceName} {

    /**
      * 根据id获取数据
      *
      * @param id
      * @return ${entity}
      */
     ${entity} findById(String id);


    /**
	 * 分页查询
     *
	 * @param page
	 * @param query
	 * @return
	 */
	IPage<${entity}> selectPage(Page<${entity}> page, ${entity} query);

}
</#if>




package ${package.Controller};


import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ${package.Entity}.${entity};
import ${package.Service}.${table.serviceName};

<#if restControllerStyle>
import org.springframework.web.bind.annotation.RestController;
<#else>
import org.springframework.stereotype.Controller;
</#if>
<#if superControllerClassPackage??>
import ${superControllerClassPackage};
</#if>


/**
 * ${table.comment!} 前端控制器
 *
 * @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>

    private Logger logger = LoggerFactory.getLogger(${table.controllerName}.class);

    @Autowired
    private ${table.serviceName} ${table.serviceName?uncap_first};

    /**
    * 根据id查询数据
    *
    * @param id
    * @return
    */
    @RequestMapping(value = {"/findById/{id}"}, method = {RequestMethod.GET})
    public ${entity} findById(@PathVariable("id") String id) {
        return ${table.serviceName?uncap_first}.getById(id);
    }
}
</#if>




package ${package.Entity};

<#list table.importPackages as pkg>
import ${pkg};
</#list>
<#if entityLombokModel>
</#if>

/**
 * <p>
 * ${table.comment!}
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
<#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!?length gt 0>
    /**
     * ${field.comment}
     */
    </#if>
    <#if field.keyFlag>
    <#-- 主键 -->
        <#if field.keyIdentityFlag>
    @TableId(value = "${field.name}")
        <#elseif idType??>
    @TableId(value = "${field.name}")
        <#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 字段循环遍历  ---------->

    <#--set get 方法生成-->
    <#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>
    <#--set get 方法生成结束-->

<#if entityColumnConstant>
    <#list table.fields as field>
    public static final String ${field.name?upper_case} = "${field.name}";

    </#list>
</#if>
<#if activeRecord>
    @Override
    protected Serializable pkVal() {
    <#if keyPropertyName??>
        return this.${keyPropertyName};
    <#else>
        return null;
    </#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>
}




package ${package.Mapper};

import ${package.Entity}.${entity};
import ${superMapperClassPackage};

/**
 * ${table.comment!}Mapper接口
 *
 * @author ${author}
 * @since ${date}
 */
<#if kotlin>
interface ${table.mapperName} : ${superMapperClass}<${entity}>
<#else>
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {

}
</#if>



<?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>
            ${field.name},
        </#list>
        ${table.fieldNames}
    </sql>

</#if>
</mapper>




package ${package.Service};

import ${package.Entity}.${entity};
import ${superServiceClassPackage};

/**
 * ${table.comment!} 服务类
 *
 * @author ${author}
 * @since ${date}
 */
<#if kotlin>
interface ${table.serviceName} : ${superServiceClass}<${entity}>
<#else>
public interface ${table.serviceName} extends ${superServiceClass}<${entity}> {

}
</#if>




package ${package.ServiceImpl};

import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * ${table.comment!} 服务实现类
 *
 * @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} {

     private Logger logger = LoggerFactory.getLogger(${table.serviceImplName}.class);

}
</#if>

 

代码生成类

package com.lingluo.util;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 代码生成器
 *
 * @author 
 * @since 
 */
public class CodeGenerator {

    /**
     * 执行代码生成 main 方法
     *
     * @param args
     */
    public static void main(String[] args) {
        CodeGenerator.autoGenerator();
    }

    /**
     * 代码生成设置
     */
    public static void autoGenerator(){
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("xxxx");
        gc.setOpen(false);
        gc.setIdType(IdType.ID_WORKER);
        gc.setBaseResultMap(true);
        gc.setBaseColumnList(true);
        gc.setServiceName("%sService");
        gc.setFileOverride(false);
        gc.setDateType(DateType.ONLY_DATE);
        gc.setSwagger2(false);
        mpg.setGlobalConfig(gc);

        //数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/product_db?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&serverTimezone=UTC");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("123456");
        mpg.setDataSource(dsc);

        //包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.lingluo");
        pc.setModuleName("base");
        pc.setController("controller");
        pc.setService("service");
        pc.setServiceImpl("service.impl");
        pc.setEntity("entity");
        pc.setMapper("mapper");
        mpg.setPackageInfo(pc);

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();
        templateConfig.setEntity("/templates/entity.java");
        templateConfig.setMapper("/templates/mapper.java");
        templateConfig.setService("/templates/service.java");
        templateConfig.setServiceImpl("/templates/serviceImpl.java");
        templateConfig.setController("/templates/controller.java");
        templateConfig.setXml("/templates/mapper.xml");
        mpg.setTemplate(templateConfig);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setEntityTableFieldAnnotationEnable(true);
        // 可是输入多个表
        strategy.setInclude("t_alipay_orders");
        strategy.setTablePrefix("t_");
        mpg.setStrategy(strategy);

        // 配置额外的输出文件(InjectionConfig可不要这一部分,如果没有额外的输出文件,额外输出文件,如:Spring Cloud的Figen层)
        // ======================= ↓ ==============================
        String injecPath = "com.lingluo.app";
        InjectionConfig injectionConfig = new MyInjectionConfig(injecPath);
        List<FileOutConfig> list = new ArrayList<>();
        list.add(new MyFileOutConfig("/templates/appService.java.ftl",  projectPath + "/src/main/java" + String.format("/%s/", injecPath.replaceAll("\\.", "/"))));
        injectionConfig.setFileOutConfigList(list);
        mpg.setCfg(injectionConfig);
        // ======================= ↑ ==============================

        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }

    /**
     * 定义切面
     */
    static class MyInjectionConfig extends InjectionConfig {

        /**
         * 文件存储的url
         */
        private String parentPath;

        /**
         * 构造器
         *
         * @param parentPath 文件存储的url 如:com.lingluo.app
         */
        public MyInjectionConfig(String parentPath) {
            this.parentPath = parentPath;
        }

        /**
         * 设置在ftl文件中要用到的参数 如:templates/appService.java.ftl 文件中 ${cfg.appServiceName}
         */
        @Override
        public void initMap() {
            List<TableInfo> list = this.getConfig().getTableInfoList();
            Map<String, Object> map = new HashMap<>(10);
            map.put("appService", parentPath);
            for (TableInfo tableInfo : list) {
                map.put("appServiceName", tableInfo.getEntityName() + "AppService");
            }
            this.setMap(map);
        }

    }

    /**
     * 自定义文件输出目录
     */
    static class MyFileOutConfig extends FileOutConfig {

        /**
         * 完整的文件输出目录
         */
        private String filePath;

        /**
         * 文件输出构造器
         *
         * @param templatePath 模板url 如:/templates/appService.java.ftl
         * @param filePath 完成的文件输出目录 如:C:\Users\luohoujian01\myProject\springboot-project/src/main/java/com/lingluo/app/
         */
        public MyFileOutConfig(String templatePath, String filePath) {
            super(templatePath);
            this.filePath = filePath;
        }

        // 自定义输出文件目录,完整的输出目录 如:C:\Users\luohoujian01\myProject\springboot-project/src/main/java/com/lingluo/app/AlipayOrdersAppService.java
        @Override
        public String outputFile(TableInfo tableInfo) {
            return filePath + String.format("%sAppService", tableInfo.getEntityName()) + ".java";
        }
    }
}

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值