Mybatis-Plus 3.5.2 + Freemake代码生成器

晋功
2023-12-01

1.引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.2</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.5.2</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger-common</artifactId>
    <version>3.0.0</version>
</dependency>

2.快速代码生成器

public class CodeGenerator {

    private static String url="jdbc:mysql://localhost:3306/mybatis-plus?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";

    private static String username="root";

    private static String password="666666";

    public static void main(String[] args) {
        FastAutoGenerator.create(url, username, password)
                .globalConfig(builder -> {
                    builder.author("deyo") // 设置作者
                            .enableSwagger() // 开启 swagger 模式
                            .fileOverride() // 覆盖已生成文件
                            .outputDir( System.getProperty("user.dir")+"/src/main/java"); // 指定输出目录


                })
                .packageConfig(builder -> {
                    builder.parent("deyo.xyz") // 设置父包名
                            .moduleName("system") // 设置父包模块名
                            .pathInfo( Collections.singletonMap( OutputFile.xml, System.getProperty("user.dir")+"/src/main/resources/mapper")); // 设置mapperXml生成路径
                })
                .strategyConfig(builder -> {
                    builder.addInclude("user") // 设置需要生成的表名,多表用逗号分割
                            .addTablePrefix("", ""); // 设置过滤表前缀
                })
                .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                .execute();
    }
}

3 交互式生成代码(推荐)

package deyo.xyz.system;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * @Author deyou
 * @Date 2022/6/27 18:00
 * @Version 1.0
 */


public class CodeGenerator2 {

    private static String url="jdbc:mysql://localhost:3306/mybatis-plus?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";

    private static String username="root";

    private static String password="666666";

    public static void main(String[] args) {
        FastAutoGenerator.create( url, username, password )
                // 全局配置
                .globalConfig( (scanner, builder) -> builder
                        //.enableSwagger() // 开启 swagger 模式
                        .outputDir( System.getProperty("user.dir")+"/src/main/java") // 指定输出目录
                        .author( scanner.apply( "请输入作者名称?" ) )
                        .fileOverride() )
                // 包配置
                .packageConfig( (scanner, builder) -> builder

                        .pathInfo( Collections.singletonMap( OutputFile.xml, System.getProperty("user.dir")+"/src/main/resources/mapper"))
                        .parent( scanner.apply( "请输入包名?" ) )
                        .moduleName( scanner.apply( "请输入模块名?" ) ) )

                // 策略配置
                .strategyConfig( (scanner, builder) -> builder
                        .addInclude( getTables( scanner.apply( "请输入表名,多个英文逗号分隔?所有输入 all" ) ) )
                        .addTablePrefix( "","","" ) //设置过滤表前缀
                        .controllerBuilder()
                        .enableRestStyle()
                        .enableHyphenStyle()
                        .entityBuilder()
                        .enableLombok() //设置是否使用Lombok

                        .addTableFills(
                                new Column( "create_time", FieldFill.INSERT ),
                                new Column( "update_time", FieldFill.INSERT_UPDATE )
                                       
                        )
                        .build() )
                /*
                    模板引擎配置,默认 Velocity 可选模板引擎 Beetl 或 Freemarker
                   .templateEngine(new BeetlTemplateEngine())*/
                   .templateEngine(new FreemarkerTemplateEngine())

                .execute();
    }
    // 处理 all 情况
    protected static List<String> getTables (String tables){
        return "all".equals( tables ) ? Collections.emptyList() : Arrays.asList( tables.split( "," ) );
    }
}

4.配置xml 文件存放路径 application.yml

#默认配置可以不用配置
mybatis-plus:
  mapper-locations: classpath*:/mapper/**/*.xml

5 配置数据库

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/自己的数据库?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: 666666
    driver-class-name: com.mysql.cj.jdbc.Driver

6 在Springboot项目中

代码自动生成后记得在启动类添加

@MapperScan("deyo.xyz.XXX.mapper")

7. 使用自定义的Controller 模版,

在resources/templates文件夹下放入默认的文件名即可。

