基于mybatis-plus的代码自动生成工具(自定义模板)

  1. MyBatis-Plus是一个MyBatis框架的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。对于mybatis-plus不了解的同学,可以去MyBatis-Plus官网看看。真的能让开发效率显著提高,本文就来和大家一起分享下它的代码自动生成工具。

  2. 其实在MyBatis-Plus的官网就为我们提供了代码生成器的使用教程,它可以为完成最基本的代码生成,但是想要实现自己的效果,还需要我们自己去设置生成模板,话不多说,直接开干。

  3. 效果展示
    基于mybatis-plus的代码自动生成工具(自定义模板)_第1张图片

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;

/**
 * 

* 用户信息表 *

* * @author * @since 2019-11-27 */
@Data @EqualsAndHashCode(callSuper = false) @Builder @AllArgsConstructor @NoArgsConstructor @ApiModel(value="User对象", description="用户信息表") public class User implements Serializable { private static final long serialVersionUID = 1L; public static final String ID = "id"; public static final String USERNAME = "username"; public static final String PASSWORD = "password"; /** * 主键 */ @ApiModelProperty(value = "主键") @TableId(value = "id", type = IdType.AUTO) private Integer id; /** * 用户名 */ @ApiModelProperty(value = "用户名") @TableField("username") private String username; /** * 密码 */ @ApiModelProperty(value = "密码") @TableField("password") private String password; }
  1. 添加项目依赖(添加swagger和lomback是因为在生成实体类中需要用到)

    
    
        com.baomidou
        mybatis-plus-generator
        3.2.0
    
    
    
        org.freemarker
        freemarker
        2.3.28
    
    
    
        org.projectlombok
        lombok
        true
    
     
     
        mysql
        mysql-connector-java
        runtime
    
    
    
        io.springfox
        springfox-swagger2
        2.9.2
    
    
        io.springfox
        springfox-swagger-ui
        2.9.2
    
    
    
  2. 编写代码生成器代码

package cn.mybatis.plus.test;

import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
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 java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

/**
 * @Auther: PWJ
 * @Date: 2019/7/2 14:17
 * @Description:
 */
// 演示例子,执行 main 方法控制台输入模块表名回车自动生成对应项目目录中
public class CodeGenerator {

