mybatis-plus代码自动生成generator配置实现

目录

简介

一、maven依赖

二、编写generator代码生成器

三、编写自己的模版

1.实体类模版

2.控制层controller模版


简介

mybatis-plus是mybatis的升级版,在 mybatis 的基础上只做增强不做改变,主要目的是简化开发、提高开发效率。它内置通用的 Mapper与 Service,仅仅通过少量配置即可实现单表大部分 简单的CRUD 操作,还有强大的条件构造器,满足各类使用需求。即使涉及到咱们最头疼的表结构调整,只要没调整业务逻辑,也可以不用手动改变代码,只需从新使用generator生成一次即可。且其可以直接丢掉xml编写sql,直接在java代码中通过wrapper编写(个人不太支持非简单CRUD的sql写到代码,因为阅读维护成本高,dao层与service层耦合度高)。它支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库。使用generator可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,可自定义各层代码生成的模版。废话不多说了,开始撸代码。

一、maven依赖


        
        
            com.baomidou
            mybatis-plus-boot-starter
            3.4.1
        
        
            com.baomidou
            mybatis-plus-generator
            3.4.1
        
        
        
            org.freemarker
            freemarker
            2.3.28
        

二、编写generator代码生成器

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
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.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;

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

public class MyBatisPlusGenerator {

    //作者名
    private static final String AUTHOR = "kevin";
    //表table的前缀,不加到生成的类名中
    private static final String PREFIX = "t_";
    //功能模块名称,生成的文件会存放到模块下
    private static final String MODULE_NAME = "test";
    //要生成的表名
    private static final String[] TABLES= {"想生成代码的表名"};
    private static final String JDBC_URL = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8" +
            "&useSSL=false&zeroDateTimeBehavior=convertToNull&";
    private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
    private static final String JDBC_USERNAME = "数据库用户名";
    private static final String JDBC_PASSWORD = "数据库密码";
    private static final String BASE_PACKAGE = "com.liu.test.mybatis.demo";

    public static void main(String[] args) {
        //当前项目路径
        String projectPath = System.getProperty("user.dir");

        // 代码生成器
        AutoGenerator generator = new AutoGenerator();

        //数据库配置
        configDataSource(generator);
        //全局配置
        configGlobal(generator, projectPath);
        //包相关配置
        configPackage(generator);
        //策略配置
        configStrategy(generator);
        //自定义配置
        cofnigCustom(generator, projectPath);
        //模版引擎配置
        configTemplate(generator);

        generator.execute();
    }

    /**
      * 进行数据库相关配置
      * @author kevin
      * @param generator :
      * @date 2021/2/8 13:27
      */
    private static void configDataSource(AutoGenerator generator){
        //数据源配置
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setUrl(JDBC_URL);
        dataSourceConfig.setDbType(DbType.MYSQL);
        // dataSourceConfig.setSchemaName("public");
        dataSourceConfig.setDriverName(JDBC_DRIVER);
        dataSourceConfig.setUsername(JDBC_USERNAME);
        dataSourceConfig.setPassword(JDBC_PASSWORD);
        generator.setDataSource(dataSourceConfig);
    }

    /**
      * 进行全局配置
      * @author kevin
      * @param generator :
      * @param projectPath :
      * @date 2021/2/8 13:28
      */
    private static void configGlobal(AutoGenerator generator, String projectPath) {
        // 全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        //生成文件输出存放路径 = 当前项目路径 + 想存放到项目中的路径
        String fileOutputPatch = projectPath.concat("/src/main/java");
        globalConfig.setOutputDir(fileOutputPatch);

        //设置作者
        globalConfig.setAuthor(AUTHOR);
        //生成完后是否打开输出目录
        globalConfig.setOpen(false);
        //是否覆盖生成过的已有文件
        globalConfig.setFileOverride(true);
        //是否开启activeRecord模式
        globalConfig.setActiveRecord(true);
        // 是否在xml中添加二级缓存配置,默认false
        globalConfig.setEnableCache(false);
        // XML文件返回对象定义ResultMap
        globalConfig.setBaseResultMap(true);
        // XML返回对象字段列表columList
        globalConfig.setBaseColumnList(true);
        //设置主键字段类型
        globalConfig.setIdType(IdType.INPUT);
        //生成的文件名字定义,%s 会自动填充表实体属性
        globalConfig.setMapperName("%sMapper");
        globalConfig.setXmlName("%sMapper");
        globalConfig.setEntityName("%s");
        globalConfig.setServiceName("%sService");
        globalConfig.setServiceImplName("%sServiceImpl");
        globalConfig.setControllerName("%sController");
        //开启 swagger2 模式,实体属性 Swagger2 注解,默认false
        globalConfig.setSwagger2(true);
        generator.setGlobalConfig(globalConfig);
    }

    /**
      * 各个包配置
      * @author kevin
      * @param generator :
      * @date 2021/2/8 13:34
      */
    private static void configPackage(AutoGenerator generator) {
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setModuleName(MODULE_NAME);
        packageConfig.setParent(BASE_PACKAGE);//包路径
        packageConfig.setController("controller");
        packageConfig.setService("service");
        packageConfig.setServiceImpl("service.impl");
        packageConfig.setEntity("entity");
        packageConfig.setMapper("mapper");
        packageConfig.setXml("mapper");
        generator.setPackageInfo(packageConfig);
    }

