MyBatis与MyBatis-Plus核心对比与实战指南
1. MyBatis与MyBatis-Plus的前世今生作为Java开发者持久层框架的选择直接影响着开发效率和系统性能。十年前我刚入行时项目组还在用原始的JDBC手写SQL直到遇见了MyBatis这个半自动化ORM框架才真正体会到什么是高效的数据库操作。而MyBatis-Plus的出现则让我们的CRUD操作变得更加优雅。MyBatis最初是Apache的一个开源项目iBatis2010年迁移到Google Code后改名为MyBatis。它的核心设计理念是SQL与代码分离通过XML或注解配置SQL语句再通过简单的映射关系将结果集转换为Java对象。这种设计既保留了SQL的灵活性又避免了JDBC的样板代码。MyBatis-Plus简称MP则是国内团队在MyBatis基础上开发的增强工具它保留了MyBatis的所有特性同时内置了大量常用功能。就像给你的MyBatis装上了涡轮增压器让常规开发效率直接翻倍。2. 核心架构对比理解设计哲学差异2.1 MyBatis的核心组件MyBatis的架构设计非常清晰主要包含以下几个核心组件SqlSessionFactory每个MyBatis应用的核心通过它创建SqlSessionSqlSession包含执行SQL命令的所有方法Mapper接口定义数据库操作方法Mapper XML编写SQL语句的地方ExecutorSQL语句的实际执行者这种设计让SQL与Java代码解耦但也意味着开发者需要编写更多配置代码。比如一个简单的用户查询我们需要定义UserMapper接口编写对应的Mapper XML文件在XML中编写SELECT语句配置结果映射public interface UserMapper { User selectById(Long id); }!-- UserMapper.xml -- select idselectById resultTypecom.example.User SELECT * FROM user WHERE id #{id} /select2.2 MyBatis-Plus的增强设计MP在MyBatis基础上做了几项关键增强通用Mapper内置常用CRUD方法无需编写XML条件构造器通过链式调用构建查询条件代码生成器自动生成Entity、Mapper、Service等代码分页插件内置物理分页支持性能分析插件帮助优化SQL性能同样的用户查询在MP中可以简化为User user userMapper.selectById(1L);或者使用Lambda表达式ListUser users userMapper.selectList( Wrappers.UserlambdaQuery() .eq(User::getName, 张三) .gt(User::getAge, 18) );注意虽然MP提供了便利但它并不是要替代MyBatis而是在其基础上提供更多开箱即用的功能。复杂的SQL仍然可以通过MyBatis原生方式实现。3. 实战对比从CRUD到高级特性3.1 基础CRUD操作MyBatis方式 每个CRUD操作都需要在Mapper接口定义方法并在XML中编写SQL// 接口定义 public interface UserMapper { int insert(User user); int update(User user); int delete(Long id); User selectById(Long id); ListUser selectAll(); }!-- XML配置 -- insert idinsert parameterTypecom.example.User INSERT INTO user(name, age) VALUES(#{name}, #{age}) /insertMyBatis-Plus方式 MP的BaseMapper已经内置了这些方法public interface UserMapper extends BaseMapperUser { // 无需定义基础CRUD方法 } // 使用示例 userMapper.insert(user); userMapper.updateById(user); userMapper.deleteById(1L); User user userMapper.selectById(1L);3.2 条件查询对比MyBatis动态SQL 需要手写XML中的 、 等标签select idselectByCondition resultTypeUser SELECT * FROM user where if testname ! null AND name #{name} /if if testage ! null AND age #{age} /if /where /selectMyBatis-Plus条件构造器 使用Java代码构建查询条件QueryWrapperUser wrapper new QueryWrapper(); wrapper.eq(name, 张三) .gt(age, 18) .orderByDesc(create_time); ListUser users userMapper.selectList(wrapper);或者更优雅的Lambda方式ListUser users userMapper.selectList( Wrappers.UserlambdaQuery() .eq(User::getName, 张三) .gt(User::getAge, 18) .orderByDesc(User::getCreateTime) );3.3 分页实现差异MyBatis分页 需要手动处理分页逻辑或者使用PageHelper插件// 使用PageHelper PageHelper.startPage(1, 10); ListUser users userMapper.selectAll(); PageInfoUser pageInfo new PageInfo(users);MyBatis-Plus分页 内置分页插件配置后直接使用// 配置分页插件 Configuration public class MybatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return interceptor; } } // 使用分页 PageUser page new Page(1, 10); PageUser result userMapper.selectPage(page, null);4. 高级特性与实战技巧4.1 代码生成器的妙用MP的代码生成器可以大幅减少重复劳动。以下是一个典型配置FastAutoGenerator.create(jdbc:mysql://localhost:3306/test, root, password) .globalConfig(builder - { builder.author(baomidou) // 设置作者 .outputDir(D://); // 指定输出目录 }) .packageConfig(builder - { builder.parent(com.example) // 设置父包名 .moduleName(system) // 设置模块名 }) .strategyConfig(builder - { builder.addInclude(user, role) // 设置需要生成的表名 .entityBuilder() .enableLombok() // 启用Lombok .controllerBuilder() .enableRestStyle(); // 开启RestController }) .execute();运行后会生成Entity、Mapper、Service、Controller等全套代码特别是对于管理后台这类CRUD密集的系统能节省70%以上的重复代码编写时间。4.2 乐观锁实现并发控制MP提供了优雅的乐观锁实现方式在表中添加version字段在Entity中添加Version注解配置乐观锁插件Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; } // Entity类 public class User { Version private Integer version; // 其他字段... }更新时会自动检查版本号User user userMapper.selectById(1L); user.setName(新名字); userMapper.updateById(user); // 会自动带上version条件4.3 多租户架构实现对于SaaS系统MP提供了多租户支持Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() { Override public String getTenantIdColumn() { return tenant_id; } Override public Expression getTenantId() { return new LongValue(1L); // 实际应从上下文中获取 } Override public boolean ignoreTable(String tableName) { return !user.equalsIgnoreCase(tableName); // 指定哪些表需要过滤 } })); return interceptor; }配置后所有相关SQL都会自动加上tenant_id条件避免跨租户数据泄露。5. 性能优化与最佳实践5.1 SQL性能分析MP的SQL性能分析插件可以帮助发现慢查询Bean public PerformanceInterceptor performanceInterceptor() { PerformanceInterceptor interceptor new PerformanceInterceptor(); interceptor.setMaxTime(1000); // 设置SQL执行最大时间(ms)超过会抛出异常 interceptor.setFormat(true); // 格式化SQL return interceptor; }警告生产环境慎用此插件建议只在开发测试环境开启因为它会带来额外的性能开销。5.2 逻辑删除的最佳实践逻辑删除是业务系统的常见需求MP提供了优雅的实现在表中添加deleted字段在Entity中添加TableLogic注解配置逻辑删除值// Entity类 public class User { TableLogic private Integer deleted; // 其他字段... } // 配置(可选默认0未删除1已删除) mybatis-plus: global-config: db-config: logic-delete-value: 1 logic-not-delete-value: 0配置后deleteById方法会自动变为逻辑删除查询也会自动过滤已删除数据。5.3 枚举类型的优雅处理MP支持将数据库字段与Java枚举自动转换// 定义枚举 public enum Gender { MALE(1, 男), FEMALE(2, 女); EnumValue // 标记数据库存储的值 private final int code; private final String desc; // 构造方法、getter等 } // Entity类 public class User { private Gender gender; // 其他字段... }这样gender字段在数据库中存储的是1或2而在Java对象中会自动转换为对应的枚举值。6. 常见问题与解决方案6.1 如何混用MP和原生MyBatisMP完全兼容原生MyBatis可以在同一个项目中混合使用public interface UserMapper extends BaseMapperUser { // MP提供的方法 // 自定义的MyBatis方法 Select(SELECT * FROM user WHERE name #{name}) ListUser selectByName(String name); // XML配置的方法 ListUser selectComplexQuery(UserQuery query); }对应的XML文件仍然可以正常使用MP不会影响原生功能。6.2 多表联查如何处理MP主要针对单表操作对于复杂联查建议使用Select注解编写SQL使用XML配置复杂SQL对于一对多查询可以使用Results注解Select(SELECT u.*, r.role_name FROM user u LEFT JOIN user_role ur ON u.id ur.user_id LEFT JOIN role r ON ur.role_id r.id WHERE u.id #{id}) Results({ Result(property id, column id), Result(property roles, column id, many Many(select com.example.mapper.RoleMapper.selectByUserId)) }) User selectUserWithRoles(Long id);6.3 如何自定义ID生成策略MP默认提供了几种ID生成策略// Entity类 public class User { TableId(type IdType.AUTO) // 数据库自增 private Long id; // 其他字段... }可选的IdType包括AUTO数据库ID自增NONE未设置主键INPUT用户输入IDASSIGN_ID分配ID(默认雪花算法)ASSIGN_UUID分配UUID也可以自定义生成器public class CustomIdGenerator implements IdentifierGenerator { Override public Number nextId(Object entity) { // 实现自定义ID生成逻辑 return IdWorker.getId(); } } // 配置 Bean public IdentifierGenerator idGenerator() { return new CustomIdGenerator(); }7. 项目选型建议经过多年的实战经验我总结出以下选型建议新项目直接使用MyBatis-Plus它能显著提升开发效率特别是管理后台类项目老项目如果已经是MyBatis项目可以逐步引入MP功能两者完全兼容简单CRUD优先使用MP提供的方法减少重复代码复杂SQL仍然使用MyBatis原生方式保持灵活性性能敏感注意MP某些特性(如分页)的性能影响必要时可回归原生方式在实际项目中我通常会这样组织代码结构src/main/java ├── com.example │ ├── config │ │ └── MybatisPlusConfig.java // MP配置 │ ├── controller │ ├── entity // 实体类 │ ├── mapper // 继承BaseMapper │ ├── service │ │ ├── impl │ │ └── IService.java // 可选扩展通用Service │ └── vo // 视图对象 src/main/resources ├── mapper │ ├── UserMapper.xml // 复杂SQL的XML配置这种结构既利用了MP的便利性又保留了MyBatis的灵活性能够适应大多数业务场景。

