什么是 MyBatis-Plus?
MyBatis-Plus(简称 MP)是 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,旨在简化开发、提高效率。
简单来说,MyBatis-Plus 可以帮你省去大量重复的 CRUD 代码,让你专注于业务逻辑开发。
为什么选择 MyBatis-Plus?
- 无侵入:只做增强不做改变,完全兼容 MyBatis
- 强大的 CRUD 操作:内置通用 Mapper,无需编写 SQL 即可完成增删改查
- 条件构造器:灵活构建查询条件,告别字符串拼接 SQL 的痛苦
- 分页插件:一键实现分页功能,无需复杂配置
- 代码生成器:自动生成 Entity、Mapper、Service、Controller 代码
- 多种主键策略:支持自动生成主键,包括雪花算法、UUID 等
环境准备
技术依赖
- JDK 8+
- Maven 3.6+
- Spring Boot 2.7.x(本文以 Spring Boot 整合为例)
- MySQL 8.0(或其他关系型数据库)
快速入门
1. 创建数据库和表
-- 创建数据库
CREATE DATABASE mp_demo DEFAULT CHARACTER SET utf8mb4;
-- 使用数据库
USE mp_demo;
-- 创建用户表
CREATE TABLE user (
id BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
create_time DATETIME NULL DEFAULT NULL COMMENT '创建时间',
update_time DATETIME NULL DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
-- 插入测试数据
INSERT INTO user (name, age, email) VALUES
('张三', 18, 'zhangsan@example.com'),
('李四', 20, 'lisi@example.com'),
('王五', 22, 'wangwu@example.com');2. 初始化 Spring Boot 项目并添加依赖
<!-- Spring Boot 父依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.15</version>
<relativePath/>
</parent>
<dependencies>
<!-- Spring Boot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis-Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Lombok (简化实体类) -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- 测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>3. 配置数据库连接
application.yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mp_demo?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password: 123456 # 替换为你的数据库密码
# MyBatis-Plus 配置
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印SQL日志
global-config:
db-config:
logic-delete-field: deleted # 全局逻辑删除字段名
logic-delete-value: 1 # 逻辑已删除值
logic-not-delete-value: 0 # 逻辑未删除值4. 创建实体类(Entity)
package com.example.mpdemo.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import java.time.LocalDateTime;
import lombok.Data;
@Data // Lombok 注解,自动生成getter、setter等方法
@TableName("user") // 对应数据库表名
public class User {
@TableId(type = IdType.AUTO) // 主键自增
private Long id;
private String name;
private Integer age;
private String email;
@TableField(fill = FieldFill.INSERT) // 插入时自动填充
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE) // 插入和更新时自动填充
private LocalDateTime updateTime;
}5. 创建 Mapper 接口
package com.example.mpdemo.mapper;
import com.example.mpdemo.entity.User;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
// 继承 BaseMapper 即可获得基本的 CRUD 方法
public interface UserMapper extends BaseMapper<User> {
}6. 在启动类添加注解
package com.example.mpdemo;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.example.mpdemo.mapper") // 扫描 Mapper 接口
public class MpDemoApplication {
public static void main(String[] args) {
SpringApplication.run(MpDemoApplication.class, args);
}
}7. 创建自动填充处理器(可选)
用于自动填充 createTime 和 updateTime 字段:
package com.example.mpdemo.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
// 插入时的填充策略
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
// 更新时的填充策略
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
}核心功能实战
1. 基本 CRUD 操作
创建 Service 层(可选,但推荐):
package com.example.mpdemo.service;
import com.example.mpdemo.entity.User;
import com.baomidou.mybatisplus.extension.service.IService;
public interface UserService extends IService<User> {
}实现 Service:
package com.example.mpdemo.service.impl;
import com.example.mpdemo.entity.User;
import com.example.mpdemo.mapper.UserMapper;
import com.example.mpdemo.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}测试 CRUD 操作(使用 JUnit 测试):
package com.example.mpdemo;
import com.example.mpdemo.entity.User;
import com.example.mpdemo.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest
public class UserServiceTest {
@Autowired
private UserService userService;
// 测试查询所有
@Test
public void testSelectAll() {
List<User> users = userService.list();
users.forEach(System.out::println);
}
// 测试新增
@Test
public void testInsert() {
User user = new User();
user.setName("赵六");
user.setAge(25);
user.setEmail("zhaoliu@example.com");
boolean save = userService.save(user);
System.out.println("保存结果:" + save);
}
// 测试更新
@Test
public void testUpdate() {
User user = new User();
user.setId(1L);
user.setAge(19); // 修改年龄
boolean update = userService.updateById(user);
System.out.println("更新结果:" + update);
}
// 测试删除
@Test
public void testDelete() {
boolean remove = userService.removeById(4L);
System.out.println("删除结果:" + remove);
}
}2. 条件构造器(QueryWrapper)
QueryWrapper 是 MyBatis-Plus 的核心功能之一,用于构建复杂查询条件:
// 测试条件查询
@Test
public void testQueryWrapper() {
// 1. 查询年龄大于20且邮箱不为空的用户
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 20) // 大于
.isNotNull("email");
List<User> users = userService.list(queryWrapper);
System.out.println("年龄大于20且邮箱不为空的用户:" + users);
// 2. 查询姓名包含"张"且年龄在15-25之间的用户
QueryWrapper<User> queryWrapper2 = new QueryWrapper<>();
queryWrapper2.like("name", "张") // 模糊查询
.between("age", 15, 25);
List<User> users2 = userService.list(queryWrapper2);
System.out.println("姓名包含张且年龄在15-25之间的用户:" + users2);
// 3. 按年龄降序排序,只查询id和name字段
QueryWrapper<User> queryWrapper3 = new QueryWrapper<>();
queryWrapper3.orderByDesc("age") // 降序排序
.select("id", "name"); // 只查询指定字段
List<User> users3 = userService.list(queryWrapper3);
System.out.println("按年龄降序排序的用户:" + users3);
}3. 分页查询
- 配置分页插件:
package com.example.mpdemo.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
// 分页插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}- 测试分页查询:
// 测试分页查询
@Test
public void testPage() {
// 第1页,每页2条数据
Page<User> page = new Page<>(1, 2);
// 可以添加查询条件
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.ge("age", 18); // 年龄大于等于18
// 执行分页查询
Page<User> userPage = userService.page(page, queryWrapper);
// 分页结果
System.out.println("总记录数:" + userPage.getTotal());
System.out.println("总页数:" + userPage.getPages());
System.out.println("当前页数据:" + userPage.getRecords());
}4. 逻辑删除
逻辑删除并不是真正删除数据,而是通过一个字段标记数据是否被删除(如 deleted 字段)。
- 添加逻辑删除字段到数据库表:
ALTER TABLE user ADD COLUMN deleted INT DEFAULT 0 COMMENT '逻辑删除字段(0-未删除,1-已删除)';- 在实体类中添加对应字段:
@TableLogic // 标记为逻辑删除字段
private Integer deleted;- 测试逻辑删除:
// 测试逻辑删除
@Test
public void testLogicDelete() {
boolean remove = userService.removeById(1L);
System.out.println("删除结果:" + remove);
}执行后,数据并不会被真正删除,而是将 deleted 字段设为 1,查询时会自动过滤已删除的数据。
代码生成器(AutoGenerator)
MyBatis-Plus 提供了代码生成器,可以自动生成 Entity、Mapper、Service、Controller 等代码,极大提高开发效率。
使用步骤:
- 添加代码生成器依赖:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.3.1</version>
</dependency>
<!-- 模板引擎 (默认使用Velocity) -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>- 编写代码生成器类:
package com.example.mpdemo.generator;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import java.util.Collections;
public class CodeGenerator {
public static void main(String[] args) {
FastAutoGenerator.create("jdbc:mysql://localhost:3306/mp_demo?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai", "root", "123456")
.globalConfig(builder -> {
builder.author("yourname") // 设置作者
.enableSwagger() // 开启 Swagger 模式
.fileOverride() // 覆盖已生成文件
.outputDir(System.getProperty("user.dir") + "/src/main/java"); // 指定输出目录
})
.packageConfig(builder -> {
builder.parent("com.example.mpdemo") // 设置父包名
.moduleName("") // 设置父包模块名
.pathInfo(Collections.singletonMap(OutputFile.xml, System.getProperty("user.dir") + "/src/main/resources/mapper")); // 设置mapperXml生成路径
})
.strategyConfig(builder -> {
builder.addInclude("user") // 设置需要生成的表名
.addTablePrefix("t_", "c_"); // 设置过滤表前缀
})
.templateEngine(new VelocityTemplateEngine()) // 使用Velocity引擎模板,默认就是Velocity
.execute();
}
}运行 main 方法,即可自动生成代码。
常见问题解决
- 依赖冲突:MyBatis-Plus 已经包含 MyBatis 依赖,无需重复引入 MyBatis
- 分页插件不生效:检查是否正确配置了分页插件,是否在 Spring 容器中被扫描到
- 逻辑删除不生效:确保实体类字段添加了
@TableLogic注解,数据库字段默认值为 0 - 字段填充不生效:检查填充处理器是否添加了
@Component注解,是否正确实现了MetaObjectHandler接口 - 条件构造器报错:注意字段名是否与数据库表字段一致,避免使用关键字作为字段名
总结
MyBatis-Plus 是一款非常优秀的 MyBatis 增强工具,通过本文的学习,你已经掌握了它的核心功能:
- 基本 CRUD 操作(无需编写 SQL)
- 条件构造器(灵活构建查询条件)
- 分页查询(一键实现分页)
- 逻辑删除(安全删除数据)
- 代码生成器(自动生成重复代码)
在实际项目中,合理使用 MyBatis-Plus 可以大幅减少重复劳动,提高开发效率。同时,对于复杂查询,MyBatis-Plus 也支持自定义 SQL,兼顾了灵活性和开发效率。