news 2026/6/3 10:19:01

MyBatis-Plus vs MyBatis:全面对比与选型指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MyBatis-Plus vs MyBatis:全面对比与选型指南

MyBatis-Plus vs MyBatis:全面对比与选型指南

前言

MyBatis 是 Java 持久层框架中“灵活派”的代表,而 MyBatis-Plus(简称 MP)在 MyBatis 的基础上做了增强,号称“为简化而生”。很多初学者甚至资深开发者在选型时都会纠结:到底用原生 MyBatis 还是 MyBatis-Plus?

本文将从一个客观、实战的角度,全方位对比两者的区别,包括核心功能、开发效率、SQL 控制、扩展机制以及适用场景,并配以流程图和代码示例,帮助你做出合理的技术决策。


一、一句话定义

框架定义
MyBatis一款优秀的持久层框架,支持定制化 SQL、存储过程以及高级映射,避免了几乎所有的 JDBC 代码和手动设置参数
MyBatis-PlusMyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,旨在简化开发、提高效率,无侵入地提供通用 CRUD、代码生成器、条件构造器等特性。

官方标语:“为简化而生”


二、核心区别概览

保留原生能力

原始JDBC

MyBatis

MyBatis-Plus

增强功能
通用Mapper
条件构造器
分页插件
代码生成器等

区别速览表

对比维度MyBatisMyBatis-Plus
设计理念灵活,SQL 与代码分离简化开发,提高效率(约定大于配置)
单表 CRUD需要手写 SQL 或使用注解内置通用 Mapper,无需写 SQL
条件构造器无,需要手动拼接 SQL 或使用第三方提供QueryWrapper/LambdaQueryWrapper
分页实现手动写方言 SQL 或用 PageHelper内置分页插件,自动生成 count 和分页 SQL
代码生成器无官方支持(可使用 MyBatis Generator)内置强大代码生成器,一键生成 Entity、Mapper、Service、Controller
主键策略手动配置或使用selectKey支持多种主键策略(雪花 ID、自增、UUID 等)
逻辑删除需要手动拦截器或自定义 SQL内置逻辑删除插件,@TableLogic注解
自动填充无,需手动设置 createTime/updateTime内置自动填充功能 (MetaObjectHandler)
性能损耗几乎无微乎其微(增强功能仅在编译/启动时生成代码)
学习曲线较陡,需要掌握 XML 配置、动态 SQL平缓,简单 CRUD 零 SQL
适用场景复杂查询、需要精细控制 SQL、遗留系统快速开发、单表操作多、团队效率优先

三、核心功能详细对比

3.1 单表 CRUD 操作

MyBatis 方式:需要编写 Mapper 接口 + XML 映射文件(或注解),手写 SQL。

<!-- UserMapper.xml --><selectid="selectById"resultType="com.example.User">SELECT * FROM user WHERE id = #{id}</select>

MyBatis-Plus 方式:继承BaseMapper<T>,直接调用内置方法。