相关新闻

开源AI模型本地部署:工程化挑战与实战优化策略

开源AI模型本地部署:工程化挑战与实战优化策略

1. 开源模型到底在面临什么考验 如果你最近在关注本地部署的AI模型,可能会注意到一个现象:新出的开源模型越来越多,但真正能在普通机器上稳定跑起来的却没几个。这就是标题里说的“生存考验”的核心——不是技术不够好,而是落地门…

2026/7/22 7:53:17阅读更多 →
Windows Docker Desktop磁盘空间清理终极指南

Windows Docker Desktop磁盘空间清理终极指南

1. 问题背景与核心痛点在Windows系统上使用Docker Desktop的开发人员,经常会遇到一个棘手问题:随着容器和镜像的频繁使用,系统磁盘空间会被大量占用,即使执行了常规清理命令,空间也无法有效释放。这背后的根本原因在于…

2026/7/22 7:51:17阅读更多 →
Linux下x64架构虚拟机开发指南

Linux下x64架构虚拟机开发指南

1. 为什么要在Linux下开发x64架构虚拟机? 十年前我第一次接触虚拟机时,被VMware Workstation的"魔法"深深震撼——它居然能在Windows系统里运行另一个完整的操作系统。后来才知道,这种技术背后是CPU硬件虚拟化指令集和虚拟机监控程…

