当前位置: 首页 > news >正文

MyBatis-Plus 三种数据库操作方式详解 + 常用方法大全

MyBatis-Plus 三种数据库操作方式详解 + 常用方法大全

在 Java 开发中,MyBatis-Plus(简称 MP)作为 MyBatis 的增强工具,极大简化了数据库操作。MP 提供了多种数据库操作方式,适配不同业务场景,掌握其核心用法能大幅提升开发效率。本文将详细拆解 MP 三种核心操作方式的区别、适用场景,并整理常用方法合集,助力开发者快速上手。

一、核心概念:三种操作方式总览

MP 的数据库操作本质是对 MyBatis 的封装,三种核心方式分别对应不同的使用层级,从简洁到灵活逐步递进:

  • this.*** 方式:基于 MP 提供的 ServiceImpl 基类,直接调用封装好的 CRUD 方法,极简高效。
  • this.baseMapper().*** 方式:通过 Service 访问对应的 Mapper 对象,支持自定义 SQL 和复杂查询,兼顾灵活与性能。
  • service.getBaseMapper().*** 方式跨 Service 获取其他实体的 Mapper,实现跨表/跨模块操作,适用于聚合统计场景。

二、三种操作方式详细解析

2.1 this.*** 方式:极简 CRUD 首选

核心定义

Service 层接口继承 IService<T>,实现类继承 ServiceImpl<Mapper, Entity> 后,可直接通过 this 调用基类封装的 CRUD 方法。

核心特点
  • 无需手动编写 Mapper 方法,开箱即用。
  • 内置参数校验、异常处理和事务支持(需配合 @Transactional)。
  • 支持 Lambda 条件查询,类型安全,避免字段名硬编码。
  • 代码简洁可读性强,开发效率最高。
常用方法合集
// 1. 查询操作
this.getById(id); // 根据 ID 单个查询
this.listByIds(Collections.singletonList(id)); // 批量查询(传入 ID 列表)
this.list(); // 查询所有记录
this.count(); // 统计总记录数
this.getOne(new LambdaQueryChainWrapper<>(lambdaQuery()).eq(Entity::getId, id)); // 条件查询单个(避免返回多个报错)
this.lambdaQuery().eq(Entity::getStatus, 1).ge(Entity::createTime, LocalDateTime.now().minusDays(7)).list(); // Lambda 多条件查询
this.page(new Page<>(1, 10), lambdaQuery().eq(Entity::type, 2)); // 分页查询// 2. 新增/修改操作
this.save(entity); // 单条新增
this.saveBatch(Collections.singletonList(entity), 100); // 批量新增(批量大小 100)
this.saveOrUpdate(entity); // 新增或更新(存在 ID 则更新,否则新增)
this.saveOrUpdateBatch(entities, 100); // 批量新增或更新
this.updateById(entity); // 根据 ID 单条更新
this.lambdaUpdate().set(Entity::getStatus, 0).eq(Entity::id, id).update(); // Lambda 条件更新
this.updateBatchById(entities, 100); // 批量更新(需实体含 ID)// 3. 删除操作
this.removeById(id); // 根据 ID 单条删除
this.removeByIds(Collections.singletonList(id)); // 批量删除(传入 ID 列表)
this.lambdaRemove().eq(Entity::expireTime, LocalDateTime.now()).remove(); // Lambda 条件删除
适用场景
  • 单表基本 CRUD 操作(新增、查询、更新、删除)。
  • 简单条件查询(无复杂联表、聚合需求)。
  • 批量数据处理(批量新增/更新/删除)。
  • 业务逻辑简单,追求开发效率的场景。

2.2 this.baseMapper().*** 方式:复杂查询必备

核心定义

ServiceImpl 基类内置了 baseMapper 属性,对应当前 Service 关联的 Mapper 接口。通过 this.baseMapper() 可直接调用 Mapper 中的方法,包括 MP 自动生成的方法和自定义 SQL 方法。

核心特点
  • 更接近原生 MyBatis,支持自定义 XML/注解 SQL。
  • 可使用 QueryWrapper/LambdaQueryWrapper 构建复杂条件。
  • 支持动态 SQL、结果映射、联表查询等 MyBatis 高级特性。
  • 性能更优,减少中间层封装开销,适合性能敏感场景。
