在使用 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 值字段会被更新为 nullupdate
:条件更新,配合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. 使用注意事项
-
批量操作性能
insert
是逐条执行,不是批量插入- 建议使用
saveBatch
(来自IService
)或自定义 SQL 提升性能
-
空值更新
updateById
会将 null 字段更新为 null- 如果想忽略 null 值,可以使用
UpdateWrapper.set()
-
多表查询
BaseMapper
仅支持单表操作- 多表需要写自定义 SQL 或使用
@Select
注解
-
Wrapper 灵活性
-
推荐使用
LambdaQueryWrapper
/LambdaUpdateWrapper
避免硬编码列名 -
例如:
javanew LambdaQueryWrapper<User>().eq(User::getName, "张三");
-
6. 总结
BaseMapper<T>
是 MyBatis-Plus 提供的核心接口- 内置丰富的 CRUD 方法,省去了大量模板代码
- 搭配
Wrapper
可实现灵活查询 - 局限性:仅支持单表,复杂场景需自定义 SQL