MyBatis-Plus指南:从入门到面试

发布时间:2026/10/30 4:38:23
MyBatis-Plus指南:从入门到面试

Hello,大家好,我是Yize,在学习SpringCloud时学习到了MyBatis-plus,下面就跟我一起来学习吧!!

目录

一、先搞清楚:MyBatis-Plus 是什么?

二、⭐ MyBatis vs MyBatis-Plus 核心对比表(面试默写级)

三、MP 解决了 MyBatis 的哪些痛点?

四、快速入门(三步走)

1️⃣ 引入依赖

2️⃣ 配置文件(application.yml)

3️⃣ 启动类加扫描

五、实体类常用注解

六、核心功能一:通用 CRUD(BaseMapper)⭐

七、核心功能二:条件构造器 Wrapper(MP 的灵魂)⭐

常用条件方法速查

示例:LambdaQueryWrapper(推荐)

示例:LambdaUpdateWrapper

八、核心功能三:分页插件 ⭐

1️⃣ 配置分页插件(必须注册)

2️⃣ 使用分页

九、核心功能四:Service 层封装(IService)

十、企业级高阶功能

十一、⚠️ 什么时候用 / 什么时候手写 SQL

十二、常见误区澄清(面试加分) ❓

十三、一句话复习提纲 📝

🔑 面试高频考点


🧩 MyBatis-Plus 知识点总结(对比 MyBatis)

一、先搞清楚:MyBatis-Plus 是什么?

MyBatis-Plus(简称 MP)是 MyBatis 的增强工具,只做增强、不做改变,为简化开发、提高效率而生。

核心定位:

  • 它不是 MyBatis 的替代品,底层依旧依赖 MyBatis​ 执行 SQL
  • 引入后,原有 MyBatis 的 XML、Mapper 接口完全不用改,平滑兼容
  • 愿景是成为 MyBatis 的"最佳搭档"(像魂斗罗 1P、2P,效率翻倍)

一句话记忆:​ MP 是 MyBatis 的"自动挡升级版"——基础的 CRUD 不用写 SQL,但复杂场景仍可切回"手动挡"(手写 XML)


二、⭐ MyBatis vs MyBatis-Plus 核心对比表(面试默写级)

对比维度

MyBatis

MyBatis-Plus

定位​

基础持久层框架

MyBatis 的增强工具

单表 CRUD​

每张表手写 XML/注解 SQL,重复代码多

BaseMapper内置,零 SQL​

条件/动态查询​

手写 XML<if>动态标签拼接

Wrapper 条件构造器,Java 链式调用

分页​

手动写LIMIT,或借助 PageHelper

内置分页插件,开箱即用

主键策略​

依赖数据库自增

自增、雪花算法、UUID 等多种

逻辑删除​

手动加标记、改 SQL

@TableLogic注解,自动软删

自动填充时间​

自己封装工具赋值

@TableField(fill)+MetaObjectHandler

Lambda 查询​

不支持,只能写字段字符串

LambdaQueryWrapper,编译期校验防写错

代码生成​

无,需第三方工具

内置代码生成器,一键生成全套

代码量​

大、模板冗余

少、告别重复代码

灵活性​

极高,完全可控

单表强,复杂多表仍可手写 XML


三、MP 解决了 MyBatis 的哪些痛点?

  1. 单表 CRUD 样板代码多​ →BaseMapper内置,继承即用
  2. 动态条件拼接易出错​ → Wrapper 链式调用,参数化防 SQL 注入
  3. 分页、逻辑删除、时间戳、乐观锁等通用能力无内置​ → 插件/注解开箱即用
  4. 实体与字段映射、多条件查询冗余​ → 约定优于配置

四、快速入门(三步走)

1️⃣ 引入依赖

<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.9</version> </dependency>

2️⃣ 配置文件(application.yml)