7.1 导入分页工具类

PageUtils

@Component
public class PageUtils {
    // 页面
    private static final String PAGE_STR = "current";
    private static final Integer DEFAULT_PAGE = 1;
    // 页面数据数量
    private static final String SIZE_STR = "size";
    private static final Integer DEFAULT_SIZE = 10;
    // 排序 是否正序排列,默认 true
    private static final String SORT_STR = "sort";
    private static final Boolean DEFAULT_SORT = true;
    private static final String SORT_NAME_STR = "sortName";

    @Autowired
    private HttpServletRequest request;

    /**
     * 获取分页数据
     */
    public Page page(){

        Page page = new Page();
        page.setCurrent(getPages());
        page.setSize(getSize());
        List<OrderItem> orderItems = getOrders(getSort(),getSortName());
        if(orderItems != null && orderItems.size() > 0){
            page.setOrders(orderItems);
        }

        return page;
    }
    /**
     * 自定义设置分页数据
     */
    public Page getPage(Long pages,Long size,boolean sort,String sortName){

        Page page = new Page();
        if(pages!=null){
            page.setCurrent(pages);
        }
        if(size!=null){
            page.setSize(size);
        }
        List<OrderItem> orderItems = getOrders(sort,sortName);
        if(orderItems != null && orderItems.size() > 0){
            page.setOrders(orderItems);
        }

        return page;
    }
    /**
     * 排序
     */
    private List<OrderItem> getOrders(boolean sort,String sortName){

        // 排序字段
        if(StringUtils.isBlank(sortName)){
            return null;
        }

        List<OrderItem> orderItems = new ArrayList<>();
        OrderItem orderItem = new OrderItem();
        orderItem.setColumn(sortName);
        orderItem.setAsc(sort);

        orderItems.add(orderItem);

        return orderItems;
    }

    /**
     * 获取page参数
     */
    private Integer getPages(){
        String page = request.getParameter(PAGE_STR);
        return StringUtils.isBlank(page) ? DEFAULT_PAGE : Integer.valueOf(page);
    }

    /**
     * 获取size参数
     */
    private Integer getSize(){
        String page = request.getParameter(SIZE_STR);
        return StringUtils.isBlank(page) ? DEFAULT_SIZE : Integer.valueOf(page);
    }

    /**
     * 获取sortName参数
     */
    private String getSortName(){
        return request.getParameter(SORT_NAME_STR);
    }

    /**
     * 获取sort参数 是否正序排列,默认 true
     */
    private boolean getSort(){

        String str = request.getParameter(SORT_STR);

        return StringUtils.isBlank(str) ? DEFAULT_SORT : Boolean.valueOf(str);
    }

}

ResponseResult

package deyo.xyz.utils;

import com.fasterxml.jackson.annotation.JsonInclude;

import java.io.Serializable;

/**
 * @Author deyou
 * @Date 2022/2/2 21:25
 * @Version 1.0
 */

@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResponseResult<T> implements Serializable {
    private Integer code;
    private String msg;
    private T data;

    public ResponseResult() {
        this.code = AppHttpCodeEnum.SUCCESS.getCode();
        this.msg = AppHttpCodeEnum.SUCCESS.getMsg();
    }

    public ResponseResult(Integer code, T data) {
        this.code = code;
        this.data = data;
    }

    public ResponseResult(Integer code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public ResponseResult(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public static ResponseResult errorResult(int code, String msg) {
        ResponseResult result = new ResponseResult();
        return result.error(code, msg);
    }
    public static ResponseResult okResult() {
        ResponseResult result = new ResponseResult();
        return result;
    }
    public static ResponseResult okResult(int code, String msg) {
        ResponseResult result = new ResponseResult();
        return result.ok(code, null, msg);
    }

    public static ResponseResult okResult(Object data) {
        ResponseResult result = setAppHttpCodeEnum(AppHttpCodeEnum.SUCCESS, AppHttpCodeEnum.SUCCESS.getMsg());
        if(data!=null) {
            result.setData(data);
        }
        return result;
    }

    public static ResponseResult errorResult(AppHttpCodeEnum enums){
        return setAppHttpCodeEnum(enums,enums.getMsg());
    }

    public static ResponseResult errorResult(AppHttpCodeEnum enums, String msg){
        return setAppHttpCodeEnum(enums,msg);
    }

    public static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums){
        return okResult(enums.getCode(),enums.getMsg());
    }

    private static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums, String msg){
        return okResult(enums.getCode(),msg);
    }

    public ResponseResult<?> error(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
        return this;
    }

    public ResponseResult<?> ok(Integer code, T data) {
        this.code = code;
        this.data = data;
        return this;
    }

    public ResponseResult<?> ok(Integer code, T data, String msg) {
        this.code = code;
        this.data = data;
        this.msg = msg;
        return this;
    }

    public ResponseResult<?> ok(T data) {
        this.data = data;
        return this;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }



}