常用方法合集
// 1. 基础查询
this.baseMapper().selectById(id); // 根据 ID 查询
this.baseMapper().selectBatchIds(Collections.singletonList(id)); // 批量查询
this.baseMapper().selectList(new LambdaQueryWrapper<Entity>().eq(Entity::name, "test")); // 条件查询列表
this.baseMapper().selectCount(new LambdaQueryWrapper<Entity>().eq(Entity::status, 1)); // 条件统计
this.baseMapper().selectOne(new LambdaQueryWrapper<Entity>().eq(Entity::id, id)); // 条件查询单个
this.baseMapper().selectPage(new Page<>(1, 10), new LambdaQueryWrapper<Entity>().eq(Entity::type, 2)); // 分页查询// 2. 新增/修改/删除
this.baseMapper().insert(entity); // 单条新增
this.baseMapper().updateById(entity); // 根据 ID 更新
this.baseMapper().update(new LambdaUpdateWrapper<Entity>().set(Entity::status, 0).eq(Entity::id, id)
); // 条件更新
this.baseMapper().deleteById(id); // 根据 ID 删除
this.baseMapper().delete(new LambdaQueryWrapper<Entity>().eq(Entity::expireTime, LocalDateTime.now())); // 条件删除// 3. 自定义方法(需在 Mapper 接口中定义)
this.baseMapper().selectByCustomCondition(param); // 自定义条件查询(如联表、复杂过滤)
this.baseMapper().customUpdate(param); // 自定义更新(如批量更新特定字段)
适用场景
  • 需要自定义 SQL(联表查询、复杂过滤、存储过程调用)。
  • 复杂条件查询(多字段组合、动态条件拼接)。
  • 性能敏感场景(如高频查询、大数据量操作)。
  • 需使用 MyBatis 高级特性(结果映射、动态 SQL、一级缓存优化)。

2.3 service.getBaseMapper().*** 方式:跨模块聚合专用

核心定义

通过注入其他 Service 实例,调用其 getBaseMapper() 方法,直接操作其他实体表的 Mapper,实现跨表/跨模块数据操作。

核心特点
  • 跨 Service 直接操作数据库,绕过 Service 层业务逻辑。
  • 适合多表聚合查询、跨模块统计分析。
  • 灵活性极高,但需谨慎使用,避免破坏业务封装。
  • 事务管理需手动控制,否则可能导致数据一致性问题。
常用方法合集
// 注入其他 Service(如 PictureService)
@Autowired
private PictureService pictureService;// 1. 跨表查询
List<Picture> pictureList = pictureService.getBaseMapper().selectList(new LambdaQueryWrapper<Picture>().eq(Picture::relatedId, entityId).eq(Picture::status, 1)
); // 查询关联图片列表// 2. 聚合统计
List<Map<String, Object>> categoryCount = pictureService.getBaseMapper().selectMaps(new QueryWrapper<Picture>().select("category", "count(*) as count").groupBy("category").having("count(*) > 10")
); // 统计各分类图片数量(大于 10 条)// 3. 跨表分页
IPage<Map<String, Object>> pageResult = pictureService.getBaseMapper().selectMapsPage(new Page<>(1, 10),new QueryWrapper<Picture>().eq("related_type", "article").orderByDesc("create_time")
); // 分页查询指定类型的关联数据// 4. 跨表删除(谨慎使用)
pictureService.getBaseMapper().delete(new LambdaQueryWrapper<Picture>().eq(Picture::relatedId, entityId)
); // 删除关联的图片数据
适用场景
  • 跨模块数据聚合(如统计多个表的关联数据)。
  • 复杂统计分析(多表分组、聚合函数计算)。
  • 需绕过其他 Service 层复杂业务逻辑,直接操作数据库。
  • 临时数据处理、报表生成等场景。
注意事项
  • 破坏 Service 层封装性,可能导致业务逻辑不一致。
  • 事务需手动管理(如使用 @Transactional(propagation = Propagation.REQUIRED))。
  • 增加代码耦合度,后续维护成本升高。
  • 非必要场景避免使用,优先通过 Service 层调用实现跨模块交互。

三、三种方式核心区别对比表

特性this.*** 方式this.baseMapper().*** 方式service.getBaseMapper().*** 方式
使用范围当前实体表当前实体表其他实体表(跨模块/跨表)
代码简洁性极高中等中等
灵活性低(仅支持基础操作)高(支持自定义 SQL)极高(跨表+自定义 SQL)
性能中等(多一层封装)高(接近原生 MyBatis)高(直接操作 Mapper)
业务封装性好(遵循 Service 规范)好(仅操作当前实体)差(绕过其他 Service 逻辑)
事务支持自动(继承 Service 事务)手动(需自行注解)需手动控制(跨 Service 事务)
适用场景简单 CRUD、批量操作复杂查询、性能优化、自定义 SQL跨表聚合、统计分析、临时数据处理

四、MP 常用方法分类汇总

4.1 查询类(高频)

