Skip to content

🗃️ MyBatis-Plus 集成指南

📖 功能介绍

TIP

MyBatis-Plus 是 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,简化开发、提高效率。 详细文档请参考MyBatis-Plus官方文档

⚙️ 依赖配置

1. 核心依赖

xml
<!-- 数据库连接池 -->
<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
</dependency>

<!-- MyBatis-Plus -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-spring-boot3-starter</artifactId>
    <version>3.5.7</version>
</dependency>

<!-- MySQL驱动 -->
<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
</dependency>

2. 代码生成依赖

xml
<!-- 模板引擎 -->
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
</dependency>

<!-- 代码生成器 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.5.7</version>
    <scope>test</scope>
</dependency>

🛠️ 代码生成器

1. 生成器配置

java
/**
 * mybatis自动生成
 * @author: fallsea
 * @version 1.0
 */
public class Generator {

	/**
	 * 数据库地址
	 */
	private static final String URL = "jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useSSL=false&useUnicode=true&characterEncoding=utf-8";
	
	/**
	 * 用户名
	 */
	private static final String  USERNAME = "root";
	
	/**
	 * 密码
	 */
	private static final String PASSWORD = "123456";

	/**
	 * 作者
	 */
	private static final String AUTHOR = "fallsea";
	
	/**
	 * 父包名
	 */
	private static final String PARENT_PACKAGE = "com.wueasy.demo";
	
	/**
	 * mybatis xml路径
	 */
	private static final String MAPPER_XML_PATH = "/mybatis/demo";
	
	/**
	 * 表名称
	 */
	private static final String TABLE_NAME = "test";
	
	
    public static void main(String[] args) throws Exception {
    	
    	
    	String relativelyPath=System.getProperty("user.dir"); 
    	
    	FastAutoGenerator.create(URL, USERNAME, PASSWORD)
        .globalConfig(builder -> {
            builder.author(AUTHOR) // 设置作者
                .fileOverride() // 覆盖已生成文件
                .disableOpenDir()
                .dateType(DateType.ONLY_DATE)
                .outputDir(FilenameUtils.normalize(relativelyPath+"/src/main/java")); // 指定输出目录
        })
        .packageConfig(builder -> {
            builder.parent(PARENT_PACKAGE) // 设置父包名
                .moduleName("") // 设置父包模块名
                .entity("entity")
                .mapper("mapper")
                .pathInfo(Collections.singletonMap(OutputFile.xml,FilenameUtils.normalize(relativelyPath+"/src/main/resources"+MAPPER_XML_PATH))); // 设置mapperXml生成路径
        })
        .strategyConfig(builder -> {
            builder.addInclude(TABLE_NAME) // 设置需要生成的表名
         // 过滤表前缀,生成的类名会去掉这个前缀
			.addTablePrefix("t_")
			// 第一阶段
			// 是否生成 entity:是
			.entityBuilder()
			// 开启lombok
			.enableLombok()
			.disableSerialVersionUID()
			// 开启实体时字段注解。 会在生成的实体类的字段上,添加注解: @TableField("nickname")
			.enableTableFieldAnnotation()
			// 设置主键Id生成策略,设置为默认的雪花算法(ASSIGN_ID)
			.idType(IdType.AUTO)
			// 会在实体类的该字段上追加注解[@TableField(value = "create_time", fill = FieldFill.INSERT)]
//			.addTableFills(new Column("create_time", FieldFill.INSERT))
			// 会在实体类的该字段上追加注解[@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)]
//			.addTableFills(new Column("update_time", FieldFill.INSERT_UPDATE))
			// 第二阶段
			.mapperBuilder()
			.mapperAnnotation(org.apache.ibatis.annotations.Mapper.class)
			// 启用 BaseResultMap 生成。 会在 mapper.xml文件生成[通用查询映射结果]配置。
			.enableBaseResultMap()
			// 启用 BaseColumnList。 会在mapper.xml文件生成[通用查询结果列 ]配置
			.enableBaseColumnList()
			.serviceBuilder()
			.disable()
			.controllerBuilder()
			.disable()
			.build()
			;
        })
        .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
        .execute();
    }
    
    
}

📝 基础配置

1. 分页插件配置

java
/**
 * mybatis plus 配置
 * @author: fallsea
 * @version 1.0
 */
@Configuration
public class MybatisPlusConfig {

	@Bean
	public MybatisPlusInterceptor mybatisPlusInterceptor() {
		return new MybatisPlusInterceptor();
	}

}

2. Mapper扫描配置

java
@SpringBootApplication
@MapperScan("com.wueasy.demo.mapper")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

3. 数据源配置

