学习Mybatis-Plus代码生成器
- 在后端编写代码时,许多功能的增删改查代码大致相同,仅仅存在实体类的差别,因此每次添加新功能时都要对此部分代码进行复制粘贴修改,效率低且较无意义,MyBatis-Plus 代码生成器, 可以通过编写的模板一键生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。
1,导入依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.7</version>
</dependency>
<!--使用默认velocity模板-->
2,工具类编写
- 项目中新建CodeGenerator工具类,在其中编写代码生成配置,配置完后只需输入数据表名并运行方法,即可生成相应的类(官方文档见:代码生成器(新) | MyBatis-Plus (baomidou.com))
生成器中的配置主要有以下几种
- DataSourceConfig 数据库配置指定需要生成目标数据库,数据库账号密码等
new DataSourceConfig.Builder("jdbc:mysql://127.0.0.1:3306/mybatis-plus","root","123456")
.dbQuery(new MySqlQuery())//数据库查询
.schema("mybatis-plus")//数据库schema
.typeConvert(new MySqlTypeConvert())//数据库类型转换器
.keyWordsHandler(new MySqlKeyWordsHandler())//数据库关键字处理器
.build();
- GlobalConfig 全局配置设置全局策略,例如是否覆盖文档,设置作者名称,注释日期等等
new GlobalConfig.Builder()
.fileOverride()//覆盖已生成文件
.disableOpenDir()//禁止打开输出目录
.outputDir("/opt/baomidou")// 指定输出目录
.author("baomidou")// 设置作者名
.enableKotlin()//开启 kotlin 模式
.enableSwagger()//开启 swagger 模式
.dateType(DateType.TIME_PACK)//时间策略
.commentDate("yyyy-MM-dd")//注释日期
.build();
- PackageConfig 包配置设置各个模块的包名
new PackageConfig.Builder()
.parent("com.baomidou.mybatisplus.samples.generator")//父包名
.moduleName("sys")//父包模块名
.entity("po")// Entity 包名
.service("service")// Service 包名
.serviceImpl("service.impl")// Service Impl 包名
.mapper("mapper")// Mapper 包名
.xml("mapper.xml")//Mapper XML 包名
.controller("controller")// Controller 包名
.other("other")// 自定义文件包名
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, "D://"))//路径配置信息
.build();
- TemplateConfig 模板配置设置各类模板的路径
new TemplateConfig.Builder()
.disable(TemplateType.ENTITY)//禁用模板
.entity("/templates/entity.java")//设置实体模板路径(JAVA)
.service("/templates/service.java")//设置 service 模板路径
.serviceImpl("/templates/serviceImpl.java")//设置 serviceImpl 模板路径
.mapper("/templates/mapper.java")//设置 mapper 模板路径
.mapperXml("/templates/mapper.xml")//设置 mapperXml 模板路径
.controller("/templates/controller.java")//设置 controller 模板路径
.build();
- InjectionConfig 注入配置自定义注入参数和对象等
new InjectionConfig.Builder()
.beforeOutputFile((tableInfo, objectMap) -> {
System.out.println("tableInfo: " + tableInfo.getEntityName() + " objectMap: " + objectMap.size());
})//输出文件之前消费者
.customMap(Collections.singletonMap("test", "baomidou"))
//自定义配置 Map 对象
.customFile(Collections.singletonMap("test.txt", "/templates/test.vm"))//自定义配置模板文件
.build();
- StrategyConfig 策略配置对数据库表进行过滤与修改
new StrategyConfig.Builder()
.enableCapitalMode()//开启大写命名
.enableSkipView()//开启跳过视图
.disableSqlFilter()//禁用 sql 过滤
.likeTable(new LikeTable("USER"))//模糊表匹配(sql 过滤)
.addInclude("t_simple")// 增加表匹配(内存过滤)
.addTablePrefix("t_", "c_")//增加过滤表前缀
.addFieldSuffix("_flag")//增加过滤表后缀
.build();
3,测试使用
- 创建数据表
- 从mybatisplus的generator包中获取模板文件(以controller类为例),将模板文件复制存在resources文件夹中
- 根据已编写的controller类代码对模板类进行修改(将实体类名等内容进行替换)
package ${package.Controller};
import cn.hutool.core.date.DateUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelWriter;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletOutputStream;
import java.net.URLEncoder;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.io.InputStream;
import java.util.List;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.springboot.common.Result;
import org.springframework.web.multipart.MultipartFile;
import com.example.springboot.entity.User;
import com.example.springboot.utils.TokenUtils;
import ${package.Service}.${table.serviceName};
import ${package.Entity}.${entity};
#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("/${table.entityPath}")
#if(${kotlin})
class ${table.controllerName}#if(${superControllerClass}) : ${superControllerClass}()#end
#else
#if(${superControllerClass})
public class ${table.controllerName} extends ${superControllerClass} {
#else
public class ${table.controllerName} {
#end
@Resource
private ${table.serviceName} ${table.entityPath}Service;
private final String now = DateUtil.now();
// 新增或者更新
@PostMapping
public Result save(@RequestBody ${entity} ${table.entityPath}) {
if (${table.entityPath}.getId() == null) {
//${table.entityPath}.setTime(DateUtil.now());
//${table.entityPath}.setUser(TokenUtils.getCurrentUser().getUsername());
}
${table.entityPath}Service.saveOrUpdate(${table.entityPath});
return Result.success();
}
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id) {
${table.entityPath}Service.removeById(id);
return Result.success();
}
@PostMapping("/del/batch")
public Result deleteBatch(@RequestBody List<Integer> ids) {
${table.entityPath}Service.removeByIds(ids);
return Result.success();
}
@GetMapping
public Result findAll() {
return Result.success(${table.entityPath}Service.list());
}
@GetMapping("/{id}")
public Result findOne(@PathVariable Integer id) {
return Result.success(${table.entityPath}Service.getById(id));
}
@GetMapping("/page")
public Map<String , Object> findPage(@RequestParam Integer pageNumber,@RequestParam Integer pageSize,@RequestParam String name){
pageNumber=(pageNumber-1)*pageSize;
List<${entity}> data=${table.entityPath}Service.selectPage(pageNumber,pageSize,name);
Integer total = ${table.entityPath}Service.selectTotal(name); //查询记录总数
Map<String , Object> res=new HashMap<>();
res.put("data",data);
res.put("total",total);
return res;
}
}
#end
- 在代码生成器中填入数据库信息以及表名并运行
package com.example.springboot.utils;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.db.ds.simple.SimpleDataSource;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;
public class CodeGenerator {
// 数据库名称
private static final String DATASOURCE = "web";
// 项目路径
private static final String basePath = "D:\\program\\Test\\control\\springboot\\";
// 数据库需要生成代码的表名
private static final String tableName = "";
// 生成页面的菜单名称
private static final String modelName = "考题管理";
public static void main(String[] args) throws Exception {
// 生成SpringBoot
generate(tableName);
}
private static final String url = "jdbc:mysql://localhost:3306/" + DATASOURCE;
private static final String username = "root";
private static final String password = "";
private static void generate(String tableName) {
FastAutoGenerator.create(url, username, password)
.globalConfig(builder -> {
builder.author("Doc")//设置作者名
.enableSwagger()//开启 swagger 模式
.fileOverride()//覆盖已生成文件
.disableOpenDir()
.outputDir(basePath + "src/main/java/");//指定输出目录
})
.packageConfig(builder -> {
builder.parent("com.example.springboot")//设置父包名
.moduleName(null)//设置父包模块名
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, basePath + "src\\main\\resources\\mapper\\")); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.entityBuilder().enableLombok();
builder.controllerBuilder().enableHyphenStyle()//驼峰命名法
.enableRestStyle();//开启生成@RestController 控制器
builder.addInclude(tableName)//设置需要生成的表名
.addTablePrefix("t_", "sys_");//过滤数据表前缀
})
.execute();
}
private static DataSource getDatasource() {
return new SimpleDataSource(url, username, password);
}
}
- 运行后Controller类下出现了新文件QuestionController,与设置的模板格式一致
package com.example.springboot.controller;
import cn.hutool.core.date.DateUtil;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.example.springboot.common.Result;
import com.example.springboot.service.IQuestionService;
import com.example.springboot.entity.Question;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 前端控制器
* </p>
*
* @author Doc
* @since 2022-09-28
*/
@RestController
@RequestMapping("/question")
public class QuestionController {
@Resource
private IQuestionService questionService;
private final String now = DateUtil.now();
// 新增或者更新
@PostMapping
public Result save(@RequestBody Question question) {
if (question.getId() == null) {
}
questionService.saveData(question);
return Result.success();
}
@DeleteMapping("/{id}")
public Result delete(@PathVariable Integer id) {
questionService.removeById(id);
return Result.success();
}
@PostMapping("/del/batch")
public Result deleteBatch(@RequestBody List<Integer> ids) {
questionService.removeByIds(ids);
return Result.success();
}
@GetMapping
public Result findAll() {
return Result.success(questionService.list());
}
@GetMapping("/{id}")
public Result findOne(@PathVariable Integer id) {
return Result.success(questionService.getById(id));
}
@GetMapping("/page")
public Map<String , Object> findPage(@RequestParam Integer pageNumber, @RequestParam Integer pageSize, @RequestParam String name){
pageNumber=(pageNumber-1)*pageSize;
List<Question> data=questionService.selectPage(pageNumber,pageSize,name);
Integer total = questionService.selectTotal(name); //查询记录总数
Map<String , Object> res=new HashMap<>();
res.put("data",data);
res.put("total",total);
return res;
}
}
- entity实体类Question
package com.example.springboot.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
*
* </p>
*
* @author Doc
* @since 2022-09-28
*/
@Getter
@Setter
@ApiModel(value = "Question对象", description = "")
public class Question implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("题目编号")
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
@ApiModelProperty("题目内容")
private String name;
@ApiModelProperty(" 题目类型,1,选择 2,判断 3,简答")
private String type;
@ApiModelProperty("A选项")
private String a;
@ApiModelProperty("B选项")
private String b;
@ApiModelProperty("C选项")
private String c;
@ApiModelProperty("D选项")
private String d;
@ApiModelProperty("分数")
private String score;
@ApiModelProperty("答案")
private String answer;
@ApiModelProperty("题目解析")
private String analysis;
}
其余类未设置模板所以内容为空,但都生成至对应文件夹下
- 生成器同样可用生成前端vue代码,但与后端配置相差较大