深入理解 MyBatis-Plus 的 `BaseMapper`

在使用 MyBatis-Plus(简称 MP)时,开发者几乎一定会接触到 BaseMapper 接口。它是 MP 的核心功能之一,提供了单表的基础 CRUD 操作,极大地减少了样板代码的编写工作。本文将详细介绍 BaseMapper 的作用、常用方法、源码解析以及最佳实践。


1. BaseMapper 简介

BaseMapper<T> 是 MyBatis-Plus 提供的一个 通用 Mapper 接口 ,泛型参数 T 指定实体类类型。

它的设计初衷是:让开发者无需编写 XML 或额外的 SQL,即可直接使用基础的 增删改查方法

定义位置

java 复制代码
package com.baomidou.mybatisplus.core.mapper;

public interface BaseMapper<T> extends Mapper<T> {
    // 内置了丰富的 CRUD 方法
}

只要你的 Mapper 接口继承了 BaseMapper<T>,并指定了对应的实体类,就能直接调用这些 CRUD 方法。例如:

java 复制代码
@Mapper
public interface UserMapper extends BaseMapper<User> {
}

2. 常用方法一览

BaseMapper 内置了近 20 个常用方法,主要涵盖了 增、删、改、查

(1)插入

java 复制代码
int insert(T entity);
  • 功能:插入一条记录
  • 特点:只插入非 null 字段,支持自增主键回填

(2)删除

java 复制代码
int deleteById(Serializable id);
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
int deleteBatchIds(@Param(Constants.COLL) Collection<? extends Serializable> idList);
  • deleteById:根据主键删除
  • deleteBatchIds:批量删除
  • deleteByMap :通过 Map<列名, 值> 删除
  • delete(Wrapper):条件删除(支持 LambdaQueryWrapper)

(3)更新

java 复制代码
int updateById(@Param(Constants.ENTITY) T entity);
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
  • updateById:根据主键更新,null 值字段会被更新为 null
  • update :条件更新,配合 UpdateWrapper 使用

(4)查询

java 复制代码
T selectById(Serializable id);
List<T> selectBatchIds(@Param(Constants.COLL) Collection<? extends Serializable> idList);
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
  • 单条查询selectById, selectOne
  • 批量查询selectBatchIds, selectList
  • 分页查询selectPage, selectMapsPage
  • 统计selectCount
  • Map 查询 :返回 Map<String, Object>,适合动态表格场景

3. 使用示例

假设我们有一个 User 实体类:

java 复制代码
@Data
@TableName("user")
public class User {
    private Long id;
    private String name;
    private Integer age;
}

对应的 UserMapper

java 复制代码
@Mapper
public interface UserMapper extends BaseMapper<User> {
}

插入

java 复制代码
User user = new User();
user.setName("张三");
user.setAge(20);
userMapper.insert(user); // 返回插入条数

删除

java 复制代码
userMapper.deleteById(1L);
userMapper.deleteBatchIds(Arrays.asList(1L, 2L, 3L));
userMapper.delete(new QueryWrapper<User>().eq("age", 20));

更新

java 复制代码
User user = userMapper.selectById(1L);
user.setAge(25);
userMapper.updateById(user);

userMapper.update(new User(), new UpdateWrapper<User>().set("age", 30).eq("name", "张三"));

查询

java 复制代码
User user = userMapper.selectById(1L);

List<User> users = userMapper.selectList(new QueryWrapper<User>().ge("age", 18));

Page<User> page = new Page<>(1, 10);
IPage<User> userPage = userMapper.selectPage(page, new QueryWrapper<User>().orderByDesc("id"));

4. 源码解析

BaseMapper 的方法本质上并没有具体实现,而是由 MyBatis-Plus 内置的 SQL 注入器 生成。

  • 默认使用 DefaultSqlInjector
  • 会自动为每个方法拼接对应 SQL
  • 所有方法底层最终都会映射到 XML 或内置 SQL 语句

举例:insert(T entity) 对应的 SQL 类似:

sql 复制代码
INSERT INTO user (id, name, age) VALUES (#{id}, #{name}, #{age})

5. 使用注意事项

  1. 批量操作性能

    • insert 是逐条执行,不是批量插入
    • 建议使用 saveBatch(来自 IService)或自定义 SQL 提升性能
  2. 空值更新

    • updateById 会将 null 字段更新为 null
    • 如果想忽略 null 值,可以使用 UpdateWrapper.set()
  3. 多表查询

    • BaseMapper 仅支持单表操作
    • 多表需要写自定义 SQL 或使用 @Select 注解
  4. Wrapper 灵活性

    • 推荐使用 LambdaQueryWrapper / LambdaUpdateWrapper 避免硬编码列名

    • 例如:

      java 复制代码
      new LambdaQueryWrapper<User>().eq(User::getName, "张三");

6. 总结

  • BaseMapper<T> 是 MyBatis-Plus 提供的核心接口
  • 内置丰富的 CRUD 方法,省去了大量模板代码
  • 搭配 Wrapper 可实现灵活查询
  • 局限性:仅支持单表,复杂场景需自定义 SQL
相关推荐
韩立学长1 分钟前
【开题答辩实录分享】以《智慧物业管理系统的设计与实现》为例进行答辩实录分享
java·后端·mysql
10km4 分钟前
java:json-path支持fastjson作为JSON解析提供者的技术实现
java·json·fastjson·json-path
小张程序人生7 分钟前
深入理解SpringSecurity从入门到实战
java
d***956224 分钟前
springboot接入deepseek深度求索 java
java·spring boot·后端
小白学大数据37 分钟前
基于Splash的搜狗图片动态页面渲染爬取实战指南
开发语言·爬虫·python
xlq2232239 分钟前
22.多态(下)
开发语言·c++·算法
CoderYanger43 分钟前
C.滑动窗口-越短越合法/求最长/最大——2958. 最多 K 个重复元素的最长子数组
java·数据结构·算法·leetcode·哈希算法·1024程序员节
洞窝技术1 小时前
Redis 4.0 升级至 5.0 实施手册
java·redis
无代码专家1 小时前
设备巡检数字化解决方案:构建高效闭环管理体系
java·大数据·人工智能
未来之窗软件服务1 小时前
操作系统应用(三十三)php版本选择系统—东方仙盟筑基期
开发语言·php·仙盟创梦ide·东方仙盟·服务器推荐