AppHttpCodeEnum

public enum AppHttpCodeEnum {
    // 成功
    SUCCESS(200,"操作成功"),
    // 登录
    NEED_LOGIN(401,"需要登录后操作"),
    NO_OPERATOR_AUTH(403,"无权限操作"),
    SYSTEM_ERROR(500,"出现错误"),
    USERNAME_EXIST(501,"用户名已存在"),
    PHONENUMBER_EXIST(502,"手机号已存在"), EMAIL_EXIST(503, "邮箱已存在"),
    REQUIRE_USERNAME(504, "必需填写用户名"),
    LOGIN_ERROR(505,"用户名或密码错误");
    int code;
    String msg;

    AppHttpCodeEnum(int code, String errorMessage){
        this.code = code;
        this.msg = errorMessage;
    }

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

7.2 配置模版

controller.java.ftl

package ${package.Controller};

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

import deyo.xyz.utils.ResponseResult;配置自己的包的路径
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

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


import javax.validation.Valid;
import java.util.List;

/**
* <p>
 * ${table.comment} 前端控制器
 * </p>
*
* @author ${author}
* @since ${date}
*/
@Api(tags = "${table.comment}")
<#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>

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

    @ApiOperation(value = "${table.comment}分页列表", response = ${entity}.class)
    @ApiImplicitParams({
    @ApiImplicitParam(name = "page", value = "页面", dataType = "Long"),
    @ApiImplicitParam(name = "size", value = "页面数据量", dataType = "Long"),
    @ApiImplicitParam(name = "sort", value = "排序方式排序[true:正序; false:倒序]", dataType = "Boolean"),
    @ApiImplicitParam(name = "sortName", value = "排序字段,参照返回字段", dataType = "String")})
    @PostMapping(value = "/page")
    public  Object list(@Valid @RequestBody ${entity} param) {

    Object data = ${table.serviceName?uncap_first}.page(param);
    return ResponseResult.okResult(data);
    }

    @ApiOperation(value = "${table.comment}详情", response = ${entity}.class)
    @GetMapping(value = "/info/{id}")
    public  Object info(@PathVariable Long id) {

    Object data = ${table.serviceName?uncap_first}.info(id);
    return ResponseResult.okResult(data);
    }

    @ApiOperation(value = "${table.comment}新增")
    @PostMapping(value = "/add")
    public  Object add(@Valid @RequestBody ${entity} param) {

    ${table.serviceName?uncap_first}.add(param);
    return ResponseResult.okResult();
    }

    @ApiOperation(value = "${table.comment}修改")
    @PostMapping(value = "/modify")
    public  Object modify(@Valid @RequestBody ${entity} param) {

    ${table.serviceName?uncap_first}.modify(param);
    return ResponseResult.okResult();
    }

    @ApiOperation(value = "${table.comment}删除(单个条目)")
    @GetMapping(value = "/remove/{id}")
    public  Object remove(@PathVariable Long id) {

    ${table.serviceName?uncap_first}.remove(id);
    return ResponseResult.okResult();
    }