2026/7/22 7:51:17阅读更多 →
传统灯展与现代光影技术的融合与创新

传统灯展与现代光影技术的融合与创新

1. 记忆中的灯展:一场光影交织的视觉盛宴 小时候第一次看灯展的场景至今历历在目。那是个寒冷的冬夜,父母牵着我的手走进公园,迎面而来的是一片璀璨夺目的光影世界。巨大的龙形灯组足有三层楼高,龙眼处安装的旋转射灯让整条龙仿佛…

2026/7/22 8:49:26阅读更多 →
YUM包管理工具:原理、配置与企业级应用

YUM包管理工具:原理、配置与企业级应用

1. YUM包管理工具概述YUM(Yellowdog Updater Modified)是Linux系统中基于RPM包管理系统的命令行工具,主要用于自动化软件包的安装、更新和依赖管理。作为RHEL/CentOS等发行版的核心组件,它通过软件仓库机制简化了系统管理员的工作…

2026/7/22 8:49:26阅读更多 →
2025年AI写作工具市场分析与核心平台评测

2025年AI写作工具市场分析与核心平台评测

1. 2025届AI写作工具市场现状当前AI写作领域正经历着从辅助工具向生产力核心的转变。根据行业跟踪数据显示,2025年全球AI写作市场规模预计突破120亿美元,年复合增长率保持在35%以上。这种爆发式增长主要源于三个关键因素:大语言模型技术的突破…