    /**
      * 策略配置
      * @author kevin
      * @param generator :
      * @date 2021/2/8 13:34
      */
    private static void configStrategy(AutoGenerator generator) {
        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        //全局大写命名
        //strategy.setCapitalMode(true)
        //全局下划线命名
        //strategy.setDbColumnUnderline(true)
        //表的前缀
        strategy.setTablePrefix(PREFIX);
        //表名下划线转为驼峰
        strategy.setNaming(NamingStrategy.underline_to_camel);
        //字段名下划线转为驼峰
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        //生成哪些表
        strategy.setInclude(TABLES);
        strategy.setControllerMappingHyphenStyle(true);
        //设置模版引擎的类型 freemarker使用ftl文件,velocity使用vm文件
        generator.setTemplateEngine(new FreemarkerTemplateEngine());
//        generator.setTemplateEngine(new VelocityTemplateEngine());
        //是否使用lombok
        strategy.setEntityLombokModel(true);
        //设置是否restful控制器
        strategy.setRestControllerStyle(true);
        //设置布尔类型字段是否去掉is前缀
        strategy.setEntityBooleanColumnRemoveIsPrefix(true);
        // 自定义实体父类
        // strategy.setSuperEntityClass("com.baomidou.demo.TestEntity");
        // 自定义实体,公共字段
        // strategy.setSuperEntityColumns(new String[] { "test_id", "age" });
        // 自定义 mapper 父类
        // strategy.setSuperMapperClass("com.baomidou.demo.TestMapper");
        // 自定义 service 父类
        // strategy.setSuperServiceClass("com.baomidou.demo.TestService");
        // 自定义 service 实现类父类
        // strategy.setSuperServiceImplClass("com.baomidou.demo.TestServiceImpl");
        // 自定义 controller 父类
        // strategy.setSuperControllerClass("com.baomidou.demo.TestController");
        // 【实体】是否生成字段常量(默认 false)
        // public static final String ID = "test_id";
        // strategy.setEntityColumnConstant(true);
        // 【实体】是否为构建者模型(默认 false)
        // public User setName(String name) {this.name = name; return this;}
        // strategy.setEntityBuilderModel(true);
        generator.setStrategy(strategy);
    }

    /**
      * 自定义配置
      * @author kevin
      * @param generator :
      * @param projectPath :
      * @date 2021/2/8 13:55
      */
    private static void cofnigCustom(AutoGenerator generator, String projectPath) {
        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };

        // 如果模板引擎是 freemarker
        String templatePath = "/templates/mapper.xml.ftl";
        // 如果模板引擎是 velocity
        // String templatePath = "/templates/mapper.xml.vm";

        // 自定义输出配置
        List focList = new ArrayList<>();
        // 自定义配置会被优先输出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                //自定义输出文件名 , 如果 Entity 设置了前后缀、此处 xml 的名称会跟着发生变化
                return projectPath.concat("/src/main/resources/mapper/").concat(MODULE_NAME).concat("/")
                        .concat(tableInfo.getEntityName()).concat("Mapper").concat(StringPool.DOT_XML);
            }
        });
       /* cfg.setFileCreate(new IFileCreate() {
            @Override
            public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
                // 判断自定义文件夹是否需要创建
                checkDir("调用默认方法创建的目录");
                return false;
            }
        });*/
        cfg.setFileOutConfigList(focList);
        generator.setCfg(cfg);
    }

    /**
      * 模版引擎配置
      * @author kevin
      * @param generator :
      * @date 2021/2/8 13:59
      */
    private static void configTemplate(AutoGenerator generator) {
        //模板引擎配置 默认是VelocityTemplateEngine
        TemplateConfig templateConfig = new TemplateConfig();

        templateConfig.setXml(null);
        generator.setTemplate(templateConfig);
    }
}

其实这样配置后就可右键运行生成代码了,只不过是最原始的代码,模版是官方的默认模版。

mybatis-plus代码自动生成generator配置实现_第1张图片

run与debug都行。运行过后就会自动生成代码结构,如下图:

mybatis-plus代码自动生成generator配置实现_第2张图片

三、编写自己的模版

可自己编写模版,也可以复制默认模版出来进行调整。默认模版在mybatis-generator包下

mybatis-plus代码自动生成generator配置实现_第3张图片

根据自己使用的模版引擎来编写模版,比如本文使用的freemarker,则编写ftl模版文件。模版在项目中存放到resources目录下的templates目录中,如图:

mybatis-plus代码自动生成generator配置实现_第4张图片

1.实体类模版

package ${package.Entity};

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

<#if swagger2>
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;

<#if entityLombokModel>
import lombok.Data;
import lombok.EqualsAndHashCode;
<#if chainModel>
import lombok.experimental.Accessors;


import com.baomidou.mybatisplus.annotation.KeySequence;

