MybatisPlus代码生成器 + FreeMarker 模板
一.引言
代码生成本身往往难以满足项目中的自定义需求,结合 FreeMarker 模板 进行代码生成的个性化定制。
二.代码生成步骤
1.配置依赖
2.修改ftl文件
3。编写代码生成器
三.配置类编写
参考Mybatis-plus官网:https://baomidou.com/reference/new-code-generator-configuration/
FreeMarker 模板对象属性和方法
| 对象 | 属性/方法 | 作用 | 用法 |
|---|---|---|---|
| package | package.Entity | 获取实体类包名 | package ${package.Entity}; |
package.Mapper | 获取 Mapper 包名 | package ${package.Mapper}; | |
package.Controller | 获取 Controller 包名 | package ${package.Controller}; | |
| table | table.importPackages | 获取导入的包 | ${table.importPackages} |
table.comment | 获取表描述 | ${table.comment!} | |
table.convert | 转换字段 | ${table.convert} | |
table.name | 获取表名 | ${table.name} | |
table.mapperName | 获取 Mapper 名称 | ${table.mapperName} | |
table.controllerName | 获取 Controller 名称 | ${table.controllerName} | |
table.fields | 获取表字段列表 | ${table.fields} | |
| superMapperClass | superMapperClass | 获取 Mapper 父类 | ${superMapperClass} |
superMapperClassPackage | 获取 Mapper 父类包 | import ${superMapperClassPackage}; | |
| entity | entity | 获取实体类名 | ${entity} |
| date | date | 获取当前日期 | ${date} |
| author | author | 获取作者 | ${author} |
| field | field.comment | 获取字段描述 | ${field.comment} |
field.keyFlag | 获取字段主键标识 | ${field.keyFlag} | |
field.keyIdentityFlag | 获取字段自增标识 | ${field.keyIdentityFlag} | |
field.name | 获取字段名 | ${field.name} | |
field.convert | 获取字段转换规则 | ${field.convert} | |
field.propertyType | 获取字段属性类型 | ${field.propertyType} | |
field.capitalName | 获取字段首字母大写名 | ${field.capitalName} | |
field.propertyName | 获取字段属性名 | ${field.propertyName} |
FreeMarker 模板控制语句
| 语句 | 条件 | 用法 |
|---|---|---|
| if | 判断某个条件是否为真 | <#if condition> ... </#if> |
| else | 在 if 条件不成立时执行 | <#else> ... </#else> |
| elseif | 额外条件判断 | <#elseif condition> ... </#elseif> |
| list | 遍历列表或集合 | <#list list as item> ... </#list> |
| macro | 定义一个宏 | <#macro macroName> ... </#macro> |
| include | 引入其他模板 | <#include "filename.ftl"> |
| assign | 赋值操作 | <#assign varName = value> |
| noparse | 禁用 FreeMarker 的语法解析 | <#noparse> ... </#noparse> |
| function | 调用自定义函数 | <#function funcName> ... </#function> |
| break | 终止循环或条件判断 | <#break> |
| continue | 跳过当前循环的剩余部分,继续下一轮 | <#continue> |
| case | 类似于 switch 语句的判断 | <#case condition> ... </#case> |
在resources里创建templates文件夹存放需要编写的ftl