yaml
spring: 
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    url: jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&useSSL=false&useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 123456
    hikari:
      minimum-idle: 5 #池中最小空闲连接数量,默认值10
      idle-timeout: 30000 #一个连接idle状态的最大时长(毫秒),超时则被释放(retired),缺省:10s
      maximum-pool-size: 15 # 池中最大连接数(包括空闲和正在使用的连接)
      auto-commit: true # 是否自动提交池中返回的连接
      pool-name: HikariCP # 连接池的名字
      max-lifetime: 120000 # 连接池中连接的最大生命周期
      connection-timeout: 30000 # 连接超时时间。默认值为30s
      connection-test-query: SELECT 1 # 测试连接
      
mybatis-plus:
  mapper-locations: classpath*:mybatis/**/*.xml

💡 开发示例

1. Controller层实现

java
/**
 * test
 * @author: fallsea
 * @version 1.0
 */
@RestController
@RequestMapping("/test")
public class TestController
{
	@Autowired
	private TestMapper testMapper;
	
	/**
	 * 新增
	 * @author: fallsea
	 * @param dto
	 * @return
	 */
	@RequestMapping(value = "/add", method = { RequestMethod.POST }, produces = MediaType.APPLICATION_JSON_VALUE)
	public Result<Void> add(@RequestBody @Valid TestAddDto dto) {
		Test test = new Test();
		BeanUtils.copyProperties(dto, test);
		test.setCreatedDate(new Date());
		testMapper.insert(test);
		return new Result<Void>();
	}
	
	/**
	 * 修改
	 * @author: fallsea
	 * @param dto
	 * @return
	 */
	@RequestMapping(value = "/edit", method = { RequestMethod.POST }, produces = MediaType.APPLICATION_JSON_VALUE)
	public Result<Void> edit(@RequestBody @Valid TestEditDto dto) {
		Test test = new Test();
		BeanUtils.copyProperties(dto, test);
		test.setCreatedDate(new Date());
		testMapper.updateById(test);
		return new Result<Void>();
	}
	
	/**
	 * 查询单个
	 * @author: fallsea
	 * @param dto
	 * @return
	 */
	@RequestMapping(value = "/get", method = { RequestMethod.POST }, produces = MediaType.APPLICATION_JSON_VALUE)
	public Result<TestVo> get(@RequestBody @Valid TestIdDto dto) {
		Test test = testMapper.selectById(dto.getId());
		if(null==test) {
			throw new InvokeException(-1, "记录不存在");
		}
		TestVo vo = new TestVo();
		BeanUtils.copyProperties(test, vo);
		return new Result<TestVo>().setData(vo);
	}

	/**
	 * 删除
	 * @author: fallsea
	 * @param dto
	 * @return
	 */
	@RequestMapping(value = "/delete", method = { RequestMethod.POST }, produces = MediaType.APPLICATION_JSON_VALUE)
	public Result<Void> delete(@RequestBody @Valid TestIdDto dto) {
		Test test = testMapper.selectById(dto.getId());
		if(null==test) {
			throw new InvokeException(-1, "记录不存在");
		}
		testMapper.deleteById(dto.getId());
		return new Result<Void>();
	}

	/**
	 * 分页
	 * @author: fallsea
	 * @param dto
	 * @return
	 */
	@RequestMapping(value = "/queryPage", method = { RequestMethod.POST }, produces = MediaType.APPLICATION_JSON_VALUE)
	public Result<Page<TestVo>> queryPage(@RequestBody @Valid TestQueryPageDto dto) {
		IPage<Test> page = testMapper.selectPageList(PageDTO.of(dto.getPageNum(), dto.getPageSize()),dto.getName());
		//旧的转新的page
		Page<TestVo> newPage = new Page<>();
		newPage.setPageNum(page.getCurrent());
		newPage.setPages(page.getPages());
		newPage.setPageSize((int) page.getSize());
		newPage.setTotal(page.getTotal());
		if(null!=page.getRecords() && !page.getRecords().isEmpty()) {
			List<TestVo> newList = new ArrayList<>();
			for (Test test : page.getRecords()) {
				TestVo vo = new TestVo();
				BeanUtils.copyProperties(test, vo);
				newList.add(vo);
			}
			newPage.setList(newList);
		}
		return new Result<Page<TestVo>>().setData(newPage);
	}
	
	
}

🔍 常见问题

  1. Mapper未注册

    • 检查@MapperScan配置
    • 验证包路径正确性
    • 确认Mapper类存在
  2. 分页失效

    • 检查分页插件配置
    • 验证分页参数正确
    • 确认使用正确的分页方法