mybatis-plus: mapper-locations: classpath*:/mapper/**/*.xml type-aliases-package: com.example.entity global-config: db-config: id-type: auto # 主键策略:自增 logic-delete-field: deleted # 逻辑删除字段 logic-delete-value: 1 logic-not-delete-value: 0 configuration: map-underscore-to-camel-case: true # 驼峰映射 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 打印SQL

3️⃣ 启动类加扫描

@SpringBootApplication @MapperScan("com.example.mapper") // 扫描 Mapper public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }

五、实体类常用注解

@Data @TableName("user") // 指定表名 public class User { @TableId(type = IdType.AUTO) // 主键策略:自增 private Long id; @TableField("user_name") // 字段映射 private String name; @TableField(select = false) // 查询时不返回该字段 private String password; @TableField(fill = FieldFill.INSERT) // 插入时自动填充 private Date createTime; @TableField(fill = FieldFill.INSERT_UPDATE) // 插入/更新填充 private Date updateTime; @TableLogic // 逻辑删除 @TableField("deleted") private Integer deleted; @Version // 乐观锁版本号 private Integer version; }

主键策略(IdType):

策略

说明

AUTO

数据库自增

ASSIGN_ID

雪花算法(默认)

ASSIGN_UUID

UUID

INPUT

手动输入


六、核心功能一:通用 CRUD(BaseMapper)⭐

Mapper 接口只需继承BaseMapper,就自动拥有单表 CRUD 方法,零 SQL:

@Mapper public interface UserMapper extends BaseMapper<User> { // 无需编写任何方法,已内置: // insert / deleteById / delete(Wrapper) // updateById / update(entity, Wrapper) // selectById / selectBatchIds / selectByMap // selectOne / selectCount / selectList / selectPage }

使用示例:

@Autowired private UserMapper userMapper; userMapper.insert(user); // 新增 userMapper.selectById(1L); // 按ID查询 userMapper.selectList(wrapper); // 按条件查询 userMapper.updateById(user); // 按ID更新 userMapper.deleteById(1L); // 删除(逻辑删除则自动改SQL)

七、核心功能二:条件构造器 Wrapper(MP 的灵魂)⭐

解决动态 SQL 拼接繁琐问题,链式调用、参数化防注入、Lambda 版本编译期校验字段。

四大构造器(企业首选 Lambda 版本):