    @ApiOperation(value = "${table.comment}删除(多个条目)")
    @PostMapping(value = "/removes")
    public  Object removes(@Valid @RequestBody List<Long> ids) {

    ${table.serviceName?uncap_first}.removes(ids);
    return ResponseResult.okResult();
    }

 }
 </#if>

service.java.ftl

package ${package.Service};

import ${package.Entity}.${entity};
import ${superServiceClassPackage};
import com.baomidou.mybatisplus.core.metadata.IPage;

import java.util.List;

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

       /**
       * ${table.comment!}分页列表
       * @param param 根据需要进行传值
       * @return
       */
       IPage<${entity}> page(${entity} param);

       /**
       * ${table.comment!}详情
       * @param id
       * @return
       */
       ${entity} info(Long id);

       /**
       * ${table.comment!}新增
       * @param param 根据需要进行传值
       * @return
       */
       void add(${entity} param);

       /**
       * ${table.comment!}修改
       * @param param 根据需要进行传值
       * @return
       */
       void modify(${entity} param);

       /**
       * ${table.comment!}删除(单个条目)
       * @param id
       * @return
       */
       void remove(Long id);

       /**
       * 删除(多个条目)
       * @param ids
       * @return
       */
       void removes(List<Long> ids);
       }
</#if>

serviceImpl.java.ftl

package ${package.ServiceImpl};

import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;

import deyo.xyz.utils.PageUtils;//配置自己的包的路径
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;

/**
* <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} {

    @Autowired
    private PageUtils pageUtils;

    /**
    * ${table.comment!}分页列表
    * @param param 根据需要进行传值
    * @return
    */
    @Override
    public IPage<${entity}> page(${entity} param) {

    QueryWrapper<${entity}> queryWrapper = new QueryWrapper<>();
    queryWrapper.lambda()
    <#list table.fields as field>
     // ${field.comment}
     <#if !entityLombokModel>
      <#if field.propertyType == "Boolean">
       <#assign getprefix="is"/>
      <#else>
       <#assign getprefix="get"/>
      </#if>
      <#if field.propertyType == "String">
       .eq(!StringUtils.isEmpty(param.${getprefix}${field.capitalName}()), ${entity}::${getprefix}${field.capitalName}, param.${getprefix}${field.capitalName}())
      <#else>
       .eq(param.${getprefix}${field.capitalName}() != null, ${entity}::${getprefix}${field.capitalName}, param.${getprefix}${field.capitalName}())
      </#if>
     <#else>
      <#if field.propertyType == "String">
       .eq(!StringUtils.isEmpty(param.get${field.capitalName}()), ${entity}::get${field.capitalName}, param.get${field.capitalName}())
      <#else>
       .eq(param.get${field.capitalName}() != null, ${entity}::get${field.capitalName}, param.get${field.capitalName}())
      </#if>
     </#if>
    </#list>;

    IPage<${entity}> page = page(pageUtils.page(), queryWrapper);

    return page;
    }

    /**
    * ${table.comment!}详情
    * @param id
    * @return
    */
    @Override
    public ${entity} info(Long id) {

    return getById(id);
    }

    /**
    * ${table.comment!}新增
    * @param param 根据需要进行传值
    * @return
    */
    @Override
    public void add(${entity} param) {

    save(param);
    }

    /**
    * ${table.comment!}修改
    * @param param 根据需要进行传值
    * @return
    */
    @Override
    public void modify(${entity} param) {

    updateById(param);
    }

    /**
    * ${table.comment!}删除(单个条目)
    * @param id
    * @return
    */
    @Override
    public void remove(Long id) {
    removeById(id);
    }

    /**
    * ${table.comment!}删除(多个条目)
    * @param ids
    * @return
    */
    @Override
    public void removes(List<Long> ids) {

     removeByIds(ids);
     }
 }
 </#if>

注意

搭建好项目

  • 设置好数据库信息
  • 先导入工具类
  • 在controller.java.ftl 和 serviceImpl.java 模版中手动导入工具类的路径。

就可以生成代码了

 类似资料: