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

引言

代码生成器模板 mybatis-plus + Freemarker + lombok模板引擎

代码生成操作步骤

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

配置类编写内容

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

相关依赖

 <dependencies>
        <!--Lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <!--MySql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.21</version>
        </dependency>

        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>

        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.31</version> <!-- 根据您的项目需求调整版本号 -->
        </dependency>
        <!--mybatis-plus-generator 代码生成器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.4.1</version>
        </dependency>

    </dependencies>

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配置文件 

mapper.java.ftl
<#assign className = table.mapperName>

package ${package.Mapper};

import ${package.Entity}.${entity};
import org.apache.ibatis.annotations.*;
import java.math.BigInteger;

@Mapper
public interface ${className} {

// 根据ID查询操作
@Select("SELECT * FROM ${table.name} WHERE ${table.name}_id =  <#noparse>#{</#noparse>${table.name}Id<#noparse>}</#noparse> AND is_deleted=0")
${entity} getById(BigInteger ${table.name}Id);

// 根据ID提取操作
@Select("SELECT * FROM ${table.name} WHERE ${table.name}_id =  <#noparse>#{</#noparse>${table.name}Id<#noparse>}</#noparse>")
${entity} extractById(BigInteger ${table.name}Id);

// 插入操作
Integer insert(${entity} ${table.name});

// 更新操作
Integer update(${entity} ${table.name});

// 删除操作
@Update("UPDATE ${table.name} SET update_time = <#noparse>#{</#noparse>updateTime<#noparse>}</#noparse> , is_deleted = 1 WHERE ${table.name}_id = <#noparse>#{</#noparse>${table.name}Id<#noparse>}</#noparse>")
Integer delete(@Param("updateTime") Integer updateTime, @Param("${table.name}Id")  BigInteger ${table.name}Id);


}
 mapper.xml.ftl
<?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}">

    <insert id="insert"
            useGeneratedKeys="true"
            keyProperty="id"
            parameterType="${package.Entity}.${entity}">
        insert into ${table.name}(
        <#list table.fields as field>
            <#if field.keyFlag == true>
            <#else>
                <#if field.name == "is_deleted">
                    is_deleted <#if field_has_next>,</#if>
                <#else>
                    <#if field.propertyType == "String">
                        <if test=" ${field.propertyName}  != null and ${field.propertyName} != ''"> `${field.name}` <#if field_has_next>,</#if></if>
                    <#else>
                        <if test=" ${field.propertyName}  != null"> `${field.name}` <#if field_has_next>,</#if></if>
                    </#if>
            </#if>
            </#if>
        </#list>
        )values(
        <#list table.fields as field>
            <#if field.keyFlag == true>
            <#else>
                <#if field.name == "is_deleted">
                    <#noparse>#{</#noparse>isDeleted<#noparse>}</#noparse> <#if field_has_next>,</#if>
                <#else>
                    <#if field.propertyType == "String">
                        <if test="${field.propertyName} != null and ${field.propertyName}!= ''"><#noparse>#{</#noparse>${field.propertyName}<#noparse>}</#noparse><#if field_has_next>,</#if></if>
                    <#else>
                        <if test="${field.propertyName} != null"><#noparse>#{</#noparse>${field.propertyName}<#noparse>}</#noparse><#if field_has_next>,</#if></if>
                    </#if>
            </#if>
            </#if>
        </#list>
        )
    </insert>

    <!-- 更新操作 -->
    <update id="update" parameterType="${package.Entity}.${entity}">
        UPDATE ${table.name}
        <set>
            <#list table.fields as field>
                    <#if field.keyFlag == true>
                        `${table.name}_id` = <#noparse>#{</#noparse>${table.name}Id<#noparse>}</#noparse>,
                    <#else>
                        <#if field.propertyType == "String">
                            <if test="${field.propertyName} != null and ${field.propertyName} != ''">
                                `${field.name}` = <#noparse>#{</#noparse> ${field.propertyName} <#noparse>}</#noparse>,
                            </if>
                        <#else>
                            <if test="${field.propertyName} != null">
                                `${field.name}` = <#noparse>#{</#noparse> ${field.propertyName} <#noparse>}</#noparse>,
                            </if>
                        </#if>
                    </#if>
            </#list>
        </set>
        WHERE `${table.name}_id` = <#noparse>#{</#noparse>${table.name}Id<#noparse>}</#noparse>
    </update>
