Mybatis-Plus 代码生成器,自定义模板Demo,快速搭建!!

Mybatis-Plus 代码生成器,自定义模板Demo,快速搭建!!

前言

详细信息以及具体配置方法解析–》官方文档:https://baomidou.com/

1.所需maven :

velocity 和 freemarker 选择导入,velocity 对应vm的模板,freemarker 对应flt模板,自定义模板,需要将导入进的配置下的模板复制到自己项目的resource下
01:Mybatis-Plus 下的模板
Mybatis-Plus 下的模板
02:自己项目 resource 新建 templates
自己项目 resource
03:maven:

    <dependencies>
        <!-- mybatis plus 代码生成器 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
        
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.1</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.3</version>
        </dependency>
        
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.31</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

    </dependencies>

2.代码生成配置

package cn.hb.ycmm.basic;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import com.baomidou.mybatisplus.generator.fill.Column;
import com.baomidou.mybatisplus.generator.keywords.MySqlKeyWordsHandler;

import java.util.Collections;

public class MyBatisPlusGenerator {

    public static void main(String[] args) {

        String projectPath = System.getProperty("user.dir");
        System.out.println(projectPath);
        // 数据源配置
        DataSourceConfig.Builder dataSourceConfig = new DataSourceConfig
                .Builder(
                "jdbc:mysql://127.0.0.1:3306/hb_ycmm?useUnicode=true&serverTimezone=GMT&useSSL=false&characterEncoding=utf8",
                "root",
                "password")
                .dbQuery(new MySqlQuery())
                .typeConvert(new MySqlTypeConvert())
                .keyWordsHandler(new MySqlKeyWordsHandler());

        FastAutoGenerator.create(dataSourceConfig)
                .globalConfig(builder -> {
                    builder.author("Hua.bin") //设置作者
                            .commentDate("YYYY-MM-DD HH:mm:ss")//注释日期
                            .outputDir(projectPath + "/ycmm-service/ycmm-service-system/src/main/java"); //指定输出目录

                })
                .packageConfig(builder -> {
                    builder.parent("cn.hb.ycmm.system") // 设置父包名
                            .moduleName("") // 设置父包模块名
                            .entity("entity")
                            .service("service") // service包名
                            .serviceImpl("service.impl") // serviceImpl包名
                            .mapper("mapper") // mapper包名
                            .controller("controller") // Controller 包名	默认值:controller
                            .other("param") // 自定义文件包名	输出自定义文件时所用到的包名
                            .pathInfo(Collections.singletonMap(OutputFile.entity,projectPath + "/ycmm-pojo/ycmm-pojo-system/src/main/java"))
                            .pathInfo(Collections.singletonMap(OutputFile.mapperXml, projectPath + "/ycmm-service/ycmm-service-system/src/main//resources/mappers")); // 设置mapperXml生成路径
                })
                .strategyConfig(builder -> {
//
                    builder.addInclude("t_config") // 设置需要生成的表名 请输入表名,多个英文逗号分隔?所有输入 all:
                            .addTablePrefix("t_")// 设置过滤表前缀

                            // Entity 策略配置
                            .entityBuilder()
                            .enableLombok() // 开启lombok
                            .enableChainModel() // 链式
                            .enableRemoveIsPrefix() // 开启boolean类型字段移除is前缀
                            .enableTableFieldAnnotation() //开启生成实体时生成的字段注解
                            .versionColumnName("请输入数据库中的乐观锁字段") // 乐观锁数据库字段
                            .versionPropertyName("请输入字段中的乐观锁名称") // 乐观锁实体类名称
                            .logicDeleteColumnName("请输入数据库中的逻辑删除字段") // 逻辑删除数据库中字段名
                            .logicDeletePropertyName("请输入数据库中的实体名称") // 逻辑删除实体类中的字段名
                            .naming(NamingStrategy.underline_to_camel) // 表名 下划线 -》 驼峰命名
                            .columnNaming(NamingStrategy.underline_to_camel) // 字段名 下划线 -》 驼峰命名
                            .idType(IdType.ASSIGN_UUID) // 主键生成策略 雪花算法生成id
                            .formatFileName("%sEntity") // Entity 文件名称
                            .addTableFills(new Column("create_time", FieldFill.INSERT), new Column("update_time", FieldFill.INSERT_UPDATE))//生成时间自动填充属性
                            .controllerBuilder().enableRestStyle()//开启@RestController风格
                            .serviceBuilder().formatServiceFileName("%sService"); //去掉默认的I前缀
                })

                //使用Freemarker引擎模板,默认的是Velocity引擎模板
                .templateEngine(new VelocityTemplateEngine())
                //设置自定义模板路径
                .templateConfig(builder -> {
                    builder.entity("/templates/entity.java.vm")
                            .service("/templates/service.java.vm")
                            .serviceImpl("/templates/serviceImpl.java.vm")
                            .controller("/templates/controller.java.vm");
                })

                //注入配置————自定义模板
                .injectionConfig(builder -> builder
                        .beforeOutputFile((tableInfo, objectMap) -> {
                            System.out.println("tableInfo: " + tableInfo.getEntityName() + " objectMap: " + objectMap.size());
                        }) //输出文件之前消费者
                        .customMap(Collections.singletonMap("my_field", "自定义配置 Map 对象")) //自定义配置 Map 对象
                        .customFile(Collections.singletonMap("query.java", "/templates/query.java.vm")) //自定义配置模板文件
                        .build()//加入构建队列
                )

                .execute();

    }

}