publicinterfaceUserMapperextendsBaseMapper<User>{// 无需任何代码,继承即可获得 insert, deleteById, updateById, selectList 等方法}// 使用Useruser=userMapper.selectById(1L);List<User>list=userMapper.selectList(newQueryWrapper<User>().eq("age",18));

3.2 条件构造器(Wrapper)

这是 MyBatis-Plus 最亮眼的功能之一,极大简化了动态查询。

// 查询 name = "张三" 且 age > 20 的用户QueryWrapper<User>wrapper=newQueryWrapper<>();wrapper.eq("name","张三").gt("age",20);List<User>users=userMapper.selectList(wrapper);// Lambda 方式(避免字段名硬编码)LambdaQueryWrapper<User>lambdaWrapper=newLambdaQueryWrapper<>();lambdaWrapper.eq(User::getName,"张三").gt(User::getAge,20);

而在原生 MyBatis 中,你需要手动编写<if>标签或使用第三方条件构造器。

3.3 分页实现

MyBatis:通常结合 PageHelper 分页插件,或手动写 limit 子句。

PageHelper.startPage(1,10);List<User>list=userMapper.selectByCondition(...);PageInfo<User>pageInfo=newPageInfo<>(list);

MyBatis-Plus:内置分页插件,API 更统一。

// 配置分页插件(Spring Boot 自动配置)@BeanpublicMybatisPlusInterceptormybatisPlusInterceptor(){MybatisPlusInterceptorinterceptor=newMybatisPlusInterceptor();interceptor.addInnerInterceptor(newPaginationInnerInterceptor(DbType.MYSQL));returninterceptor;}// 使用Page<User>page=newPage<>(1,10);LambdaQueryWrapper<User>wrapper=newLambdaQueryWrapper<>();wrapper.eq(User::getStatus,1);Page<User>result=userMapper.selectPage(page,wrapper);System.out.println(result.getRecords());// 数据列表System.out.println(result.getTotal());// 总记录数

3.4 代码生成器

MyBatis-Plus 官方提供强大的代码生成器,可一键生成 Entity、Mapper、Service、Controller 等,大幅提升开发效率。

// 示例:AutoGenerator 配置AutoGeneratorgenerator=newAutoGenerator();// 设置数据源、包名、策略等generator.execute();

MyBatis 官方没有类似的生成器,但可以使用第三方的 MyBatis Generator (MBG),不过配置相对繁琐。

3.5 逻辑删除

MyBatis:需要手动拦截 SQL 或每次写 SQL 时加上deleted=0条件。

MyBatis-Plus:在实体类字段上加@TableLogic,然后内置删除方法会自动变为更新逻辑删除字段,查询时自动过滤已删除数据。

@TableLogicprivateIntegerdeleted;

3.6 自动填充(如 create_time, update_time)

MyBatis-Plus 提供了MetaObjectHandler,可以自动填充字段,无需每次手动设置。

@ComponentpublicclassMyMetaObjectHandlerimplementsMetaObjectHandler{@OverridepublicvoidinsertFill(MetaObjectmetaObject){this.strictInsertFill(metaObject,"createTime",LocalDateTime.class,LocalDateTime.now());this.strictInsertFill(metaObject,"updateTime",LocalDateTime.class,LocalDateTime.now());}@OverridepublicvoidupdateFill(MetaObjectmetaObject){this.strictUpdateFill(metaObject,"updateTime",LocalDateTime.class,LocalDateTime.now());}}

四、工作流程对比

MyBatis 执行流程

调用 Mapper 接口方法

MyBatis 动态代理

解析 XML 或注解中的 SQL

参数映射

执行 SQL

结果映射为实体对象

返回结果

MyBatis-Plus 执行流程(增强部分)

通用 CRUD

条件查询

分页

调用 BaseMapper 方法

MP 拦截器

方法类型判断

自动生成 SQL

解析 QueryWrapper

分页插件改写 SQL

交给 MyBatis 执行

返回结果

MP 并不会替换 MyBatis 的核心执行机制,而是在其基础上注入自定义 SQL 片段(通过 SQL 注入器)和拦截器链实现增强。


五、优缺点分析

MyBatis

优点缺点
✅ SQL 与代码分离,精细化控制❌ 单表操作仍需编写重复 SQL
✅ 动态 SQL 强大(if, choose, foreach)❌ 无自带分页、逻辑删除等通用功能
✅ 性能可控,没有额外开销❌ 代码量较大,开发效率相对低
✅ 适合复杂查询、多表联查❌ 需要维护 XML 和接口映射

MyBatis-Plus

优点缺点
单表 CRUD 零 SQL,开发效率高❌ 多表复杂查询依然需要手写 SQL(但可混合使用)
✅ 内置分页、条件构造器、逻辑删除、自动填充❌ 过度依赖 MP 特有 API 可能降低代码可移植性
✅ 代码生成器一键生成基础代码❌ 如果滥用 Wrapper 会导致业务逻辑泄露到数据层
✅ 无侵入,可与 MyBatis 共存❌ 对动态表名、多租户等高级场景需要额外配置
✅ 社区活跃,文档丰富

六、使用场景与选型建议

场景推荐框架理由
快速开发中小型项目(单体/微服务)MyBatis-Plus单表操作多,通用功能节省大量时间
大型复杂企业系统,有资深 SQL 优化人员MyBatis 或MyBatis + MP 混合复杂查询需要精细控制 SQL,MP 仅用于单表
遗留系统改造,不想大量重写只引入 MP 作为辅助MP 无侵入,可以逐步替换单表操作
团队对 MyBatis 非常熟悉且已有成熟封装MyBatis避免引入额外依赖,保持技术栈统一
需要极高性能,对 SQL 执行计划有极致要求MyBatisMP 的自动生成 SQL 可能不是最优(可手动改写)
学习/教学/个人项目MyBatis-Plus快速出活,体验现代开发方式

最佳实践MyBatis-Plus + MyBatis 混合使用。单表操作用 MP,复杂多表查询、存储过程依然写在 XML 中,互不干扰。


七、代码示例:同一个功能两种实现

假设实现:根据用户名和年龄区间查询用户列表,并分页展示

MyBatis 实现

<!-- UserMapper.xml --><selectid="selectByCondition"resultType="User">SELECT * FROM user<where><iftest="name != null and name != ''">AND name = #{name}</if><iftest="minAge != null">AND age >= #{minAge}</if><iftest="maxAge != null">AND age <= #{maxAge}</if></where></select>
// 配合 PageHelperPageHelper.startPage(pageNum,pageSize);List<User>list=userMapper.selectByCondition(name,minAge,maxAge);PageInfo<User>pageInfo=newPageInfo<>(list);

MyBatis-Plus 实现

// 无需修改 XML,直接使用 MPPage<User>page=newPage<>(pageNum,pageSize);LambdaQueryWrapper<User>wrapper=newLambdaQueryWrapper<>();wrapper.eq(StringUtils.hasText(name),User::getName,name).ge(minAge!=null,User::getAge,minAge).le(maxAge!=null,User::getAge,maxAge);Page<User>result=userMapper.selectPage(page,wrapper);

可见 MP 代码量显著减少,且可读性更高。


八、总结

  • MyBatis-Plus 不是 MyBatis 的替代品,而是增强工具。它完全兼容 MyBatis,你可以随时切换回原生方式。
  • 对于单表操作,MP 可以极大提升效率;对于复杂查询,依然推荐手写 SQL 以获得最佳性能和控制力。
  • 选型时建议:中小型项目直接用 MyBatis-Plus;大型项目以 MyBatis 为主,引入 MP 仅用于通用 CRUD。
  • 从长远维护角度看,MP 遵循“约定大于配置”,降低了团队沟通成本,是当前 Java 后端开发的主流选择之一。

官方文档:MyBatis-Plus 官网


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/3 10:18:23

手把手教你用华为USG防火墙的LDAP功能对接AD域,搞定SSLVPN用户认证

华为USG防火墙LDAP对接AD域全流程实战指南在企业网络架构中&#xff0c;统一身份认证是安全运维的核心环节。本文将详细解析如何通过华为USG防火墙的LDAP协议对接Active Directory域服务&#xff0c;实现SSLVPN用户的集中认证管理。不同于市面上常见的理论教程&#xff0c;本指…

作者头像 李华
网站建设 2026/6/3 10:16:06

微软研究院纽约实验室:AI与社会科学交叉创新的数据科学实践

1. 从零到一&#xff1a;微软研究院纽约实验室的诞生与定位2012年5月3日&#xff0c;当微软研究院纽约实验室&#xff08;Microsoft Research New York City&#xff09;正式挂牌成立时&#xff0c;它承载的远不止是科技巨头在曼哈顿设立的一个新办公室。对于当时的研究界&…

作者头像 李华
网站建设 2026/6/3 10:14:10

《企业IT系统无缝集成指南》

工业自动化领域的技术演进始终围绕着两个核心命题展开&#xff0c;一个是硬件控制精度的持续提升&#xff0c;另一个是控制层与业务层的深度融合。当大多数企业还在为不同厂商设备之间的协议不兼容而头疼时&#xff0c;开源控制框架的出现为解决这一问题提供了全新的思路。它不…

作者头像 李华
网站建设 2026/6/3 10:12:40

北光恒电:安捷伦E4418A功率计不开机故障排查与解决方法

安捷伦E4418A是市面常用的射频功率计&#xff0c;凭借测试精准、响应快、稳定性强的特点&#xff0c;广泛应用于通信设备检测、产线功率校准、实验室研发调试等场景。设备使用频次高&#xff0c;长期连续工作、频繁移动摆放、电源电压波动&#xff0c;加上常年使用老化&#xf…

作者头像 李华