/**
 * ${table.comment!}
 * @author ${author}
 * @since ${date}
 */
<#if entityLombokModel>
@Data
    <#if superEntityClass??>
@EqualsAndHashCode(callSuper = true)
    <#else>
@EqualsAndHashCode(callSuper = false)
    
    <#if chainModel>
@Accessors(chain = true)
    

<#if table.convert>
@TableName("${table.name}")

<#if swagger2>
@ApiModel(value="${entity}对象" <#if table.comment??>, description="${table.comment}")

@KeySequence(value="SEQ_${table.name?upper_case}", clazz = Integer.class)
<#if superEntityClass??>
public class ${entity} extends ${superEntityClass}<#if activeRecord><${entity}> {
<#elseif activeRecord>
public class ${entity} extends Model<${entity}> {
<#else>
public class ${entity} implements Serializable {


<#if entitySerialVersionUID>
    private static final long serialVersionUID = 1L;

<#-- ----------  BEGIN 字段循环遍历  ---------->
<#list table.fields as field>
    <#if field.keyFlag>
        <#assign keyPropertyName="${field.propertyName}"/>
    

    /**
    * ${field.comment}
    */
    <#if field.comment!?length gt 0>
        <#if swagger2>
    @ApiModelProperty(value = "${field.comment}")
        
    
    <#if field.keyFlag>
        <#-- 主键 -->
        <#if field.keyIdentityFlag && idType??>
    @TableId(value = "${field.annotationColumnName}", type = IdType.${idType})
        <#elseif field.keyIdentityFlag>
    @TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)
        <#elseif field.convert>
    @TableId("${field.annotationColumnName}")
        
        <#-- 普通字段 -->
    <#elseif field.fill??>
    <#-- -----   存在字段填充设置   ----->
        <#if field.convert>
    @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill})
        <#else>
    @TableField(fill = FieldFill.${field.fill})
        
    <#elseif field.convert>
    @TableField("${field.annotationColumnName}")
    
    <#-- 乐观锁注解 -->
    <#if (versionFieldName!"") == field.name>
    @Version
    
    <#-- 逻辑删除注解 -->
    <#if (logicDeleteFieldName!"") == field.name>
    @TableLogic
    
    private ${field.propertyType} ${field.propertyName};

<#------------  END 字段循环遍历  ---------->

<#if !entityLombokModel>
    <#list table.fields as field>
        <#if field.propertyType == "boolean">
            <#assign getprefix="is"/>
        <#else>
            <#assign getprefix="get"/>
        
    public ${field.propertyType} ${getprefix}${field.capitalName}() {
        return ${field.propertyName};
    }

    <#if chainModel>
    public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
    <#else>
    public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) {
    
        this.${field.propertyName} = ${field.propertyName};
        <#if chainModel>
        return this;
        
    }
    


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

    

<#if activeRecord>
    @Override
    protected Serializable pkVal() {
    <#if keyPropertyName??>
        return this.${keyPropertyName};
    <#else>
        return null;
    
    }


<#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} +
        
    
        "}";
    }

}

2.控制层controller模版

package ${package.Controller};

import ${package.Entity}.${entity};
import ${package.Service}.${table.serviceName};
<#if swagger2>
import io.swagger.annotations.ApiOperation;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
<#if restControllerStyle>
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
<#else>
import org.springframework.stereotype.Controller;

<#if superControllerClassPackage??>
import ${superControllerClassPackage};


/**
 * 

* ${table.comment!} 控制层 *

* * @author ${author} * @since ${date} */ <#if restControllerStyle> @RestController <#else> @Controller @RequestMapping("<#if package.ModuleName?? && package.ModuleName != "">/${package.ModuleName}/<#if controllerMappingHyphenStyle??>${controllerMappingHyphen}<#else>${table.entityPath}") <#if kotlin> class ${table.controllerName}<#if superControllerClass??> : ${superControllerClass}() <#else> <#if superControllerClass??> public class ${table.controllerName} extends ${superControllerClass} { <#else> public class ${table.controllerName} { @Autowired private ${table.serviceName} ${table.serviceName?lower_case}; <#if restControllerStyle> @GetMapping("/list") <#if swagger2> @ApiOperation(value = "${table.comment}列表查询",notes = "list") public List<${entity}> list(){ return ${table.serviceName?lower_case}.list(); } <#if restControllerStyle> @GetMapping("/get") <#if swagger2> @ApiOperation(value = "${table.comment}详情查询",notes = "get") public ${entity} get(String id){ return ${table.serviceName?lower_case}.getById(id); } <#if restControllerStyle> @PostMapping("/save") <#if swagger2> @ApiOperation(value = "${table.comment}保存",notes = "save") public void save(${entity} ${entity?lower_case}){ ${table.serviceName?lower_case}.save(${entity?lower_case}); } <#if restControllerStyle> @DeleteMapping("/delete") <#if swagger2> @ApiOperation(value = "${table.comment}删除",notes = "delete") public void delete(List ids){ ${table.serviceName?lower_case}.removeByIds(ids); } }

 

你可能感兴趣的:(springboot,sql,java,mybatis,generator,spring,boot)