利用mybatisPlus代码生成插件快速搭建springboot应用


新建一个空白的springboot项目,然后将以下代码复制到一个类里,按指示运行main方法,即可生成一个简单的项目

点击展开代码
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
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 java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;
import java.util.stream.Stream;

/**

  • mybatis-plus 逆向工程示例代码
    1. 新建一个maven工程
    1. 导入依赖包 (见底部依赖包注释)
    1. 修改下面的数据库配置
    1. 运行下面的main方法,(如遇报错,请再次执行,首次执行要执行二次)
    1. 以上即创建项目完成
      */

public class GenerateCode {

private String driverName = "com.mysql.jdbc.Driver";
private String url = "jdbc:mysql://localhost:3306/mytest?serverTimezone=UTC&useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF8";
private String username = "root";
private String password = "root";
private String[] tableNames = {"student", "parent","sql_datasource"};   // 需要生成代码的表名
private String parentPackage = "com.demo";   //父类包名(必须有)

private String author = "author";  // 每个类加上作者
private String outputDir = "";   // 请默认空当前项目(否则请以/src/main/java结尾)

private DbType datebaseType = DbType.MYSQL; //数据库类型
private String javaPath = new File("").getCanonicalPath() + "\\src\\main\\java\\";
private String resourcePath = new File("").getCanonicalPath() + "\\src\\main\\resources\\";;  // 资源路径
private String javaPathAndPackage = javaPath + parentPackage.replace(".", "\\") + "\\";

public GenerateCode() throws IOException {
}

public static void main(String[] args) throws Exception {

    GenerateCode generateCode = new GenerateCode();
    // 生成controller 模板文件
    generateCode.createControllerTemplate();
    // 生成controller/service/entity/mapper等
    generateCode.generator();
    // 删除多余的mapper.xml文件
    generateCode.deleteXML();
    // 生成main方法
    generateCode.generatorMain();
    // 生成配置文件
    generateCode.generatorYML();
    // 生成swagger 配置类
    generateCode.generatorSwagger();
    // 生成mybatis-plus 分页配置类
    generateCode.generatorMybatisPlusPage();
    // 生成 ResultVO
    generateCode.generatorResultVO();
}

private void deleteXML() {
    String filePath = javaPathAndPackage + "mapper\\xml";
    File file = new File(filePath);
    Stream.of(Objects.requireNonNull(file.listFiles())).forEach(File::delete);
    file.delete();
}

// 生成controller service serviceImpl entity mapper mapper.xml
public void generator() throws Exception {
    if (outputDir == null || "".equals(outputDir)) {
        outputDir = new File("").getCanonicalPath() + "\\src\\main\\java";
    }
    // 1、全局配置
    GlobalConfig config = new GlobalConfig();
    config.setActiveRecord(false)  // 开启AR模式
            .setAuthor(author)  // 设置作者
            // 生成路径(一般都是生成在此项目的src/main/java下面)
            .setOutputDir(outputDir)
            .setSwagger2(false)    // 开启swagger 注解
            .setFileOverride(false) // 第二次生成会把第一次生成的覆盖掉
            .setIdType(IdType.AUTO) // 主键策略
            .setServiceName("%sService") // 生成的service接口名字首字母是否为I,这样设置就没有I
            .setBaseResultMap(true) // 生成resultMap
            .setBaseColumnList(false); // 在xml中生成基础列
    // 2、数据源配置
    DataSourceConfig dataSourceConfig = new DataSourceConfig();
    dataSourceConfig.setDbType(datebaseType) // 数据库类型
            .setDriverName(driverName)
            .setUrl(url)
            .setUsername(username)
            .setPassword(password);
    // 3、策略配置
    StrategyConfig strategyConfig = new StrategyConfig();
    strategyConfig.setCapitalMode(true) // 开启全局大写命名
            // .setDbColumnUnderline(true) // 表名字段名使用下划线
            .setNaming(NamingStrategy.underline_to_camel) // 下划线到驼峰的命名方式
            .setRestControllerStyle(true)   // rest风格,即controller加 @RestController
            .setTablePrefix("tb_") // 表名前缀
            .setEntityLombokModel(false) // 使用lombok
            .setInclude(tableNames); // 逆向工程使用的表
    // 4、包名策略配置
    PackageConfig packageConfig = new PackageConfig();
    packageConfig.setParent(parentPackage) // 设置包名的parent
                 .setMapper("mapper")
                 .setService("service")
                 .setController("controller")
                 .setEntity("entity")
                 .setXml("mapper.xml"); // 设置xml文件的目录,如果为null,则不生成xml文件

    // 5、自定义配置,调整 xml 生成目录到resource/mapper下面
    InjectionConfig cfg = new InjectionConfig() {
        @Override
        public void initMap() {
            Map<String, Object> map = new HashMap<>();
            map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
            this.setMap(map);
        }
    };
    List<FileOutConfig> focList = new ArrayList<>();
    focList.add(new FileOutConfig("/templates/mapper.xml.vm") {
        @Override
        public String outputFile(TableInfo tableInfo) {
            return outputDir + "\\..\\resources\\mapper\\" + tableInfo.getEntityName() + "Mapper.xml";
        }
    });
    cfg.setFileOutConfigList(focList);

    // 6、模板配置(自定义controller层模板)
    TemplateConfig templateConfig = new TemplateConfig();
    templateConfig.setController("/controller.java.vm"); // controller模板采用自定义模板

    // 7、整合配置
    AutoGenerator autoGenerator = new AutoGenerator();
    autoGenerator.setGlobalConfig(config)
            .setDataSource(dataSourceConfig)
            .setStrategy(strategyConfig)
            .setPackageInfo(packageConfig)
            .setTemplate(templateConfig)
            .setCfg(cfg);
    // 6、执行
    autoGenerator.execute();
}


private void generatorResultVO() throws IOException {
    File dir = new File(javaPathAndPackage, "common");
    dir.mkdirs();
    String resultVo = String.format(CodeString.resultVO,parentPackage);
    creatFile(resultVo, new File(dir,"ResultVO.java"));
}

// 创建Controller的自定义模板
private void createControllerTemplate() throws IOException {
    String resourcePath = new GenerateCode().resourcePath;
    File resourceFile = new File(resourcePath, "controller.java.vm");
    String controllerTemlate = CodeString.controllerTemlate;
    controllerTemlate = String.format(controllerTemlate, parentPackage);
    creatFile(controllerTemlate,resourceFile);
}

// 生成MybatisPlus 分页配置
private void generatorMybatisPlusPage() throws IOException {
    String mybatisPlusPage =CodeString.mybatisPlusPage;
    mybatisPlusPage = String.format(mybatisPlusPage, parentPackage);
    File dir = new File(javaPathAndPackage + "config");
    dir.mkdirs();
    File mainFile = new File(dir, "MybatisPlusConfig.java");
    creatFile(mybatisPlusPage, mainFile);
}

// 生成swagger-ui的配置文件
private void generatorSwagger() throws IOException {
    String swaggerConfig = CodeString.swaggerConfig;
    swaggerConfig = String.format(swaggerConfig, parentPackage, parentPackage);
    File dir = new File(javaPathAndPackage+ "config");
    dir.mkdirs();
    File mainFile = new File(dir, "Swagger2.java");
    creatFile(swaggerConfig,mainFile);
}

// 生成项目启动类
private void generatorMain() throws IOException {
    // 取出 applicationName, 并且首字母大写
    String applicationName = parentPackage.substring(parentPackage.lastIndexOf('.') + 1);;
    applicationName = applicationName.substring(0, 1).toUpperCase() + applicationName.substring(1) + "Application";

    // 将main字符串的字符替换
    String mainStr = CodeString.mainStr;
    mainStr = String.format(mainStr, parentPackage, parentPackage, applicationName, applicationName);

    File mainFile = new File(javaPathAndPackage,applicationName+".java");
    creatFile(mainStr,mainFile);
}

// 生成配置文件application.yml(如果存在,则不生成)
private void generatorYML() throws IOException {
    String applicationYML = CodeString.applicationYML;
    applicationYML = String.format(applicationYML, driverName, url, username, password, parentPackage, parentPackage);
    File resourceFile = new File(resourcePath, "application.yml");
    creatFile(applicationYML, resourceFile);
}

private void creatFile(String contentStr, File createFile) throws IOException {
    if (!createFile.exists()) {
        FileWriter fileWriter = new FileWriter(createFile);
        fileWriter.write(contentStr);
        fileWriter.flush();
        fileWriter.close();
        System.out.println(String.format("====================生成文件%s成功!!!====================",createFile.getName()));
    } else {
        System.out.println(String.format("-------------生成文件%s失败,配置文件已存在!!!-------------",createFile.getName()));
    }
}

class CodeString{
// application.yml 模板
final static String applicationYML = "# 配置端口号\n" +
"server:\n" +
" port: 8888\n" +
"\n" +
"spring:\n" +
" datasource:\n" +
" driver-class-name: %s\n" +
" url: %s\n" +
" password: %s\n" +
" username: %s\n" +
"\n" +
"mybatis:\n" +
" # 指定bean所在包,在mapper.xml中可以使用别名而不使用类的全路径名\n" +
" type-aliases-package: %s.entity\n" +
" configuration:\n" +
" # 驼峰转换\n" +
" map-underscore-to-camel-case: true\n" +
" # 当mybatis的xml文件和mapper接口不在相同包下时,用mapperLocations属性指定xml文件的路径。\n" +
" mapper-locations: mapper/*.xml\n" +
"mapper:\n" +
" wrap-keyword: "{0}" # 自动配置关键字,配置后不需要使用 @Column 指定别名\n\n" +
"logging:\n" +
" level:\n" +
" %s: debug\n" +
"swagger:\n" +
" enable: true";

// 启动类模板
final static String mainStr = "package %s;\n" +
        "import org.mybatis.spring.annotation.MapperScan;\n" +
        "import org.springframework.boot.SpringApplication;\n" +
        "import org.springframework.boot.autoconfigure.SpringBootApplication;\n\n" +
        "@SpringBootApplication\n" +
        "@MapperScan(\"%s.mapper\")\n" +
        "public class %s{\n" +
        "    public static void main(String[] args) {\n" +
        "        SpringApplication.run(%s.class, args);\n" +
        "    }\n}";

// swagger-ui配置模板
final static String swaggerConfig = "package %s.config;\n" +
        "\n" +
        "import org.springframework.beans.factory.annotation.Value;\n" +
        "import org.springframework.context.annotation.Bean;\n" +
        "import org.springframework.context.annotation.Configuration;\n" +
        "import springfox.documentation.builders.ApiInfoBuilder;\n" +
        "import springfox.documentation.builders.PathSelectors;\n" +
        "import springfox.documentation.builders.RequestHandlerSelectors;\n" +
        "import springfox.documentation.service.ApiInfo;\n" +
        "import springfox.documentation.service.Contact;\n" +
        "import springfox.documentation.spi.DocumentationType;\n" +
        "import springfox.documentation.spring.web.plugins.Docket;\n" +
        "import springfox.documentation.swagger2.annotations.EnableSwagger2;\n" +
        "import java.io.IOException;\n" +
        "\n" +
        "@Configuration\n" +
        "@EnableSwagger2\n" +
        "public class Swagger2 {\n" +
        "\n" +
        "    // swagger开关\n" +
        "    @Value(\"${swagger.enable}\")\n" +
        "    private boolean swaggerEnable;\n" +
        "    @Value(\"${server.port}\")\n" +
        "    private Integer port;\n" +
        "\n" +
        "    @Bean\n" +
        "    public Docket createRestApi() {\n" +
        "        if (swaggerEnable) {\n" +
        "            System.out.println(\"\\n 访问地址:\\n http://127.0.0.1:\"+port+\"/swagger-ui.html\\n\");\n" +
        "            try {\n" +
        "                Runtime.getRuntime().exec(\"rundll32 url.dll,FileProtocolHandler \" + \"http://127.0.0.1:\"+port+\"/swagger-ui.html\");\n" +
        "            } catch (IOException e) {\n" +
        "                e.printStackTrace();\n" +
        "            }\n" +
        "        }\n" +
        "        return new Docket(DocumentationType.SWAGGER_2)\n" +
        "                .enable(swaggerEnable)\n" +
        "                .apiInfo(apiInfo())\n" +
        "                .select()\n" +
        "                .apis(RequestHandlerSelectors.basePackage(\"%s\"))    //swagger扫描指定包下面的接口\n" +
        "                .paths(PathSelectors.any())\n" +
        "                .build();\n" +
        "    }\n" +
        "\n" +
        "    private ApiInfo apiInfo() {\n" +
        "        Contact contact = new Contact(\"author\",\"http://127.0.0.1:xxxx(随便或者网站地址)\",\"xxxxxxx@qq.com\");\n" +
        "        return new ApiInfoBuilder()\n" +
        "                .title(\"这个是swagger的标题\")\n" +
        "                .description(\"这个是副标题\")\n" +
        "                .contact(contact)\n" +
        "                .version(\"1.0\")\n" +
        "                .build();\n" +
        "    }\n" +
        "\n" +
        "    /**\n" +
        "     *    分多个组\n" +
        "     *    将上面两个方法复制并改名\n" +
        "     *    分组必须加组名,且不能重复\n" +
        "     */ \n" +
        "}";

// mybatis-plus 分页插件
final static String mybatisPlusPage = "package %s.config;\n" +
        "\n" +
        "import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;\n" +
        "import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;\n" +
        "import org.springframework.context.annotation.Bean;\n" +
        "import org.springframework.context.annotation.Configuration;\n" +
        "\n" +
        "@Configuration\n" +
        "@ConditionalOnClass(value = {PaginationInterceptor.class})\n" +
        "public class MybatisPlusConfig {\n" +
        "   @Bean\n" +
        "   public PaginationInterceptor paginationInterceptor() {\n" +
        "      PaginationInterceptor paginationInterceptor = new PaginationInterceptor();\n" +
        "      return paginationInterceptor;\n" +
        "   }\n" +
        "}\n";

// controller模板
final static String controllerTemlate = "package ${package.Controller};\n" +
        "\n" +
        "import ${package.Entity}.${table.entityName};\n" +
        "import ${package.Service}.${table.serviceName};\n" +
        "import com.demo.common.ResultVO;import com.baomidou.mybatisplus.core.metadata.IPage;\n" +
        "import io.swagger.annotations.Api;" +
        "import org.slf4j.Logger;\n" +
        "import org.slf4j.LoggerFactory;\n" +
        "import io.swagger.annotations.ApiOperation;\n" +
        "import com.baomidou.mybatisplus.extension.plugins.pagination.Page;\n" +
        "import org.springframework.beans.factory.annotation.Autowired;\n" +
        "import org.springframework.transaction.annotation.Transactional;\n" +
        "import org.springframework.web.bind.annotation.*;\n" +
        "import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;\n" +
        "import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;\n" +
        "\n" +
        "#if(${restControllerStyle})\n" +
        "#else\n" +
        "import org.springframework.stereotype.Controller;\n" +
        "#end\n" +
        "#if(${superControllerClassPackage})\n" +
        "import ${superControllerClassPackage};\n" +
        "#end\n" +
        "\n" +
        "/**\n" +
        " * <p>\n" +
        " * $!{table.comment} 前端控制器\n" +
        " * </p>\n" +
        " *\n" +
        " * @author ${author}\n" +
        " * @since ${date}\n" +
        " */\n" +
        "@Api(tags=\"\")\n" +
        "#if(${restControllerStyle})\n" +
        "@RestController\n" +
        "#else\n" +
        "@Controller\n" +
        "#end\n" +
        "@RequestMapping(\"#if(${package.ModuleName})/${package.ModuleName}#end/#if(${controllerMappingHyphenStyle})${controllerMappingHyphen}#else${table.entityPath}#end\")\n" +
        "#if(${kotlin})\n" +
        "class ${table.controllerName}#if(${superControllerClass}) : ${superControllerClass}()#end\n" +
        "\n" +
        "#else\n" +
        "#if(${superControllerClass})\n" +
        "public class ${table.controllerName} extends ${superControllerClass} {\n" +
        "#else\n" +
        "public class ${table.controllerName} {\n" +
        "#end\n" +
        "\n" +
        "    @Autowired\n" +
        "    private ${table.serviceName} ${table.entityPath}Service;\n" +
        "\n" +
        "    private final Logger log = LoggerFactory.getLogger(this.getClass());\n\n" +
        "    @PostMapping(\"selectAll\")\n" +
        "    @ApiOperation(value=\"查找所有\",notes=\"\")\n" +
        "    public ResultVO selectAll() {\n" +
        "        return ResultVO.success(\"查找成功\",${table.entityPath}Service.lambdaQuery().getBaseMapper().selectList(null));\n" +
        "    }\n" +
        "\n" +
        "    @PostMapping(\"selectById\")\n" +
        "    @ApiOperation(value=\"根据id查找\",notes=\"\")\n" +
        "    public ResultVO selectById(@RequestParam(\"id\") Integer id) {\n" +
        "        return ResultVO.success(\"查找成功\",${table.entityPath}Service.getById(id));\n" +
        "    }\n" +
        "\n" +
        "    @PostMapping(\"selectForPage\")\n" +
        "    @ApiOperation(value=\"根据条件分页查找\",notes=\"\")\n" +
        "    public ResultVO selectForPage(@RequestParam(\"pageNum\") Integer pageNum,\n" +
        "                                @RequestParam(\"pageSize\") Integer pageSize,\n" +
        "                                @RequestParam(value = \"condition\",required = false) String condition) {\n" +
        "        IPage<${table.entityName}> page = new Page<>(pageNum,pageSize);\n" +
        "        QueryWrapper<${table.entityName}> queryWrapper = new QueryWrapper<>();\n" +
        "//        queryWrapper.lambda()\n" +
        "//                .ge(Parent::getId, condition);\n" +
        "        return ResultVO.success(\"查找成功\",${table.entityPath}Service.getBaseMapper().selectPage(page, queryWrapper));\n" +
        "    }\n" +
        "\n" +
        "    @PostMapping(\"deleteById\")\n" +
        "    @ApiOperation(value=\"根据id删除\",notes=\"\")\n" +
        "    @Transactional(rollbackFor = {Exception.class})\n" +
        "    public ResultVO deleteById(@RequestParam(\"id\") Integer id) {\n" +
        "        int i = ${table.entityPath}Service.getBaseMapper().deleteById(id);\n" +
        "        if (i == 1) {\n" +
        "             return ResultVO.success(\"删除成功\");\n" +
        "         } else {\n" +
        "             return ResultVO.error(\"删除失败\");\n" +
        "         }\n" +
        "    }\n" +
        "\n" +
        "    @PostMapping(\"add\")\n" +
        "    @ApiOperation(value=\"添加\",notes=\"\")\n" +
        "    @Transactional(rollbackFor = {Exception.class})\n" +
        "    public ResultVO add(@RequestBody ${table.entityName} ${table.entityPath}) {\n" +
        "        int i = ${table.entityPath}Service.getBaseMapper().insert(${table.entityPath});\n" +
        "        if (i == 1) {\n" +
        "            return ResultVO.success(\"添加成功\");\n" +
        "        } else {\n" +
        "            return ResultVO.error(\"添加失败\");\n" +
        "        }     \n" +
        "    }\n" +
        "\n" +
        "    @PostMapping(\"updateById\")\n" +
        "    @ApiOperation(value=\"根据id更新非null字段\",notes=\"\")\n" +
        "    @Transactional(rollbackFor = {Exception.class})\n" +
        "    public ResultVO updateById(@RequestBody ${table.entityName} ${table.entityPath}) {\n" +
        "        UpdateWrapper<${table.entityName}> updateWrapper = new UpdateWrapper<>();\n" +
        "        updateWrapper.eq(\"id\", ${table.entityPath}.getId());\n" +
        "        int i = ${table.entityPath}Service.lambdaQuery().getBaseMapper().update(${table.entityPath}, updateWrapper);\n" +
        "        if (i == 1) {\n" +
        "            return ResultVO.success(\"更新成功\");\n" +
        "        } else {\n" +
        "            return ResultVO.error(\"更新失败\");\n" +
        "        }\n" +
        "    }\n" +
        "\n" +
        "}\n" +
        "\n" +
        "#end";

// ResultVO 返回结果集
final static String resultVO = "package %s.common;\n" +
        "\n" +
        "public class ResultVO {\n" +
        "    private String code;\n" +
        "    private String message;\n" +
        "    private Object data;\n" +
        "\n" +
        "    // 静态成功方法\n" +
        "    public static ResultVO success(String message, Object obj) {\n" +
        "        ResultVO responseResult = new ResultVO();\n" +
        "        responseResult.setCode(\"success\");\n" +
        "        responseResult.setMessage(message);\n" +
        "        responseResult.setData(obj);\n" +
        "        return responseResult;\n" +
        "    }\n" +
        "\n" +
        "    // 静态成功方法\n" +
        "    public static ResultVO success(String message) {\n" +
        "        ResultVO responseResult = new ResultVO();\n" +
        "        responseResult.setCode(\"success\");\n" +
        "        responseResult.setMessage(message);\n" +
        "        return responseResult;\n" +
        "    }\n" +
        "\n" +
        "    // 静态失败方法\n" +
        "    public static ResultVO error(String message) {\n" +
        "        ResultVO responseResult = new ResultVO();\n" +
        "        responseResult.setCode(\"error\");\n" +
        "        responseResult.setMessage(message);\n" +
        "        return responseResult;\n" +
        "    }\n" +
        "\n" +
        "\n" +
        "\n" +
        "    private ResultVO() {\n" +
        "    }\n" +
        "\n" +
        "    public String getCode() {\n" +
        "        return code;\n" +
        "    }\n" +
        "\n" +
        "    public void setCode(String code) {\n" +
        "        this.code = code;\n" +
        "    }\n" +
        "\n" +
        "    public String getMessage() {\n" +
        "        return message;\n" +
        "    }\n" +
        "\n" +
        "    public void setMessage(String message) {\n" +
        "        this.message = message;\n" +
        "    }\n" +
        "\n" +
        "    public Object getData() {\n" +
        "        return data;\n" +
        "    }\n" +
        "\n" +
        "    public void setData(Object data) {\n" +
        "        this.data = data;\n" +
        "    }\n" +
        "}\n";

/* maven 依赖包

org.springframework.boot
spring-boot-starter-parent
2.1.6.RELEASE

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--druid连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.21</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>

        <!--配置mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.2</version>
        </dependency>

        <!--mybatisplus代码生成器-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.7.0</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.7.0</version>
        </dependency>
    </dependencies>

*/