深入理解 MyBatis-Plus 的 `BaseMapper`

发布于:2025-09-11 ⋅ 阅读:(20) ⋅ 点赞:(0)

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


1. BaseMapper 简介

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

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

定义位置

package com.baomidou.mybatisplus.core.mapper;

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

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

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

2. 常用方法一览

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

(1)插入

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

(2)删除

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)更新

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)查询

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 实体类:

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

对应的 UserMapper

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

插入

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

删除

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

更新

User user = userMapper.selectById(1L);
user.setAge(25);
userMapper.updateById(user);

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

查询

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 类似:

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 避免硬编码列名

    • 例如:

      new LambdaQueryWrapper<User>().eq(User::getName, "张三");
      

6. 总结

  • BaseMapper<T> 是 MyBatis-Plus 提供的核心接口
  • 内置丰富的 CRUD 方法,省去了大量模板代码
  • 搭配 Wrapper 可实现灵活查询
  • 局限性:仅支持单表,复杂场景需自定义 SQL

网站公告

今日签到

点亮在社区的每一天
去签到