方法签名功能描述所属方式
getById(ID id)根据 ID 查询单条记录this.***
listByIds(Collection<? extends ID> ids)批量查询(ID 列表)this.***
list(Wrapper<T> queryWrapper)条件查询列表this.***/baseMapper
lambdaQuery().eq(...)Lambda 条件查询(类型安全)this.***
selectPage(IPage<T> page, Wrapper<T> queryWrapper)分页查询baseMapper/跨 Service
selectCount(Wrapper<T> queryWrapper)条件统计记录数baseMapper/跨 Service
selectMaps(Wrapper<T> queryWrapper)条件查询返回 Map 列表(无需实体)baseMapper/跨 Service

4.2 新增/修改类(高频)

方法签名功能描述所属方式
save(T entity)单条新增this.***
saveBatch(Collection<T> entityList, int batchSize)批量新增this.***
saveOrUpdate(T entity)新增或更新(根据 ID 判断)this.***
updateById(T entity)根据 ID 更新三种方式均支持
lambdaUpdate().set(...).eq(...)Lambda 条件更新this.***
update(Wrapper<T> updateWrapper)条件更新(非 ID 字段)baseMapper/跨 Service
updateBatchById(Collection<T> entityList, int batchSize)批量更新this.***

4.3 删除类(高频)

方法签名功能描述所属方式
removeById(ID id)根据 ID 删除this.***
removeByIds(Collection<? extends ID> ids)批量删除(ID 列表)this.***
lambdaRemove().eq(...)Lambda 条件删除this.***
delete(Wrapper<T> queryWrapper)条件删除baseMapper/跨 Service

五、最佳实践建议

  1. 优先使用 this.*** 方式:单表基础 CRUD 场景首选,代码简洁、维护成本低,且内置异常处理和事务支持。
  2. 复杂场景用 this.baseMapper().***:需要自定义 SQL、联表查询或性能优化时,切换到此方式,兼顾灵活性和性能。
  3. 谨慎使用跨 Service 方式:仅在跨表聚合、统计分析等必要场景使用,使用时需注意事务管理和代码耦合问题。
  4. 保持代码一致性:同一项目中尽量统一操作方式,避免混用导致可读性下降(如统一用 this.*** 处理简单 CRUD,baseMapper 处理复杂查询)。
  5. 善用 Lambda 表达式:优先使用 LambdaQueryWrapper/LambdaUpdateWrapper,避免字段名硬编码,减少因字段修改导致的 Bug。
  6. 批量操作指定批次大小:使用 saveBatch/updateBatchById 时,指定合理的批次大小(如 100-500),避免一次性操作过多数据导致数据库压力过大。

总结

MyBatis-Plus 的三种数据库操作方式各有侧重,从极简的 this.*** 到灵活的 baseMapper,再到跨模块的 service.getBaseMapper(),覆盖了从简单 CRUD 到复杂聚合的全场景需求。掌握其核心区别和适用场景,结合常用方法合集,能大幅提升数据库操作效率。

如果本文对你有帮助,欢迎点赞、收藏、转发~ 若需补充特定场景的用法示例(如联表查询、动态 SQL 实战),可在评论区留言!

http://www.dtcms.com/a/618396.html

相关文章:

  • C++鼠标滑块轨迹 - 解决“京东滑块验证码”
  • 中山做网站的wordpress官网流量统计插件下载
  • 出口贸易公司网站怎么做煤棚网架加工厂
  • 如何自学建网站国内免备案网站空间
  • VS CMake报错Vbin32缺失?三步搞定
  • 用Rust实现一个简易的rsync(远程文件同步)工具
  • 如何用ps做照片模板下载网站哪里有网站建设
  • 【MIT-OS6.S081作业1.5】Lab1-utilities xargs
  • 文档抽取技术:通过OCR、NLP和机器学习技术,将非结构化的合同、发票等文档转化为结构化数据
  • 网站调研怎样做装修公司设计图
  • 西安网站制作优化顺德网站建设itshunde
  • 46 修改购物车数据
  • VUE的创建与配置
  • 44_FastMCP 2.x 中文文档之FastMCP集成:AWS Cognito 指南
  • 旅游网站建设市场分析公司就两个开发
  • 武昌手机网站59网一起做网站
  • 对抗拖库 —— Web 前端慢加密
  • BMAD-METHOD 开发方法论实践指南
  • MVC 模型
  • 【图像处理基石】如何从色彩的角度分析一张图是否是好图?
  • 从 1.56% 到 62.9%:SFT 推理微调优化实战
  • Java 实战:图书管理系统(ArrayList 应用)
  • 网站建设客户资料收集清单普洱茶网站建设
  • 网站反链数淮南网站建设报价
  • Week 25: 深度学习补遗:多模态学习
  • 广汉市建设局网站做外发的网站
  • html5商城网站开发h5制作的网站
  • 传统机器学习算法:基于手工特征
  • OpenCV(二十七):中值滤波
  • 建设部网站实名制举报学校网站规划