MyBatis-Plus 中的extends BaseMapperUserEntity到底是什么意思在 MyBatis-Plus 项目中你几乎每个实体都会看到类似下面的代码MapperpublicinterfaceUserMapperextendsBaseMapperUserEntity{}很多人第一次看到都会懵这个extends BaseMapperUserEntity到底是什么鬼它帮我干了什么为什么我接口里什么方法都不写就能用selectById、insert、updateById这些方法这篇博客就来把这件事讲清楚尽量用最白话、最直白的语言不绕弯子。1. 先说结论一句话记住extends BaseMapperUserEntity的意思是“我这个 UserMapper 接口自动继承了 MyBatis-Plus 写好的一个万能父接口 BaseMapper它里面已经预定义了 20 个最常用的单表 CRUD 方法而且这些方法全部是针对 UserEntity 这张表的。”你什么都不用写就能直接用这些方法userMapper.selectById(1L)userMapper.insert(user)userMapper.updateById(user)userMapper.deleteById(1L)userMapper.selectList(...)……这就是 MyBatis-Plus 号称“单表 CRUD 无需写 SQL”的核心秘密。2. BaseMapper 到底是什么BaseMapperT是 MyBatis-Plus 提供的一个泛型接口位于包com.baomidou.mybatisplus.core.mapper.BaseMapper它里面定义了 20 个通用方法全部是针对泛型 T也就是你的实体类的。下面是 BaseMapper 里最常用的几个方法部分摘录publicinterfaceBaseMapperTextendsSerializable{// 插入intinsert(Tentity);// 根据 ID 删除intdeleteById(Serializableid);// 根据实体条件删除intdelete(WrapperTwrapper);// 根据 ID 修改只更新非 null 字段intupdateById(Tentity);// 根据条件修改intupdate(Tentity,WrapperTupdateWrapper);// 根据 ID 查询TselectById(Serializableid);// 根据条件查询一条记录TselectOne(WrapperTqueryWrapper);// 查询列表ListTselectList(WrapperTqueryWrapper);// 分页查询IPageTselectPage(IPageTpage,WrapperTqueryWrapper);// 统计数量LongselectCount(WrapperTqueryWrapper);// ... 还有更多比如 selectMaps、selectObjs 等}重点来了当你写extends BaseMapperUserEntity时MyBatis-Plus 会自动把上面这些方法“复制”到你的UserMapper接口里而且这些方法里面的 SQL 都是针对UserEntity这张表自动生成的。所以你才能在 Service 层直接写AutowiredprivateUserMapperuserMapper;publicUsergetUser(Longid){returnuserMapper.selectById(id);// 自动生成 select * from user where id ?}完全不用自己写任何Select、xml或 SQL。3. 它是怎么做到的原理简单版MyBatis-Plus 在项目启动时做了下面几件事扫描所有标注了Mapper的接口发现某个接口extends BaseMapperT通过反射拿到泛型 T这里是 UserEntity根据 UserEntity 的TableName、TableId等注解自动生成对应的 SQL 模板把这些方法动态注入到你的 Mapper 接口的代理对象里MyBatis 的 Mapper 都是动态代理最终效果就是你写了一个空接口但运行时它拥有了 20 个现成方法全是针对你这张表的。4. 为什么这么设计有什么好处好处说明极大减少重复代码以前每个表都要写一堆 selectById、insert、update 的 xml现在不用了统一规范所有表的 CRUD 操作都用同样的方法名代码风格一致开发效率翻倍新增一张表只需写实体类 Mapper 接口空着就行秒级完成 CRUD维护成本降低改表字段只要实体类改了BaseMapper 方法自动适配减少 SQL 错误不用手写 SQL自动生成字段名、表名出错的概率几乎为 05. 什么时候不能依赖 BaseMapperBaseMapper 虽然强大但只适合单表简单 CRUD。以下情况你还是得自己写 SQL 或扩展多表关联查询join复杂条件动态 where批量插入/更新虽然有 saveBatch但性能不如自定义特殊 SQL存储过程、复杂聚合性能极致优化需要索引提示、自定义 join这时候你可以publicinterfaceUserMapperextendsBaseMapperUserEntity{Select(SELECT u.*, d.dept_name FROM user u LEFT JOIN dept d ON u.dept_id d.id WHERE u.id #{id})UserVOselectUserWithDept(Param(id)Longid);}或者用 Wrapper 动态拼接QueryWrapperUserEntitywrappernewQueryWrapper();wrapper.eq(age,18).like(name,梦);ListUserEntitylistuserMapper.selectList(wrapper);6. 总结最核心的几句话extends BaseMapperUserEntity “免费获得 20 个针对 User 表的通用 CRUD 方法”这些方法由 MyBatis-Plus 在启动时自动注入到你的 Mapper 接口你接口可以是空的但运行时它会变得“很丰富”这是 MyBatis-Plus “单表 CRUD 无需写 SQL”的核心魔法适合 80% 的单表操作场景复杂查询再自己写现在你再看到别人项目里写extends BaseMapperUser就知道他们在偷懒但这是官方鼓励的偷懒了