引入相关依赖信息
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.31</version>
</dependency>
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} {
// 获取类目列表
@Select("SELECT * FROM ${table.name} WHERE is_deleted=0")
List<${entity}> getAll();
// 根据ID查询操作
@Select("SELECT * FROM ${table.name} WHERE id = <#noparse>#{</#noparse>id<#noparse>}</#noparse> AND is_deleted=0")
${entity} getById(@Param("id")BigInteger id);
// 根据ID提取操作
@Select("SELECT * FROM ${table.name} WHERE id = <#noparse>#{</#noparse>id<#noparse>}</#noparse>")
${entity} extractById(@Param("id")BigInteger id);
// 插入操作
int insert(@Param("category") ${entity} ${table.name});
// 更新操作
int update(@Param("${table.name}") ${entity} ${table.name});
// 删除操作
@Update("UPDATE ${table.name} SET updated_time = <#noparse>#{</#noparse>time<#noparse>}</#noparse> , is_deleted = 1 WHERE id = <#noparse>#{</#noparse>id<#noparse>}</#noparse>")
int delete(@Param("id")BigInteger id,@Param("time") Integer time );
}
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" parameterType="${package.Entity}.${entity}">
insert into ${table.name} (
<#list table.fields as field>
<if test="${table.name}.${field.propertyName} != null and ${table.name}.${field.propertyName} !=''">${field.name}<#if field_has_next>,</#if></if>
</#list>
)
values (
<#list table.fields as field>
<if test="${field.propertyName} != null and ${table.name}.${field.propertyName} !=''"><#noparse>#{</#noparse>${table.name}.${field.propertyName}<#noparse>}</#noparse><#if field_has_next>,</#if></if>
</#list>
)
</insert>
<!-- 更新操作 -->
<update id="update" parameterType="${package.Entity}.${entity}">
update ${table.name} set id = #{</#noparse>${table.name}.${field.propertyName}<#noparse>}
<#list table.fields as field>
<if test="${table.name}.${field.propertyName} != null and ${table.name}.${field.propertyName} !=''">${field.name} = <#noparse>#{</#noparse>${table.name}.${field.propertyName}<#noparse>}</#noparse><#if field_has_next>,</#if></if>
</#list>
where 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>
}
serviceImpl.java.ftl
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} {
@Resource
private ${table.mapperName} mapper;
public ${entity} getById(BigInteger id) {
return mapper.getById(id);
}
public ${entity} extractById(BigInteger id) {
return mapper.extractById(id);
}
public List<${entity}> getAll() {
return mapper.getAll();
}
//创建商品类目
public int insert(${entity} ${entity?uncap_first}){
return mapper.insert(${entity?uncap_first});
}
//更新商品类目
public int update(${entity} ${entity?uncap_first}){
return mapper.update(${entity?uncap_first});
}
// 删除商品类目
public int delete(BigInteger id) {
return mapper.delete(id, (int) (System.currentTimeMillis() / 1000));
}
}
</#if>
controller.java.ftl
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>
</#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>
@Autowired
private ${table.serviceImplName} service;
}
</#if>
代码生成类编写
package com.example.multi.console;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.TemplateType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
public class CodeGenerator {
public static void main(String[] args) {
// 使用 FastAutoGenerator 快速配置代码生成器
FastAutoGenerator.create("jdbc:mysql://localhost:3306/xiaobai_Mall?serverTimezone=GMT%2B8", "root", "Aa258369")
.globalConfig(builder -> {
builder.author("小白-945") // 设置作者
.outputDir("/Users/liuzefeng/Documents/JavaWeb/good/console/src/main/java/com/example/multi"); // 输出目录
})
.packageConfig(builder -> {
builder.parent("category") // 设置父包名
.controller("controller")
.service("service")
.entity("entity") // 设置实体类包名
.mapper("mapper") // 设置 Mapper 接口包名
.xml("mappers"); // 设置 Mapper XML 文件包名
})
.strategyConfig(builder -> {
builder.addInclude("category") // 设置需要生成的表名
.entityBuilder()
.enableLombok() // 启用 Lombok
.enableTableFieldAnnotation() // 启用字段注解
.controllerBuilder()
.enableRestStyle(); // 启用 REST 风格
})
.templateEngine(new FreemarkerTemplateEngine()) // 使用 Freemarker 模板引擎
.execute(); // 执行生成
//配置模版
TemplateConfig templateConfig = new TemplateConfig.Builder()
.disable(TemplateType.ENTITY)
.entity("/templates/entity.java")
.mapper("/templates/mapper.java")
.mapper("/templates/mapper.xml")
.controller("/templates/controller.java")
.build();
}
}


被折叠的 条评论
为什么被折叠?



