MP 分页插件与乐观锁插件

MP 的插件通过 MybatisPlusInterceptor 统一注册(3.4 起的推荐机制,旧 PaginationInterceptor 已废弃,以官方文档为准)。本节配置最常用的两个:分页插件与乐观锁插件。

插件注册骨架

一个拦截器链,多个内部插件按注册顺序工作:

@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

多插件叠加时顺序影响行为(如多租户、动态表名等要放外层),组合用法以官方文档为准。

分页插件

PaginationInnerInterceptor 拦截分页查询:自动补 COUNT 查总数、按方言生成 LIMIT。DbType 要与数据库匹配(MYSQL / POSTGRE_SQL / ORACLE 等)。用法:

Page<User> page = new Page<>(2, 10);   // 第 2 页,每页 10 条

// 方式一:Mapper 传 Page
Page<User> result = userMapper.selectPage(page,
        Wrappers.<User>lambdaQuery().eq(User::getStatus, 1));

// 方式二:Service 层
Page<User> result2 = userService.page(page,
        Wrappers.<User>lambdaQuery().orderByDesc(User::getCreateTime));

System.out.println(result.getTotal());      // 输出:总数(自动 COUNT)
System.out.println(result.getRecords().size()); // 输出:本页条数,如 10

注意点:

  • 分页插件对主查询改写 SQL(COUNT + LIMIT),入参放 Page 即生效,返回 List 也可(以官方文档为准);
  • 一对多 join 分页的坑依然存在(见前面章节),复杂场景先分页主表再拼子表;
  • 深分页(LIMIT 100000,10)性能差,数据量大改用游标/按上次最大 id 的条件分页。

乐观锁插件

乐观锁前提:表有版本列 + 实体标注 @Version:

public class User {
    @TableId(type = IdType.AUTO)
    private Long id;
    // ...
    @Version   // 版本号
    private Integer version;
}

更新时插件自动改写 SQL:

-- 开发者写:UPDATE user SET name=? WHERE id=?
-- 插件改写:UPDATE user SET name=?, version=version+1
--           WHERE id=? AND version=旧version

影响行数为 0 说明 version 已被别人改过,业务侧重试:

User u = userService.getById(1L);
u.setName("新名字");
int rows = userMapper.updateById(u);  // 带乐观锁条件
if (rows == 0) {
    // 冲突:提示用户或重新读取后再试
}

使用注意:version 由插件维护,不要手动 +1;乐观锁适合冲突少的更新,高冲突场景用悲观锁/分布式锁更合适;updateById(entity) 与 update(entity, wrapper) 的支持细节以官方文档为准。

两个插件都是"注册一次、全局生效":PaginationInnerInterceptor 消灭分页样板 SQL,OptimisticLockerInnerInterceptor 用版本号杜绝更新覆盖。先配好拦截器链,再按"Page 入参、@Version 标注"两步使用即可。

笔记加载中…