
MyBatis-Plus简称 MP是 MyBatis 的增强工具在 MyBatis 的基础上只做增强不做改变旨在简化开发、提高效率。它的核心价值在于通过继承BaseMapper无需编写任何 SQL 和 XML 映射文件即可获得完整的单表 CRUD 能力。一句话速记MyBatis-Plus MyBatis 瑞士军刀皮肤 防删库保险栓。它保留了 MyBatis 的全部灵活性同时用 Lambda 表达式和自动化能力解决了原生框架的重复劳动问题。一、快速入门3 步启动1.1 引入依赖xmldependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.1/version /dependency注意引入 MP 的 starter 后可以移除原生的mybatis-spring-boot-starter依赖避免版本冲突。MP 的 starter 已包含 MyBatis 核心包。1.2 继承 BaseMapperjavaMapper public interface UserMapper extends BaseMapperUser { // 无需编写任何方法即可获得完整 CRUD 能力 }1.3 实体类映射javaData TableName(user) // 指定表名类名与表名一致时可省略 public class User { TableId(type IdType.AUTO) // 主键策略数据库自增 private Long id; private String name; private Integer age; private String email; }二、核心注解速查表注解作用示例TableName指定实体类对应的数据库表名TableName(sys_user)TableId指定主键字段及生成策略TableId(value id, type IdType.AUTO)TableField指定普通字段映射TableField(user_name)TableField(exist false)非表字段TableLogic逻辑删除字段标记TableLogic private Integer deleted;Version乐观锁版本号字段Version private Integer version;主键策略IdType策略说明AUTO数据库 ID 自增ASSIGN_ID雪花算法生成 Long 型 ID默认策略INPUT用户手动输入 IDASSIGN_UUID分配 UUID主键类型为 String三、BaseMapper CRUD 速查BaseMapper 内置了完整的单表操作 API无需手动编写 SQL。操作类型方法说明插入int insert(T entity)插入一条记录自动忽略 null 字段删除int deleteById(Serializable id)根据主键删除int deleteBatchIds(Collection? idList)批量删除int deleteByMap(MapString, Object columnMap)根据 Map 条件删除int delete(WrapperT wrapper)根据条件构造器删除更新int updateById(T entity)根据主键更新只更新非 null 字段int update(T entity, WrapperT updateWrapper)根据条件更新查询T selectById(Serializable id)根据主键查询ListT selectBatchIds(Collection? idList)批量 ID 查询ListT selectByMap(MapString, Object columnMap)根据 Map 条件查询ListT selectList(WrapperT queryWrapper)条件查询返回列表T selectOne(WrapperT queryWrapper)条件查询返回单条Integer selectCount(WrapperT queryWrapper)条件计数IPageT selectPage(IPageT page, WrapperT queryWrapper)分页查询四、条件构造器Wrapper条件构造器是 MP 最核心的查询工具通过链式编程动态构建 SQL 条件避免硬编码字段名和 SQL 注入风险。4.1 Wrapper 继承体系textWrapper ├── AbstractWrapper │ ├── QueryWrapper // 查询条件封装 │ ├── UpdateWrapper // 更新条件封装 │ └── LambdaQueryWrapper // Lambda 版推荐 └── LambdaUpdateWrapper // Lambda 版更新推荐4.2 常用条件方法速查表方法说明示例eq等于 .eq(name, 张三)ne不等于 .ne(age, 20)gt大于 .gt(age, 18)ge大于等于 .ge(age, 18)lt小于 .lt(age, 65)le小于等于 .le(age, 65)betweenBETWEEN ... AND ....between(age, 18, 30)likeLIKE %值%.like(name, 张)likeLeftLIKE %值.likeLeft(name, 三)likeRightLIKE 值%.likeRight(name, 张)inIN ( ... ).in(id, Arrays.asList(1,2,3))isNullIS NULL.isNull(email)isNotNullIS NOT NULL.isNotNull(email)orderByAscORDER BY ... ASC.orderByAsc(age)orderByDescORDER BY ... DESC.orderByDesc(create_time)select指定查询字段.select(id, name, email)setUPDATE 时设置字段值.set(email, newmail.com)4.3 推荐使用 LambdaWrapper使用 Lambda 表达式通过方法引用指定字段可在编译期发现字段名错误是更安全、更推荐的方式。javaTest void testLambdaQueryWrapper() { LambdaQueryWrapperUser wrapper new LambdaQueryWrapper(); wrapper.gt(User::getAge, 20) .like(User::getName, 张) .orderByDesc(User::getAge); ListUser users userMapper.selectList(wrapper); }4.4 条件性添加NULL 值自动跳过当查询条件可能为 null 时传统方式需要大量 if 判断。MP 支持条件性添加一行解决java// 方法签名.eq(condition, column, value) // 只有 condition 为 true 时该条件才会生效 wrapper.eq(status ! null, User::getStatus, status) .like(name ! null, User::getUsername, name);4.5 更新条件UpdateWrapperjavaTest void testUpdateWrapper() { // 将指定用户余额减少 200 UpdateWrapperUser wrapper new UpdateWrapper(); wrapper.setSql(balance balance - 200) .in(id, Arrays.asList(1L, 2L, 4L)); userMapper.update(null, wrapper); }五、Service 层封装MP 对 Service 层也提供了增强。继承IService接口和ServiceImpl实现类即可获得丰富的业务层方法。5.1 快速接入java// Service 接口 public interface UserService extends IServiceUser { // 可添加自定义业务方法 } // Service 实现类 Service public class UserServiceImpl extends ServiceImplUserMapper, User implements UserService { // 无需手动实现即可使用 IService 的全部方法 }5.2 IService 常用方法速查类型方法说明保存boolean save(T entity)插入一条记录boolean saveBatch(CollectionT entityList)批量插入更新boolean updateById(T entity)根据 ID 更新boolean update(T entity, WrapperT updateWrapper)根据条件更新boolean updateBatchById(CollectionT entityList)批量更新查询T getById(Serializable id)根据 ID 查询ListT list(WrapperT queryWrapper)条件查询列表IPageT page(IPageT page, WrapperT queryWrapper)分页查询long count(WrapperT queryWrapper)条件计数删除boolean removeById(Serializable id)根据 ID 删除boolean remove(WrapperT queryWrapper)根据条件删除链式调用lambdaQuery()Lambda 条件查询lambdaUpdate()Lambda 条件更新5.3 Service 层 Lambda 链式调用javapublic ListUser queryUserList(String name, Integer status, Integer minBal, Integer maxBal) { return lambdaQuery() .like(name ! null, User::getUsername, name) .eq(status ! null, User::getStatus, status) .between(minBal ! null maxBal ! null, User::getBalance, minBal, maxBal) .list(); }六、高级特性6.1 分页插件配置分页插件后分页查询如同普通 List 查询一样简单。java// 1. 配置分页插件Spring Boot 配置类 Configuration public class MybatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } } // 2. 使用分页查询 Test void testPage() { PageUser page new Page(1, 10); // 第1页每页10条 LambdaQueryWrapperUser wrapper new LambdaQueryWrapper(); wrapper.ge(User::getAge, 18); PageUser result userMapper.selectPage(page, wrapper); ListUser records result.getRecords(); long total result.getTotal(); }6.2 逻辑删除逻辑删除通过标记字段实现“假删除”数据不会真正从数据库移除。java// 实体类添加逻辑删除字段 TableLogic private Integer deleted; // 配置文件 mybatis-plus: global-config: db-config: logic-delete-field: deleted logic-delete-value: 1 # 已删除值 logic-not-delete-value: 0 # 未删除值6.3 自动填充自动填充用于create_time、update_time等字段无需手动设置。java// 实体类字段配置 TableField(fill FieldFill.INSERT) private LocalDateTime createTime; TableField(fill FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; // 元对象处理器 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()); } }6.4 乐观锁通过版本号机制防止并发更新冲突。java// 实体类添加版本号字段 Version private Integer version; // 配置乐观锁插件 Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; }6.5 代码生成器根据数据库表结构自动生成 Entity、Mapper、Service、Controller 等代码。具体配置可根据官方文档示例结合项目实际进行调整。6.6 自定义 SQLWrapper 复用利用 Wrapper 构建 Where 条件自定义 SQL 的剩余部分。java// 1. Mapper 接口 void updateBalanceByIds(Param(ew) LambdaQueryWrapperUser wrapper, Param(amount) int amount); // 2. XML 映射 update idupdateBalanceByIds UPDATE user SET balance balance - #{amount} ${ew.customSqlSegment} /update // 3. 调用端 Test void testCustomSql() { LambdaQueryWrapperUser wrapper new LambdaQueryWrapper(); wrapper.in(User::getId, Arrays.asList(1L, 2L, 4L)); userMapper.updateBalanceByIds(wrapper, 200); }七、配置速查表yamlmybatis-plus: # Mapper XML 文件位置 mapper-locations: classpath*:/mapper/**/*.xml # 实体类别名扫描包 type-aliases-package: com.example.entity configuration: # 驼峰命名自动映射默认 true map-underscore-to-camel-case: true # SQL 日志输出开发环境开启 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 二级缓存 cache-enabled: false global-config: db-config: # 主键策略assign_id雪花算法/ auto自增/ none id-type: assign_id # 逻辑删除字段名 logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0 # 更新策略只更新非空字段 update-strategy: not_null八、总结功能模块核心要点BaseMapper继承即用零 SQL 实现单表 CRUDLambdaWrapper类型安全的条件构造编译期校验字段名IServiceService 层增强批量操作、链式调用分页插件物理分页一行配置与普通查询无异逻辑删除假删除机制数据可追溯乐观锁版本号防并发冲突代码生成器一键生成全套基础代码核心建议优先使用LambdaQueryWrapper / LambdaUpdateWrapper替代字符串硬编码复杂查询组合使用 Wrapper 自定义 SQL日常 CRUD 直接复用 BaseMapper / IService 即可省去编写冗余 XML 的重复劳动。MP 让开发者能够将精力聚焦于业务逻辑而非底层 SQL 的重复劳动。