2026/7/22 8:49:26阅读更多 →
Python与AI结合实现智能文档生成实战

Python与AI结合实现智能文档生成实战

1. 项目概述:Python与AI结合的文档生成实战这个实训项目瞄准了一个职场刚需痛点——如何高效产出专业文档。利用Python调用AI大模型接口,我们可以实现求职简历、实习报告、活动策划案等常见文档的智能生成。不同于传统模板填充方式,AI生成能根…

2026/7/22 8:49:26阅读更多 →
AI代码重构技术:原理、实践与工具链解析

AI代码重构技术:原理、实践与工具链解析

1. 项目概述:AI重构旧代码的技术本质在软件开发领域,代码重构一直是提升系统可维护性的重要手段。传统重构需要开发者手动分析代码结构、识别坏味道、设计改进方案并实施修改,整个过程耗时耗力且容易引入新问题。而AI技术的介入正在彻底改变这…

2026/7/22 8:49:26阅读更多 →
Python游戏开发三剑客实战指南:从Arcade快速入门到项目发布

Python游戏开发三剑客实战指南:从Arcade快速入门到项目发布

1. 项目概述:为什么是“三剑客”?如果你对用Python做游戏开发感兴趣,可能已经听过Pygame、Pyglet和Arcade这三个名字。它们常被圈内人戏称为“Python游戏开发三剑客”。这可不是随便叫的,背后反映的是它们在生态位、上手难度和社区…

2026/7/22 8:47:26阅读更多 →
Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/22 0:53:59阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/22 0:53:59阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/22 0:53:59阅读更多 →
中小企业小程序开发公司怎么选:预算、上手和售后避坑指南

中小企业小程序开发公司怎么选:预算、上手和售后避坑指南

中小企业做小程序,最常见的矛盾是预算有限,但又不希望功能太单薄;没有技术团队,但又希望后续能自己运营;想快速上线,又担心隐性收费和售后失联。选型时如果只看“低价套餐”或“案例数量”,很容…

2026/7/22 0:01:17阅读更多 →
GEO优化如何沉淀长期内容资产?广拓时代谈AI搜索时代的内容ROI

GEO优化如何沉淀长期内容资产?广拓时代谈AI搜索时代的内容ROI

企业做营销,最怕钱花完了,资产没有留下。 效果广告能带来一段时间的曝光,但预算停止后,流量往往也随之停止。短视频内容可能在几天内冲高,也可能很快沉下去。AI搜索时代,企业需要重新思考一个问题&#xff…

2026/7/22 0:01:17阅读更多 →
Agent 终态判定:何时该停止思考、给出最终回复

Agent 终态判定:何时该停止思考、给出最终回复

Agent 终态判定:何时该停止思考、给出最终回复 一、你的 Agent 在"再想想"的循环里绕了 12 轮,用户已经关窗口了 Agent 与人最大的区别是:人知道什么时候该停下来给答案,Agent 会一直"想"下去。你给 Agent 接…

2026/7/22 0:01:17阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/21 22:53:50阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/21 18:53:30阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/21 18:53:30阅读更多 →