示例程序选择的技术目前各项技术的稳定版本。
相信大家厌烦重复的造轮子过程,编写与数据库表对应的实体类,接着再进行创建各种层次的包(mapper,service,impl),而现在一款神器登场了,它就是:MpBatis-Plus的代码自动生成器。能够节约大部分时间,还能覆盖许多增删改查方法,加快我们的开发速度。
项目源地址放在gitee仓库,想要源代码的读者也可以根据实际情况自取,对你有帮助的话不妨点个赞加个Star⭐吧
代码源地址PracticeCode: 练习
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` bigint(0) NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of user -- ---------------------------- INSERT INTO `user` VALUES (1, 'yeye', '123'); SET FOREIGN_KEY_CHECKS = 1;
创建Spring Boot项目,在pom.xml文件中引入如下依赖:
1.8 UTF-8 UTF-8 2.3.12.RELEASE 5.8.15 3.5.2 2.3 8.0.17 2.0.5 1.2.8 com.alibaba fastjson${fastjson.version} com.alibaba druid-spring-boot-starter${druid.version} mysql mysql-connector-java${mysql.version} runtime cn.hutool hutool-all${hutool.version} com.baomidou mybatis-plus-boot-starter${mybatis-plus.version} com.baomidou mybatis-plus-generator${mybatis-plus.version} org.apache.velocity velocity-engine-core${velocity.version} org.springframework.boot spring-boot-starter-weborg.projectlombok lomboktrue org.springframework.boot spring-boot-starter-testtest org.junit.vintage junit-vintage-engine
MyBatis Plus Generator支持的模板引擎有Velocity、Beetl、FreeMarker,笔者这里选择的是MyBatis Plus Generator默认的模板引擎 — Velocity 2.3,选择不同的模板引擎导入不同的模板即可。
数据源配置和全局代码配置类
String password = "123456"; String username = "root"; String url = "jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai"; DataSourceConfig.Builder dataSourceConfig = new DataSourceConfig.Builder(url, username, password); String finalProjectPath = System.getProperty("user.dir"); //当前项目根目录 // dataSourceConfig数据源 FastAutoGenerator.create(dataSourceConfig) // 全局代码配置类 .globalConfig(builder -> { builder.author("yeye") // 设置作者 .enableSwagger() // 开启 swagger 模式 .fileOverride() // 覆盖已生成文件 .disableOpenDir() //禁止打开输出目录 .outputDir(finalProjectPath + "/src/main/java"); // 指定输出目录 }) // 包配置 .packageConfig(builder -> { /// }) // 策略配置 .strategyConfig(builder -> { /// }) // 自定义模版引擎 .injectionConfig(consumer -> { /// }) // 选择模板引擎 .templateEngine( /// ) // 执行 .execute();
包配置
FastAutoGenerator.create(dataSourceConfig) // 全局代码配置类 .globalConfig(builder -> { // }) // 包配置 .packageConfig(builder -> { builder.parent("com.yeye") // 设置父包名 .entity("model") //设置entity包名 .controller("web.controller")//设置controller包名 .mapper("dao")//设置mapper包名 .service("service")//设置service包名 .serviceImpl("service.impl")//设置impl包名 .other("other")//设置other包名 .pathInfo(Collections.singletonMap(OutputFile.xml, finalProjectPath + "/src/main/resources/mapper")); // 设置mapperXml生成路径 }) // 策略配置 .strategyConfig(builder -> { /// }) // 自定义模版引擎 .injectionConfig(consumer -> { /// }) // 选择模板引擎 .templateEngine( /// ) // 执行 .execute();
在包配置中,笔者配置了父包名,配置了mybatis mapper文件存储路径,配置 Entity 包名、Mapper 包名、Service 包名、Controller 包名的。
策略配置
// dataSourceConfig数据源 FastAutoGenerator.create(dataSourceConfig) // }) // 包配置 .packageConfig(builder -> { /// }) // 策略配置 .strategyConfig(builder -> { if (!CollectionUtils.isEmpty(tableList)) { builder.addInclude(tableList); } builder.addTablePrefix("wms_");// 设置过滤表前缀 builder.entityBuilder() // entity配置 .enableRemoveIsPrefix() .enableTableFieldAnnotation() .enableLombok(); builder.controllerBuilder() // controller配置 .enableRestStyle(); builder.serviceBuilder() // service配置 .formatServiceFileName("%sService") .formatServiceImplFileName("%sServiceImpl") .fileOverride(); builder.mapperBuilder() // mapper配置 .enableBaseResultMap() .enableMapperAnnotation() .formatMapperFileName("%sDao") .formatXmlFileName("%sMapper") .enableBaseColumnList(); if (isOverride) { // 覆写配置 builder.entityBuilder() // entity配置 .fileOverride(); builder.controllerBuilder() // controller配置 .fileOverride(); builder.serviceBuilder() // service配置 .fileOverride(); builder.mapperBuilder() // mapper配置 .fileOverride(); } }) // 自定义模版引擎 .injectionConfig(consumer -> { /// }) // 选择模板引擎 .templateEngine( /// ) // 执行 .execute();
在策略配置中,笔者配置了需要生成的表名、过滤表前缀、开启 Lombok、覆盖已生成文件、下划线转驼峰命、Service 接口文件及实现类的文件名以及是否覆写。
自定义模版引擎
// dataSourceConfig数据源 FastAutoGenerator.create(dataSourceConfig) // 全局代码配置类 .globalConfig(builder -> { // }) // 包配置 .packageConfig(builder -> { /// }) // 策略配置 .strategyConfig(builder -> { /// }) // 自定义模版引擎 .injectionConfig(consumer -> { MapcustomFile = new HashMap<>(); customFile.put("DTO.java", "/templates/entityDTO.java.ftl"); //自定义模版引擎 consumer.customFile(customFile); }) // 选择模板引擎 .templateEngine( /// ) // 执行 .execute();
选择模板引擎
// dataSourceConfig数据源 FastAutoGenerator.create(dataSourceConfig) // 全局代码配置类 // }) // 包配置 .packageConfig(builder -> { /// }) // 策略配置 .strategyConfig(builder -> { /// }) // 自定义模版引擎 .injectionConfig(consumer -> { /// }) // 选择模板引擎 .templateEngine( new VelocityTemplateEngine() ) // 执行 .execute();
完整的代码生成器启动类 CodeGenerator.java 内容如下:
package com.yeye.util; 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.engine.VelocityTemplateEngine; import org.springframework.util.CollectionUtils; import java.util.*; public class CodeGenerator { public static void main(String[] args) { String password = "123456"; String username = "root"; String url = "jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai"; DataSourceConfig.Builder dataSourceConfig = new DataSourceConfig.Builder(url, username, password); //String finalProjectPath = System.getProperty("user.dir"); //当前项目根目录 String finalProjectPath = Objects.requireNonNull(CodeGenerator.class.getClassLoader().getResource("")) .getPath().replace("/target/classes/", ""); ListtableList = new ArrayList<>(); tableList.add("user"); // 生成全部table注释add掉就好 // 写死 creteModel(dataSourceConfig, finalProjectPath, Boolean.TRUE, tableList); // 手动输入(互动式) createSingleModel(dataSourceConfig,finalProjectPath); } private static void creteModel(DataSourceConfig.Builder dataSourceConfig, String finalProjectPath, Boolean isOverride, List tableList) { // dataSourceConfig数据源 FastAutoGenerator.create(dataSourceConfig) // 全局代码配置类 .globalConfig(builder -> { builder.author("yeye") // 设置作者 // .enableSwagger() // 开启 swagger 模式 .fileOverride() // 覆盖已生成文件 .disableOpenDir() //禁止打开输出目录 .outputDir(finalProjectPath + "/src/main/java"); // 指定输出目录 }) // 包配置 .packageConfig(builder -> { builder.parent("com.yeye") // 设置父包名 .entity("model") //设置entity包名 .controller("web.controller") .mapper("dao") .service("service") .serviceImpl("service.impl") .other("other") .pathInfo(Collections.singletonMap(OutputFile.xml, finalProjectPath + "/src/main/resources/mapper")); // 设置mapperXml生成路径 }) // 策略配置 .strategyConfig(builder -> { if (!CollectionUtils.isEmpty(tableList)) { builder.addInclude(tableList); } builder.addTablePrefix("wms_");// 设置过滤表前缀 builder.entityBuilder() // entity配置 .enableRemoveIsPrefix() .enableTableFieldAnnotation() .enableLombok(); builder.controllerBuilder() // controller配置 .enableRestStyle(); builder.serviceBuilder() // service配置 .formatServiceFileName("%sService") .formatServiceImplFileName("%sServiceImpl") .fileOverride(); builder.mapperBuilder() // mapper配置 .enableBaseResultMap() .enableMapperAnnotation() .formatMapperFileName("%sDao") .formatXmlFileName("%sMapper") .enableBaseColumnList(); if (isOverride) { builder.entityBuilder() // entity配置 .fileOverride(); builder.controllerBuilder() // controller配置 .fileOverride(); builder.serviceBuilder() // service配置 .fileOverride(); builder.mapperBuilder() // mapper配置 .fileOverride(); } }) // 自定义模版引擎 .injectionConfig(consumer -> { Map customFile = new HashMap<>(); // DTO // customFile.put("DTO.java", "/templates/entityDTO.java.ftl"); //自定义模版引擎 consumer.customFile(customFile); }) // 选择模板引擎 .templateEngine(new VelocityTemplateEngine()) // 执行 .execute(); } private static void createSingleModel(DataSourceConfig.Builder dataSourceConfig, String finalProjectPath) { FastAutoGenerator.create(dataSourceConfig) // 全局配置 .globalConfig((scanner, builder) -> builder.author(scanner.apply("请输入作者名称?")) .fileOverride() .outputDir(finalProjectPath + "/src/main/java")) // 包配置 .packageConfig(builder -> { builder.parent("com.yeye") // 设置父包名 .entity("model") //设置entity包名 .other("dao") // 设置dto包名 .pathInfo(Collections.singletonMap(OutputFile.xml, finalProjectPath + "/src/main/resources/mapper")); // 设置mapperXml生成路径 }) // 策略配置 .strategyConfig((scanner, builder) -> builder.addInclude(getTables(scanner.apply("请输入表名,多个英文逗号分隔?所有输入 all"))) .controllerBuilder().enableRestStyle() .entityBuilder().enableLombok() .mapperBuilder().enableBaseResultMap().enableBaseColumnList() .build()) .execute(); } // 处理 all 情况 protected static List getTables(String tables) { return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(",")); } }
注意:全局配置中的用于覆盖已生成文件的方法fileOverride在当前版本中已过时,官方文档中目前还未更新,笔者使用 Boolean isOverride控制是否覆写代码。
另外,本文提供了两种生成方式,一种是写死的代码生成,另外一种是交互式生成方式,可自行选择使用。
增删改查及自定义查询示例
@RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @GetMapping("list") public R list() { return R.ok().put("data", userService.list()); } @GetMapping("count") public R count() { return R.ok().put("data", userService.count()); } @GetMapping("info") public R info(@PathVariable("id") Long id) { return R.ok().put("data", userService.getById(id)); } @GetMapping("query") public R query(@PathVariable("name") Long name) { return R.ok().put("data", userService .getOne(new LambdaQueryWrapper().eq(User::getName,name))); } @GetMapping("delete") public R delete(@PathVariable("id") Long id) { return R.ok().put("data", userService.removeById(id)); } @PostMapping("save") public R save(@RequestParam User user) { return R.ok().put("data", userService.save(user)); } @PostMapping("saveBatch") public R saveBatch(@RequestParam User user) { return R.ok().put("data", userService.saveBatch((Collection ) user)); } }
MyBatis Plus Generator 根据默认模板生成的代码是比较简单的,在实际的应用中需要根据自身需要编写自定义模板引擎代码模板,实现自己的定制代码生成,对于笔者来说基本够用,能够满足日常的增删改查操作。
项目源地址放在gitee仓库,想要源代码的读者也可以根据实际情况自取,对你有帮助的话不妨点个赞加个Star⭐吧
代码源地址PracticeCode: 练习
如果这篇【文章】有帮助到你,希望可以给笔者点个赞👍,创作不易,相比官方的陈述,我更喜欢用直接用代码示例解析每一个有用的知识点,感兴趣的也可以关注一下笔者,后续也会更新更多的内容,例如状态机和工作流的实践,都会在后续慢慢更新。