3.自定义模板

3.1 公共基础类

import cn.hb.ycmm.common.utils.ObjectUtil;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.util.Optional;
import org.springframework.lang.Nullable;

@ApiModel(
    description = "返回信息"
)
public class R<T> implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(
        value = "状态码",
        required = true
    )
    private int code;
    @ApiModelProperty(
        value = "是否成功",
        required = true
    )
    private boolean success;
    @ApiModelProperty("承载数据")
    private T data;
    @ApiModelProperty(
        value = "返回消息",
        required = true
    )
    private String msg;

    private R(IResultCode resultCode) {
        this(resultCode, (T) null, resultCode.getMessage());
    }

    private R(IResultCode resultCode, String msg) {
        this(resultCode, (T) null, msg);
    }

    private R(IResultCode resultCode, T data) {
        this(resultCode, data, resultCode.getMessage());
    }

    private R(IResultCode resultCode, T data, String msg) {
        this(resultCode.getCode(), data, msg);
    }

    private R(int code, T data, String msg) {
        this.code = code;
        this.data = data;
        this.msg = msg;
        this.success = ResultCode.SUCCESS.code == code;
    }

    public static boolean isSuccess(@Nullable R<?> result) {
        return (Boolean)Optional.ofNullable(result).map((x) -> {
            return ObjectUtil.nullSafeEquals(ResultCode.SUCCESS.code, x.code);
        }).orElse(Boolean.FALSE);
    }

    public static boolean isNotSuccess(@Nullable R<?> result) {
        return !isSuccess(result);
    }

    public static <T> R<T> data(T data) {
        return data(data, "操作成功");
    }

    public static <T> R<T> data(T data, String msg) {
        return data(200, data, msg);
    }

    public static <T> R<T> data(int code, T data, String msg) {
        return new R(code, data, data == null ? "暂无承载数据" : msg);
    }

    public static <T> R<T> success(String msg) {
        return new R(ResultCode.SUCCESS, msg);
    }

    public static <T> R<T> success(IResultCode resultCode) {
        return new R(resultCode);
    }

    public static <T> R<T> success(IResultCode resultCode, String msg) {
        return new R(resultCode, msg);
    }

    public static <T> R<T> fail(String msg) {
        return new R(ResultCode.FAILURE, msg);
    }

    public static <T> R<T> fail(int code, String msg) {
        return new R(code, (Object)null, msg);
    }

    public static <T> R<T> fail(IResultCode resultCode) {
        return new R(resultCode);
    }

    public static <T> R<T> fail(IResultCode resultCode, String msg) {
        return new R(resultCode, msg);
    }

    public static <T> R<T> status(boolean flag) {
        return flag ? success("操作成功") : fail("操作失败");
    }

    public int getCode() {
        return this.code;
    }

    public boolean isSuccess() {
        return this.success;
    }

    public T getData() {
        return this.data;
    }

    public String getMsg() {
        return this.msg;
    }

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

    public void setSuccess(final boolean success) {
        this.success = success;
    }

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

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

    public String toString() {
        return "R(code=" + this.getCode() + ", success=" + this.isSuccess() + ", data=" + this.getData() + ", msg=" + this.getMsg() + ")";
    }

    public R() {
    }
}
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.Setter;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.util.Objects;

/**
 * @author hua.bin
 * @version 1.0.0
 * @ClassName BaseQuery.java
 * @Description 公共查询
 * @createTime 2022-05-13
 */
@Data
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ApiModel
public class BaseQuery {

    @NotNull(message = "页码不能为空")
    @Min(1)
    @ApiModelProperty("页码")
    private Integer current;

    @NotNull(message = "分页size不能为空")
    @ApiModelProperty("分页size")
    private Integer size;


    public Integer getCurrent() {
        return Objects.isNull(current) ? 1 : Math.max(1, current);
    }

    public Integer getSize() {
        return Objects.nonNull(size) ? Math.min(100, Math.max(1, size)) : 10;
    }

}

3.2 自定义模板(vm)

