MyBatis-Plus详解(速成版)
·
一、介绍MyBatis-Plus:
1.概念
MyBatis-Plus 是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
2.特点:
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
- 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
- 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
- 支持自定义全局通用操作:支持全局通用方法注入
- 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
- 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
- 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
- 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
- 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
3.框架结构:

二、配置MyBatis-Plus:
1.引入依赖:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.15</version>
</dependency>
2.使用 @MapperScan 注解扫描 mapper 文件:
@SpringBootApplication
@MapperScan("com.baomidou.mybatisplus.samples.quickstart.mapper")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
3.在 application.yml 文件中增加MyBatis-Plus 的统一配置:
# mybatis 相关统一配置
mybatis-plus:
configuration:
#开启下划线转驼峰
map-underscore-to-camel-case: true
作用:将数据库表中的下划线命名方式映射为 Java 对象中的驼峰命名方式。例如,数据库表中的列名为 user_name,对应的 Java 对象的属性名为 userName。
三、基本使用
1. BaseMapper CRUD
@Data
@TableName("user")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
}
// Mapper 接口 —— 继承 BaseMapper 即拥有全套单表 CRUD
public interface UserMapper extends BaseMapper<User> {}
增
User user = new User();
user.setName("张三");
user.setAge(25);
userMapper.insert(user); // id 自动回填到实体
删
userMapper.deleteById(1L);
userMapper.deleteBatchIds(Arrays.asList(1L, 2L, 3L));
// 条件删除
userMapper.delete(new LambdaQueryWrapper<User>()
.lt(User::getAge, 18)
.eq(User::getName, "张三")
);
改
// 只更新非 null 字段
User user = new User();
user.setId(1L);
user.setName("李四");
userMapper.updateById(user);
// 条件更新
userMapper.update(user, new LambdaUpdateWrapper<User>()
.eq(User::getAge, 25)
);
查
User user = userMapper.selectById(1L);
List<User> users = userMapper.selectBatchIds(Arrays.asList(1L, 2L));
List<User> users = userMapper.selectList(
new LambdaQueryWrapper<User>()
.eq(User::getAge, 25)
.orderByDesc(User::getCreateTime)
);
Long count = userMapper.selectCount(
new LambdaQueryWrapper<User>().gt(User::getAge, 20)
);
2. 条件构造器 Wrapper
LambdaQueryWrapper
// SELECT * FROM user WHERE age BETWEEN 20 AND 30
// AND name LIKE '%张%' AND email IS NOT NULL
// ORDER BY age DESC, id ASC LIMIT 10
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
.between(User::getAge, 20, 30)
.like(User::getName, "张")
.isNotNull(User::getEmail)
.orderByDesc(User::getAge)
.orderByAsc(User::getId)
.last("LIMIT 10");
List<User> users = userMapper.selectList(wrapper);
条件方法速查
| 方法 | 说明 | SQL |
|---|---|---|
eq |
等于 | name = '张三' |
ne |
不等于 | name <> '张三' |
gt / ge |
大于 / ≥ | age > 18 |
lt / le |
小于 / ≤ | age < 30 |
between |
区间 | age BETWEEN 20 AND 30 |
like / notLike |
模糊 | name LIKE '%张%' |
likeLeft / likeRight |
左/右模糊 | name LIKE '%张' |
in / notIn |
包含 | id IN (1,2,3) |
isNull / isNotNull |
空/非空 | email IS NULL |
orderByAsc / orderByDesc |
排序 | ORDER BY age ASC |
UpdateWrapper
// UPDATE user SET age = 26, name = '王五' WHERE id = 1
LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<User>()
.eq(User::getId, 1L)
.set(User::getAge, 26)
.set(User::getName, "王五");
userMapper.update(null, wrapper);
动态条件
// condition 为 false 时该条件不会拼入 SQL
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
.eq(StringUtils.isNotBlank(name), User::getName, name)
.ge(age != null, User::getAge, age);
嵌套条件
// WHERE name = '张三' AND (age = 20 OR email IS NOT NULL)
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
.eq(User::getName, "张三")
.and(w -> w.eq(User::getAge, 20).or().isNotNull(User::getEmail));
3. 分页查询
配置插件
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(
new PaginationInnerInterceptor(DbType.MYSQL)
);
return interceptor;
}
}
使用
Page<User> page = new Page<>(1, 10); // 第1页,每页10条
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
.like(StringUtils.isNotBlank(keyword), User::getName, keyword)
.orderByDesc(User::getCreateTime);
Page<User> result = userMapper.selectPage(page, wrapper);
result.getRecords(); // 当前页数据
result.getTotal(); // 总记录数
result.getPages(); // 总页数
联表分页
// Mapper 接口
Page<UserVO> selectUserWithDept(Page<UserVO> page,
@Param("ew") LambdaQueryWrapper<User> wrapper);
// XML
// SELECT u.*, d.name AS dept_name
// FROM user u LEFT JOIN department d ON u.dept_id = d.id
// ${ew.customSqlSegment}
4. IService
IService 对 BaseMapper 的进一步封装,提供批量操作和链式调用。
public interface IUserService extends IService<User> {}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
implements IUserService {}
常用方法
// 增
userService.save(user);
userService.saveBatch(userList); // 批量(默认每批1000条)
// 删
userService.removeById(1L);
userService.removeByIds(ids);
// 改
userService.updateById(user);
userService.updateBatchById(userList); // 批量更新
// 查
userService.getById(1L);
userService.list(queryWrapper);
userService.count(queryWrapper);
链式调用
// 链式查询
userService.lambdaQuery()
.eq(User::getAge, 25)
.like(User::getName, "张")
.list();
// 链式更新
userService.lambdaUpdate()
.set(User::getAge, 30)
.eq(User::getId, 1L)
.update();
// 链式删除
userService.lambdaUpdate()
.eq(User::getAge, 0)
.remove();
5. 自动填充
实体标注
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
实现 Handler
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", LocalDateTime::now, LocalDateTime.class);
this.strictInsertFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
}
}
四、常用注解速查
| 注解 | 位置 | 说明 |
|---|---|---|
@TableName |
实体类 | 指定表名 |
@TableId |
主键字段 | 主键策略 |
@TableField |
普通字段 | 映射、填充、非数据库字段 |
@TableLogic |
逻辑删除字段 | 逻辑删除标识 |
@Version |
乐观锁字段 | 配合乐观锁插件 |
@EnumValue |
枚举字段 | 枚举值映射 |
@OrderBy |
字段 | 默认排序 |
IdType 主键策略
| 策略 | 说明 |
|---|---|
AUTO |
数据库自增 |
INPUT |
手动设置 |
ASSIGN_ID |
雪花算法(默认,Long) |
ASSIGN_UUID |
UUID(String) |
@TableField 属性
@TableField(value = "email_addr") // 列名映射
@TableField(exist = false) // 非数据库字段
@TableField(fill = FieldFill.INSERT) // 自动填充
@TableField(select = false) // 查询不返回
五、实用技巧
1. 逻辑删除
mybatis-plus:
global-config:
db-config:
logic-delete-field: deleted
logic-delete-value: 1
logic-not-delete-value: 0
配置后所有 CRUD 自动适配:deleteById → UPDATE SET deleted=1,selectList → 自动追加 WHERE deleted=0。
2. 乐观锁
// 配置插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
// 实体
@Version
private Integer version;
// 使用:先查后改,version 自动 +1
User user = userMapper.selectById(1L); // version = 1
user.setName("新名字");
userMapper.updateById(user); // WHERE id=1 AND version=1 → version=2
3. 防全表更新/删除
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
// 阻止无 WHERE 条件的 update/delete
4. AR 模式(ActiveRecord)
@Data
@TableName("user")
public class User extends Model<User> { ... }
// 无需注入 Mapper,直接用实体操作
User user = new User();
user.setName("张三");
user.insert();
User found = new User();
found.setId(1L);
found = found.selectById();
速记:继承 BaseMapper 得单表 CRUD,Wrapper 构造条件,IService 加批量和链式调用,分页插件配一行,注解搞定映射和填充。
更多推荐




所有评论(0)