</mapper>

 entity.java.ftl
package ${package.Entity};
import lombok.Data;
import lombok.experimental.Accessors;


@Data
@Accessors(chain = true)
public class ${entity} {
<#list table.fields as field>
    //${field.comment}
    private ${field.propertyType} ${field.propertyName};
</#list>
}

代码生成类

package com.camp.gen.config;

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/practice?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&serverTimezone=UTC");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("password");
        mpg.setDataSource(dsc);

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

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();
        templateConfig.setMapper("/templates/mapper.java");
        templateConfig.setXml("/templates/mapper.xml");
//        templateConfig.setEntity()
        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("special_subject");
        strategy.setInclude("homestay");
        strategy.setInclude("homestay_special_subject_relation");
        strategy.setInclude("label");
        strategy.setInclude("homestay_label_relation");
        strategy.setInclude("guest_room");
        strategy.setInclude("guest_room_label_relation");
        strategy.setInclude("facilities");
        strategy.setInclude("guest_room_facilities_relation");
//        strategy.setTablePrefix("reservation_label_relation");
        mpg.setStrategy(strategy);

        // 配置额外的输出文件(InjectionConfig可不要这一部分,如果没有额外的输出文件,额外输出文件,如:Spring Cloud的Figen层)
        // ======================= ↓ ==============================
        String injecPath = "com.practice.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";
        }
    }
}
### MyBatis-Plus 代码生成器使用 FreeMarker 模板引擎示例 #### 配置 FreeMarker 模板引擎 为了使 MyBatis-Plus代码生成器能够利用 FreeMarker 模板引擎工作,需先配置 `TemplateConfig` 对象并指定模板路径。这允许开发者自定义不同类型的代码片段如何被渲染。 ```java // 设置模板配置 TemplateConfig templateConfig = new TemplateConfig.Builder() .entity("/templates/entity.java") .service("/templates/service.java") .mapper("/templates/mapper.java") .xml("/templates/mapper.xml") .controller("/templates/controller.java") .build(); ``` 上述代码展示了怎样设置各个模块对应的模板文件位置[^2]。 #### 自定义模板文件 创建所需的 `.ftl` 文件放置于资源目录下的 `/templates/` 路径中。这些文件将作为各层代码生成的基础模版。例如: - 实体类模板 (`entity.java`) - Service 接口和服务实现类模板 (`service.java`, `ServiceImpl.java`) - Mapper 接口及其 XML 映射文件模板 (`mapper.java`, `mapper.xml`) - 控制器模板 (`controller.java`) 每个`.ftl`文件都遵循 FreeMarker 语法规范,并可以嵌入动态变量用于替换实际值。 #### 启动代码生成过程 完成以上准备工作之后,可以通过如下方式启动代码生成功能: ```java AutoGenerator mpg = new AutoGenerator(new DataSourceConfig.Builder(url, username, password)); mpg.setPackageInfo( new PackageConfig.Builder() .parent("com.example") // 父级包名 .moduleName("demo") // 子模块名称 .pathInfo(Collections.singletonMap(OutputFile.mapperXml, "/src/main/resources/mapper")) // 输出路径映射 .build()); mpg.setGlobalConfig( new GlobalConfig.Builder() .outputDir(System.getProperty("user.dir") + "/src/main/java") // Java源码输出根目录 .author("Your Name Here") // 作者名字 .fileOverride() // 是否覆盖已有文件 .disableOpenDir() // 关闭打开输出目录功能 .build()); mpg.setStrategy( new StrategyConfig.Builder() .addInclude("table_name") // 表白名单 .versionFieldName("version") // 版本字段名 .logicDeleteFieldName("deleted") // 逻辑删除字段名 .build()); mpg.setTemplate(templateConfig); // 应用之前设定好的模板配置 mpg.execute(); // 执行代码生成操作 ``` 这段代码构建了一个完整的自动化代码生成流程实例,其中包含了数据源连接信息、包命名空间规划以及具体策略选项等内容[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宁好.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值