    /**
     * 

* 读取控制台内容 *

*/
public static String scanner(String tip) { Scanner scanner = new Scanner(System.in); StringBuilder help = new StringBuilder(); help.append("请输入" + tip + ":"); System.out.println(help.toString()); if (scanner.hasNext()) { String ipt = scanner.next(); if (StringUtils.isNotEmpty(ipt)) { return ipt; } } throw new MybatisPlusException("请输入正确的" + tip + "!"); } public static void main(String[] args) { // 代码生成器 AutoGenerator mpg = new AutoGenerator(); // 全局配置 GlobalConfig gc = new GlobalConfig(); String projectPath = System.getProperty("user.dir"); //用于多个模块下生成到精确的目录下 // String projectPath = "E:/IDEA WorkSpace/demo_springcoud2/demo_security_oauth2"; //生成文件的输出目录 gc.setOutputDir(projectPath + "/src/main/java"); //开发人员 gc.setAuthor("pwj"); //是否打开输出目录 gc.setOpen(false); // 实体属性 Swagger2 注解 gc.setSwagger2(true); mpg.setGlobalConfig(gc); // 数据源配置 DataSourceConfig dsc = new DataSourceConfig(); dsc.setUrl("jdbc:mysql://127.0.0.1:3306/smart_vault?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone = GMT"); //设置驱动 dsc.setDriverName("com.mysql.cj.jdbc.Driver"); //用户名 dsc.setUsername("root"); //密码 dsc.setPassword("root"); //设置数据源 mpg.setDataSource(dsc); // 包配置 PackageConfig pc = new PackageConfig(); //添加这个后 会以一个实体为一个模块 比如user实体会生成user模块 每个模块下都会生成三层 // pc.setModuleName(scanner("模块名")); pc.setParent("cn.mybatis.plus.test"); pc.setEntity("domain"); mpg.setPackageInfo(pc); // 自定义配置 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<FileOutConfig> focList = new ArrayList<>(); // 自定义配置会被优先输出 focList.add(new FileOutConfig(templatePath) { @Override public String outputFile(TableInfo tableInfo) { // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!! // return projectPath + "/src/main/resources/mappers/" + pc.getModuleName() return projectPath + "/src/main/resources/mapper/" + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; } }); cfg.setFileOutConfigList(focList); mpg.setCfg(cfg); // 配置模板 TemplateConfig templateConfig = new TemplateConfig(); // 配置自定义输出模板(如果不配置这些,则会按照官方的配置进行生成) //指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别 templateConfig.setEntity("templates/entity2.java"); templateConfig.setMapper("templates/mapper2.java"); templateConfig.setController("templates/controller2.java"); templateConfig.setServiceImpl("templates/serviceImpl2.java"); //设置为空则代表不需要生成 templateConfig.setXml(null); mpg.setTemplate(templateConfig); // 策略配置 StrategyConfig strategy = new StrategyConfig(); //数据库表映射到实体的命名策略 strategy.setNaming(NamingStrategy.underline_to_camel); //数据库表字段映射到实体的命名策略, 未指定按照 naming 执行 strategy.setColumnNaming(NamingStrategy.underline_to_camel); //为实体类添加公共基类 // strategy.setSuperEntityClass("com.wt.demo01.BaseEntity"); //实体类采用lombok的形式 strategy.setEntityLombokModel(true); //设置controller为restcontroller strategy.setRestControllerStyle(true); //【实体】是否生成字段常量(默认 false) strategy.setEntityColumnConstant(true); //是否生成实体时,生成字段配置 即在字段属性上加上@TableField("")注解 strategy.setEntityTableFieldAnnotationEnable(true); // controller的公共父类 // strategy.setSuperControllerClass("com.wt.demo01.BaseController"); // 写于父类中的公共字段 // strategy.setSuperEntityColumns("id"); strategy.setInclude(scanner("表名,多个英文逗号分割").split(",")); //驼峰转连字符 strategy.setControllerMappingHyphenStyle(true); //表前缀 strategy.setTablePrefix(pc.getModuleName() + "_"); mpg.setStrategy(strategy); //设置模板引擎 mpg.setTemplateEngine(new FreemarkerTemplateEngine()); mpg.execute(); } }

更多的关于自动生成的配置大家可以在官网的代码生成器配置上进行了解。

  1. 自定义模板:controller2.java.ftl
package ${package.Controller};


import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;
import ${package.Service}.${table.serviceName};
<#if restControllerStyle>
import org.springframework.web.bind.annotation.RestController;
<#else>
import org.springframework.stereotype.Controller;
</#if>
<#if superControllerClassPackage??>
import ${superControllerClassPackage};
</#if>

/**
 * 

* ${table.comment!} 前端控制器 *

* * @author ${author} * @since ${date} */
<#if restControllerStyle> @RestController <#else> @Controller </#if> @RequestMapping("<#if package.ModuleName??>/${package.ModuleName}/<#if controllerMappingHyphenStyle??>${controllerMappingHyphen}<#else>${table.entityPath}") <#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} service; } </#if>
  1. 自定义模板:serviceImpl2.java.ftl
package ${package.ServiceImpl};

import ${package.Entity}.${entity};
import ${package.Mapper}.${table.mapperName};
import ${package.Service}.${table.serviceName};
import ${superServiceImplClassPackage};
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * 

* ${table.comment!} 服务实现类 *

* * @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 ${table.mapperName} mapper; } </#if>
  1. 自定义模板:entity2.java.ftl
package ${package.Entity};

<#list table.importPackages as pkg>
import ${pkg};
</#list>
<#if swagger2>
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
</#if>
<#if entityLombokModel>
import lombok.*;
</#if>

/**
 * 

* ${table.comment!} *

* * @author ${author} * @since ${date} */
<#if entityLombokModel> @Data <#if superEntityClass??> @EqualsAndHashCode(callSuper = true) <#else> @EqualsAndHashCode(callSuper = false) </#if> @Builder @AllArgsConstructor @NoArgsConstructor </#if> <#if table.convert> @TableName("${table.name}") </#if> <#if swagger2> @ApiModel(value="${entity}对象", description="${table.comment!}") </#if> <#if superEntityClass??> public class ${entity} extends ${superEntityClass}<#if activeRecord><${entity}></#if> { <#elseif activeRecord> public class ${entity} extends Model<${entity}> { <#else> public class ${entity} implements Serializable { </#if> <#if entitySerialVersionUID> private static final long serialVersionUID = 1L; </#if> <#if entityColumnConstant> <#list table.fields as field> public static final String ${field.name?upper_case} = "${field.name}"; </#list> </#if> <#-- ---------- BEGIN 字段循环遍历 ----------> <#list table.fields as field> <#if field.keyFlag> <#assign keyPropertyName="${field.propertyName}"/> </#if> <#if field.comment!?length gt 0> <#if swagger2> /** * ${field.comment} */ @ApiModelProperty(value = "${field.comment}") <#else> /** * ${field.comment} */ </#if> </#if> <#if field.keyFlag> <#-- 主键 --> <#if field.keyIdentityFlag> @TableId(value = "${field.name}", type = IdType.AUTO) <#elseif idType??> @TableId(value = "${field.name}", type = IdType.${idType}) <#elseif field.convert> @TableId("${field.name}") </#if> <#-- 普通字段 --> <#elseif field.fill??> <#-- ----- 存在字段填充设置 -----> <#if field.convert> @TableField(value = "${field.name}", fill = FieldFill.${field.fill}) <#else> @TableField(fill = FieldFill.${field.fill}) </#if> <#elseif field.convert> @TableField("${field.name}") </#if> <#-- 乐观锁注解 --> <#if (versionFieldName!"") == field.name> @Version </#if> <#-- 逻辑删除注解 --> <#if (logicDeleteFieldName!"") == field.name> @TableLogic </#if> private ${field.propertyType} ${field.propertyName}; </#list> <#------------ END 字段循环遍历 ----------> <#if !entityLombokModel> <#list table.fields as field> <#if field.propertyType == "boolean"> <#assign getprefix="is"/> <#else> <#assign getprefix="get"/> </#if> public ${field.propertyType} ${getprefix}${field.capitalName}() { return ${field.propertyName}; } <#if entityBuilderModel> public ${entity} set${field.capitalName}(${field.propertyType} ${field.propertyName}) { <#else> public void set${field.capitalName}(${field.propertyType} ${field.propertyName}) { </#if> this.${field.propertyName} = ${field.propertyName}; <#if entityBuilderModel> return this; </#if> } </#list> </#if> <#if activeRecord> @Override protected Serializable pkVal() { <#if keyPropertyName??> return this.${keyPropertyName}; <#else> return null; </#if> } </#if> <#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} + </#if> </#list> "}"; } </#if> }
  1. 自定义模板:mapper2.java.ftl
package ${package.Mapper};

import ${package.Entity}.${entity};
import ${superMapperClassPackage};
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

/**
 * 

* ${table.comment!} Mapper 接口 *

* * @author ${author} * @since ${date} */
@Mapper @Repository <#if kotlin> interface ${table.mapperName} : ${superMapperClass}<${entity}> <#else> public interface ${table.mapperName} extends ${superMapperClass}<${entity}> { } </#if>

总结

所有的模板都可以根据个人的需求进行相应的更改,不会的都可以参照官方原来的模板进行修改,找不到的可以在com.baomidou.mybatisplus.generator包下的templates下进行寻找,附上截图。找到后将其复制到自己项目的templates目录下,在进行项目自定义修改即可(记得修改配置)。
基于mybatis-plus的代码自动生成工具(自定义模板)_第2张图片

你可能感兴趣的:(Mybatis)