BaseMapper的介绍
BaseMapper 是什么它是 MyBatis‑Plus 提供的一个泛型接口里面预定义了CRUD 的 17 个常用方法。只要让你的 Mapper 继承它无需编写 XML即可实现单表的增删改查。一、BaseMapper 接口源码概览核心部分public interface BaseMapperT extends MapperT { // 新增 int insert(T entity); // 删除 int deleteById(Serializable id); int deleteByMap(Param(cm) MapString, Object columnMap); int delete(Param(ew) WrapperT wrapper); int deleteBatchIds(Param(coll) Collection? idList); // 修改 int updateById(Param(et) T entity); int update(Param(et) T entity, Param(ew) WrapperT updateWrapper); // 查询 T selectById(Serializable id); ListT selectBatchIds(Param(coll) Collection? extends Serializable idList); ListT selectByMap(MapString, Object columnMap); ListT selectList(Param(ew) WrapperT queryWrapper); Long selectCount(Param(ew) WrapperT queryWrapper); // 分页 P extends IPageT P selectPage(P page, Param(ew) WrapperT queryWrapper); }二、环境准备实体类Entity在使用 BaseMapper 之前必须先定义实体类这是 MP 自动生成 SQL 的依据。1️⃣ 实体类代码逐行解释package com.example.demo.entity; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; /** * TableName(user) * 作用指定该实体类对应的数据库表名。 * 如果不写MP 默认将类名驼峰转下划线User - user。 */ TableName(user) Data // Lombok注解自动生成 Getter、Setter、toString 等方法 public class User { /** * TableId(type IdType.AUTO) * 作用标识该字段为主键并指定主键生成策略。 * IdType.AUTO依赖数据库自增如 MySQL 的 AUTO_INCREMENT。 * 如果是雪花算法通常用 IdType.ASSIGN_ID。 */ TableId(type IdType.AUTO) private Long id; /** * 普通字段 * 变量名username * 数据库列名username默认规则 */ private String username; /** * 如果数据库字段名是 user_name而属性名是 userName * 需要加注解TableField(user_name) */ private String password; /** * 注意实体类不需要写任何方法BaseMapper 会接管持久化操作。 */ }三、Mapper 层继承 BaseMapper核心步骤2️⃣ Mapper 接口代码逐行解释package com.example.demo.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.example.demo.entity.User; import org.apache.ibatis.annotations.Mapper; /** * UserMapper 接口 * 作用定义数据访问层DAO层的操作规范。 */ Mapper // 标记该类为 MyBatis 的 Mapper 接口Spring 启动时会扫描并创建代理对象 public interface UserMapper extends BaseMapperUser { /** * 重点解释extends BaseMapperUser * * 1. BaseMapperMP 提供的通用 CRUD 接口。 * 2. User泛型告诉 MP 这个 Mapper 是为 User 实体服务的。 * * 继承后UserMapper 瞬间拥有了 BaseMapper 里的所有方法 * - insert * - deleteById * - updateById * - selectById * - selectList * - ...等等 * * 注意这里不需要写任何方法体也不需要写 XML。 */ // 如果有复杂的多表查询可以在这里定义方法然后在 XML 中实现 // ListUser selectComplexUserList(); }四、BaseMapper 方法实战逐行拆解假设我们在测试类或 Service 中注入了 MapperAutowired private UserMapper userMapper;3️⃣ 新增InsertTest public void testInsert() { User user new User(); user.setUsername(zhangsan); user.setPassword(123456); // 方法insert(T entity) // 作用将实体对象持久化到数据库。 // 参数user 实体对象。 // 返回值int受影响的行数成功通常为 1。 // 底层 SQLINSERT INTO user (username, password) VALUES (zhangsan, 123456); int rows userMapper.insert(user); System.out.println(影响行数 rows); // 如果是自增主键插入后 ID 会自动回填到 user 对象中 System.out.println(插入后的ID user.getId()); }4️⃣ 删除DeleteTest public void testDelete() { // 方法deleteById(Serializable id) // 作用根据主键 ID 删除记录。 // 参数主键的值可以是 Integer、Long、String 等。 // 底层 SQLDELETE FROM user WHERE id 1; int rows userMapper.deleteById(1L); System.out.println(删除行数 rows); }Test public void testDeleteBatch() { // 方法deleteBatchIds(Collection? idList) // 作用批量删除根据 ID 集合。 // 参数包含多个 ID 的集合List、Set 等。 // 底层 SQLDELETE FROM user WHERE id IN (1, 2, 3); ListLong ids Arrays.asList(2L, 3L, 4L); int rows userMapper.deleteBatchIds(ids); }5️⃣ 修改UpdateTest public void testUpdate() { User user new User(); user.setId(5L); // 必须指定 ID否则不知道改哪条 user.setUsername(lisi_new); // 方法updateById(T entity) // 作用根据 ID 修改数据非空字段才会被更新。 // 注意MP 默认使用字段的 NULL 判断如果字段为 null则不出现在 SET 语句中。 // 底层 SQLUPDATE user SET usernamelisi_new WHERE id 5; int rows userMapper.updateById(user); }6️⃣ 查询Select根据 ID 查询Test public void testSelectById() { // 方法selectById(Serializable id) // 作用根据主键查询一条记录。 // 返回值实体对象查不到返回 null。 // 底层 SQLSELECT id, username, password FROM user WHERE id 5; User user userMapper.selectById(5L); System.out.println(user); }查询全部常用Test public void testSelectList() { // 方法selectList(WrapperT queryWrapper) // 作用查询列表。 // 参数条件构造器Wrapper。 // 如果参数为 null表示查询全部无任何条件。 // 底层 SQLSELECT id, username, password FROM user; ListUser users userMapper.selectList(null); users.forEach(System.out::println); }条件查询Wrapper 初探Test public void testSelectByCondition() { // QueryWrapper 是 MP 的条件构造器用于拼接 WHERE 条件 QueryWrapperUser wrapper new QueryWrapper(); // 拼接条件username zhangsan wrapper.eq(username, zhangsan); // 拼接条件AND age 18 // wrapper.gt(age, 18); // 底层 SQLSELECT * FROM user WHERE username zhangsan; ListUser users userMapper.selectList(wrapper); }7️⃣ 分页查询重点注意分页功能需要在配置类中注册拦截器才能生效见附录。Test public void testSelectPage() { // 1. 创建分页对象 // Page(current, size): current 是当前页从 1 开始size 是每页条数 PageUser page new Page(1, 5); // 2. 调用分页查询 // 第一个参数是分页对象第二个参数是条件构造器null 表示无额外条件 PageUser resultPage userMapper.selectPage(page, null); // 3. 获取数据 System.out.println(总记录数 resultPage.getTotal()); System.out.println(总页数 resultPage.getPages()); System.out.println(当前页数据 resultPage.getRecords()); }五、BaseMapper 的执行原理简图Controller ↓ Service ↓ UserMapper (接口) ↓ MyBatis‑Plus 动态代理 ↓ 根据 User 实体 注解 ↓ 自动生成 SQL ↓ JDBC ↓ Database六、BaseMapper 使用限制与注意事项单表操作BaseMapper 只能操作单张表不支持多表 JOIN。实体映射实体类必须存在且最好标注TableName和TableId。主键策略如果数据库主键是自增的实体类必须配置IdType.AUTO否则插入后拿不到 ID。Wrapper 注入风险selectList(null)会查询全表数据量大时要慎用必须加分页或条件。七、附录分页插件配置必须配置才能用 selectPagepackage com.example.demo.config; import com.baomidou.mybatisplus.annotation.DbType; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class MybatisPlusConfig { /** * 添加分页拦截器 * 作用拦截 SQL自动在 SQL 末尾拼接 LIMIT ? OFFSET ? */ Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); // 添加分页插件指定数据库类型为 MySQL interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }八、总结口诀实体映射表Mapper 继承它。增删改查全都有条件构造 Wrapper。单表 CRUD 不用写分页记得加拦截。