  • QueryWrapper:查询/删除,字段写字符串(硬编码,不推荐)
  • LambdaQueryWrapper:查询/删除,Lambda 方法引用(✅ 推荐)
  • UpdateWrapper:更新条件,字符串
  • LambdaUpdateWrapper:更新条件,Lambda(✅ 推荐)

常用条件方法速查

方法

含义

示例

eq

=

eq("name", "张三")

ne

≠

ne("age", 18)

gt/ge

> / ≥

gt("age", 18)

lt/le

< / ≤

le("age", 60)

between

区间

between("age", 18, 30)

like

%值%

like("name", "李")

likeRight

值%

likeRight("phone", "138")

isNull/isNotNull

空判断

isNull("email")

in/notIn

集合

in("dept_id", list)

orderByAsc/Desc

排序

orderByDesc("age")

groupBy

分组

groupBy("age")

示例:LambdaQueryWrapper(推荐)

// 查询:年龄>18 且 城市=武汉 的用户 LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(); wrapper.gt(User::getAge, 18) .eq(User::getCity, "武汉") .orderByDesc(User::getAge); List<User> userList = userMapper.selectList(wrapper);

示例:LambdaUpdateWrapper

// 把张三的年龄改为20 LambdaUpdateWrapper<User> wrapper = Wrappers.lambdaUpdate(); wrapper.eq(User::getName, "张三") .set(User::getAge, 20); userMapper.update(null, wrapper);

💡vs MyBatis:​ 同样需求在 MyBatis 要手写 XML<if>动态标签,MP 用 Java 链式一行搞定,且防 SQL 注入。


八、核心功能三:分页插件 ⭐

1️⃣ 配置分页插件(必须注册)

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

2️⃣ 使用分页

// 查询第1页,每页10条 Page<User> page = new Page<>(1, 10); LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery(); wrapper.gt(User::getAge, 18); Page<User> result = userMapper.selectPage(page, wrapper); // result.getRecords() 数据列表 // result.getTotal() 总记录数 // result.getCurrent() 当前页

💡vs MyBatis:​ 不用手写LIMIT,插件自动拦截改写 SQL 并查总数,纯物理分页。


九、核心功能四:Service 层封装(IService)

MP 提供IService+ServiceImpl做业务层二次封装,新增批量操作、链式查询:

// Service 接口 public interface UserService extends IService<User> {} // 实现类 @Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {}

IService 增强能力(批量、语义化):

userService.saveBatch(userList); // 批量新增 userService.updateBatchById(userList);// 批量更新 userService.listByIds(idList); // 按主键批量查询 userService.removeByIds(idList); // 按主键批量删除 userService.lambdaQuery() // 链式查询 .eq(User::getAge, 18) .list();

BaseMapper vs IService 区别:

BaseMapper

IService

层级

DAO/Mapper 层

Service 层

特点

底层原生操作

批量、链式、语义化

使用

简单单条/自定义

项目标准分层


十、企业级高阶功能

功能

用法

自动填充​

@TableField(fill)+ 实现MetaObjectHandler,自动注入 createTime/updateTime

逻辑删除​

@TableLogic,delete 自动改写为 update

乐观锁​

@Version+ 注册乐观锁拦截器,防并发覆盖

防全表操作​

全局拦截插件,阻断无条件的全表 delete/update

代码生成器​

根据表结构一键生成 Entity/Mapper/Service/Controller

多租户​

TenantLineInnerInterceptor自动追加 tenant_id


十一、⚠️ 什么时候用 / 什么时候手写 SQL

✅ 优先用 MP:

  • 后台管理系统、CRUD 为主
  • 单表增删改查、简单条件查询
  • 需要统一规范(自动填充、逻辑删除、乐观锁)

✅ 必须用原生 MyBatis(手写 XML):

  • 多表联查、复杂统计、子查询
  • 大数据量复杂报表、分组聚合
  • 需要 DBA 深度优化 SQL 的核心业务(支付、对账)

💡企业最佳实践:MP 做单表快速开发 + 原生 XML 做复杂 SQL,两者混合使用,互不冲突。


十二、常见误区澄清(面试加分) ❓

  • ❌ MP 可以完全替代 MyBatis?​ ✅ 错,MP 只是增强,底层仍依赖 MyBatis
  • ❌ 用 MP 就不能写 XML SQL?​ ✅ 错,完全可混用,自定义方法 + XML 共存
  • ❌ MP 会降低性能?​ ✅ 错,只是代码封装,最终生成标准 SQL,性能一致
  • ❌ MP 只能做简单 CRUD?​ ✅ 错,支持条件、分页、分组、批量等

十三、一句话复习提纲 📝

MP 是 MyBatis 的"增强搭档,只增强不改动"。​ 靠BaseMapper实现单表零 SQL 的 CRUD,靠Wrapper(推荐 Lambda 版)链式构造条件,靠分页插件自动拦截分页,配合自动填充、逻辑删除、乐观锁、代码生成器等企业级能力大幅提升效率。单表用 MP,多表联查退回原生 XML。


🔑 面试高频考点

  1. MyBatis 与 MP 的区别(增强 vs 替代、CRUD、Wrapper、分页)
  2. MP 的核心定位(只做增强不做改变,兼容原生)
  3. BaseMapper内置方法
  4. Wrapper条件构造器(优先 Lambda 版,防字段写错)
  5. 分页插件配置与使用
  6. 自动填充 / 逻辑删除 / 乐观锁的注解与配置
  7. MP 与原生 MyBatis 的选型(单表 MP,多表手写 SQL)

好啦!本次的分享到此结束,我们下次见!!!