3.21 controller模板
package ${package.Controller};


import org.springframework.beans.factory.annotation.Autowired;
import cn.hb.ycmm.common.api.R;
import io.swagger.annotations.*;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestMapping;

#if(${restControllerStyle})
import org.springframework.web.bind.annotation.RestController;
#else
import org.springframework.stereotype.Controller;
#end
#if(${superControllerClassPackage})
import ${superControllerClassPackage};
#end

/**
 * <p>
 * $!{table.comment} 前端控制器
 * </p>
 *
 * @author ${author}
 * @since ${date}
 */
#if(${restControllerStyle})
@RestController
#else
@Controller
#end
@RequestMapping("#if(${package.ModuleName})/${package.ModuleName}#end/#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end")
@Api(value = "${table.controllerName}",tags = "${table.controllerName}")
#if(${kotlin})
class ${table.controllerName}#if(${superControllerClass}) : ${superControllerClass}()#end

#else
#if(${superControllerClass})
public class ${table.controllerName} extends ${superControllerClass} {
#else
public class ${table.controllerName} {
#end

@Autowired
private ${table.serviceName} ${table.entityPath}Service;

@PostMapping("/save")
@ApiOperation("添加XXL")
@ApiImplicitParams({
        @ApiImplicitParam(value = "token", paramType = "header", name = "token", required = true)
})
public  R save(@RequestBody ${entity} ${table.entityPath}){
        return R.status( ${table.entityPath}Service.insert${entity}(${table.entityPath}));
        }

@PostMapping("/update")
@ApiOperation("修改XXL")
@ApiImplicitParams({
        @ApiImplicitParam(value = "token", paramType = "header", name = "token", required = true)
})
public  R update(@RequestBody ${entity} ${table.entityPath}){
        return R.status( ${table.entityPath}Service.update${entity}(${table.entityPath}));
        }

@PostMapping("/delete")
@ApiOperation("删除XXL")
@ApiImplicitParams({
        @ApiImplicitParam(value = "token", paramType = "header", name = "token", required = true)
})
public R delete(@PathVariable("id") Long id){
        return R.status(${table.entityPath}Service.delete${entity}(id));
        }

@GetMapping("/queryById")
@ApiOperation("查询XXL实体对象")
@ApiImplicitParams({
        @ApiImplicitParam(value = "token", paramType = "header", name = "token", required = true)
})
@ApiResponses(@ApiResponse(code = 200, message = "成功", response = ${entity}.class))
public R<${entity}> get(@PathVariable("id")Long id){
        return R.data(${table.entityPath}Service.queryById(id));
        }

@PostMapping("/pageList")
@ApiOperation("查询XXL列表")
@ApiImplicitParams({
        @ApiImplicitParam(value = "token", paramType = "header", name = "token", required = true)
})
@ApiResponses(@ApiResponse(code = 200, message = "成功", response = ${entity}.class))
public R<IPage<${entity}>> pageList(@RequestBody ${entity}QueryParam queryParam){
        return R.data(${table.entityPath}Service.pageList(queryParam));
        }


}

#end
3.22 service模板(vm)
package ${package.Service};

import cn.hb.ycmm.common.api.R;
import com.baomidou.mybatisplus.core.metadata.IPage;
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}> {

        Boolean insert${entity}(${entity} ${table.entityPath});

        Boolean update${entity}(${entity} ${table.entityPath});

        Boolean delete${entity}(Long id);

        ${entity} queryById(Long id);

        IPage<${entity}> pageList(${entity}QueryParam queryParam);


        }
#end

3.23 serviceImpl模板(vm)
package ${package.ServiceImpl};

import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import cn.hb.ycmm.common.api.R;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.web.bind.annotation.*;
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} {

        @Override
        public Boolean insert${entity}(${entity} ${table.entityPath}){
        return this.save(${table.entityPath});
        }

        @Override
        public Boolean update${entity}(${entity} ${table.entityPath}){
        return this.updateById(${table.entityPath});
        }

        @Override
        public Boolean delete${entity}(Long id){
        return this.removeById(id);
        }

        @Override
        public ${entity} queryById(Long id){
        return this.getById(id);
        }

        @Override
        public IPage<${entity}> pageList(${entity}QueryParam queryParam){
        Page<${entity}> page = this.page(new Page<>(queryParam.getCurrent(), queryParam.getSize()));
        return page;
        }

}
#end

3.24公共查询基础模板(vm):
package ${package.Entity};

import cn.hb.ycmm.common.api.BaseQuery;
import io.swagger.annotations.ApiModel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.validation.annotation.Validated;

/**
 *
 * @author ${author}
 * @since ${date}
 */
@Data
@Builder
@Validated
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("查询XXL入参")
public class ${table.entityName}QueryParam extends BaseQuery{
}