MyBatis 大清算:技术路径依赖下的集体认知失调
前言:全网统一的谎言,和无人敢戳破的真相
打开任何Java教程、面试手册、企业技术规范,都会出现一套标准答案式话术:
MyBatis 轻量、灵活、解耦SQL、动态SQL强大、结果映射便捷、生态丰富,是Java后端持久层最佳实践。
二十年来,这套说辞被无数培训机构、博客、面试官、项目团队反复复制、传播、神化。 所有人默认它是技术最优解,默认Spring JdbcTemplate简陋、原始、不好用。
但我们经过多轮纯逻辑推演、同场景代码对写、落地场景核验、跨语言范式对比、逐条推翻社区优势,得出一个颠覆行业认知的终极结论:
MyBatis 除了市场运营、生态垄断、历史惯性、群众基础这些非技术维度极其成功之外,在纯软件工程技术层面,一无是处。
它没有真正的简化、没有真正的解耦、没有真正的封装、没有真正的性能优势。 它所有的“优势”,全是认知偏差、话术包装、路径依赖、补丁代偿。
本文,完成二十年以来,对MyBatis第一次彻底、完整、无死角的技术大清算。
第一章 范式错位:全世界都在进步,只有Java停留在模板时代
我们先跳出Java生态,站在全球编程语言持久层设计范式的上帝视角。
一个极其讽刺、却无人深究的事实:
全世界所有主流编程语言,没有一个效仿MyBatis的XML模板拼SQL模式。
- Go:database/sql、sqlx —— 原生SQL字符串,显式优于隐式
- Rust:sqlx、Diesel —— 字符串SQL + 编译期校验
- Python:psycopg2、SQLAlchemy —— 宿主语言拼接SQL
- C#:Dapper、EF Core —— 纯字符串SQL / LINQ
- Node.js:pg、knex —— 字符串SQL、查询构建器
- PHP、Ruby、Kotlin:全部放弃模板生成SQL
唯独Java生态,将「XML模板+OGNL表达式动态拼接SQL」奉为行业标准。
这不是先进,这是技术孤岛、历史遗留、范式掉队。
历史真相:MyBatis 是模板狂热时代的畸形产物
2000年代中后期,JSP、Velocity、FreeMarker模板引擎统治文本生成领域。 行业普遍思维:动态文本,就该用模板引擎生成。
于是设计者理所当然认为:HTML可以模板生成,SQL也可以。
但行业二十年演进已经彻底证明: 模板引擎承载业务逻辑,是错误的软件工程方向。
前端已经完成彻底去模板化迭代: JSP模板渲染 → Vue/React JS原生逻辑渲染 逻辑归宿主语言,彻底抛弃弱逻辑标记语言
而后端Java持久层,原地踏步二十年。
SQL结构极简、规则固定、变更频率极低,完全不需要模板引擎。 MyBatis为了拼接几句WHERE条件,强行堆砌一整套重型体系: XML解析引擎、OGNL表达式、数十种动态标签、ResultMap映射、Mapper动态代理、专属拦截器、插件生命周期。
杀鸡用航天飞机,只为切一颗西瓜。
第二章 逐条清算:MyBatis 所有宣传优势,全部证伪
我们不凭感觉、不随大流、不看社区软文。 以Spring JdbcTemplate(NamedParameterJdbcTemplate+BeanPropertyRowMapper)为公正参照系,逐条死刑宣判。
1. 谎言一:SQL与代码分离,解耦优雅
真相:物理分离,逻辑超级耦合,耦合度MAX
真正的解耦:一方变更,不影响另一方。 MyBatis真实绑定关系: Mapper接口方法名、XML的id、OGNL参数、SQL字段、ResultMap映射、实体属性 六向强绑定。
改参数、改字段、改方法名、改返回值,必须多文件同步修改。
反观Spring Jdbc: 所有SQL、参数、映射、组装逻辑,全部内聚在同一个Java方法。 单一职责、高内聚、低耦合,修改只改一处。
所谓“解耦”,是行业最大的话术骗局。 真实情况是:把完整内聚的逻辑,人为撕碎拆分到两个文件三个位置,制造人为耦合。
2. 谎言二:强大的动态SQL,简化开发
真相:换壳拼接,零简化,多一套垃圾语法
MyBatis的if、where、foreach、trim、choose: 本质就是用残缺的XML标记语言,模拟Java最基础的if/for逻辑。
Java是图灵完备语言,字符串处理、判断、循环、截取、正则无所不能。 XML是弱逻辑标记语言,功能残缺、语法诡异、限制极多。
开发者本来写一行Java三元表达式、一行循环就能解决的事, 被迫写多行XML标签、嵌套结构、OGNL表达式,代码量只增不减,难度只增不减。
没有任何简化,只有语法驯化和心智负担。
3. 谎言三:ResultMap、collection/association 复杂对象映射简化开发
彻底清算:该特性鸡肋至极,现实无人正经使用
行业真实开发现状: 90%以上MyBatis开发者根本不会、也不用collection/association。
所有人遇到一对多、多对多场景,统一采用标准方案: 两次单表全量查询 + 内存Stream分组组装
这也是Spring Jdbc的标准最优实践:
而MyBatis的嵌套标签,只有两个下场:
所谓复杂映射优势,是完全脱离生产的纸面优势。
我们实战代码对写最终定论: 同等一对多场景,Spring Jdbc代码更干净、更稳定、更好维护、零坑。
4. 谎言四:内置缓存体系提升性能
真相:生产100%禁用,负优化设计
MyBatis一级缓存、二级缓存: 存在分布式失效、事务不一致、脏读、多Mapper共享冲突等致命问题。
所有正规企业项目,上线第一件事:关闭MyBatis全部缓存。
行业统一方案:废弃框架自带缓存,统一使用Spring Cache+Redis。 该特性完全无落地价值,纯冗余设计。
5. 谎言五:TypeHandler 全局类型转换更便捷
真相:脱裤子放屁,零收益多负担
数据库基础类型天然与Java类型一一对应。 JSON、文本、特殊字段,Jackson即可全局统一序列化。
MyBatis TypeHandler: 需要单独写类、注册配置、适配XML,多一套专属规范,多一套学习成本。 收益为0,负担拉满。
6. 谎言六:插件生态丰富,扩展强大
终极真相:生态繁荣 = 框架设计缺陷的补丁代偿 这是本次清算最核心、最颠覆行业认知的结论:
MyBatis所有热门插件:PageHelper、多租户插件、数据权限插件、通用Mapper、MyBatis-Plus 没有一个是锦上添花,全部是雪中补坑。
因为MyBatis执行链路是完全黑盒: SQL渲染、参数填充、语句生成全部封闭在底层源码。 开发者无法在上层直接修改SQL字符串,无法极简扩展。
想要实现分页、多租户、逻辑删除、数据权限, 必须编写复杂的底层拦截器,侵入框架生命周期,门槛极高、极易冲突、极难调试。
反观Spring Jdbc: 全链路白盒,SQL就是普通Java字符串。 分页、条件追加、租户过滤、逻辑删除,只是简单的字符串前后缀拼接。
无需插件、无需拦截器、无需底层侵入, 几十行通用工具类,永久全局复用,成本低到令人发指。
MyBatis的生态强大,不是优势,是架构垃圾的最好证明。
7. 谎言七:Mapper动态代理简化开发,无需写DAO实现
彻底推翻:伪接口、伪抽象、负优化设计
接口的软件工程核心意义:多实现、多替换、解耦扩展。
而MyBatis的Mapper接口:
这不是简化开发,这是制造仪式感、制造黑盒、制造耦合。
Spring Jdbc 普通DAO类,透明、可调试、可扩展、可叠加业务逻辑,碾压式胜出。
第三章 调试与维护:MyBatis 是开发者的噩梦,Spring Jdbc 是绝对通透
1. Spring Jdbc:全白盒、可断点、可逐行追踪
SQL是Java普通字符串, 动态拼接逻辑是原生Java代码, 参数Map、实体映射全程可见。
写错任何一个字符、任何一个条件,断点直接定位,秒级排错。
2. MyBatis:全黑盒、无调试、靠猜、靠日志
XML动态SQL渲染、OGNL解析、标签执行、参数填充, 全部隐藏在底层源码,业务层无法断点跟踪。
所有语法错误、条件漏拼、映射错位、参数不匹配, 编译期零报错,运行时爆炸。
排错只能依靠打印日志、逐行注释XML、猜底层执行逻辑。
二十年了,MyBatis 从未解决调试难的底层硬伤。
第四章 认知失调:行业二十年的双标与自我洗脑
为什么所有人都默认MyBatis更好? 本质是全行业大范围认知失调 + 信息茧房 + 双标评判。
明明是一模一样的字符串拼接行为, 两套完全相反的评价标准。
选择性遗忘坑 所有人天天踩坑:N+1、笛卡尔积、XML报错、映射错位、代理异常 但所有人依旧背书:MyBatis是最佳实践。
低估Spring Jdbc 99%开发者从未系统学过 NamedParameterJdbcTemplate、BeanPropertyRowMapper、内存组装、条件封装。 仅凭老旧刻板印象,判定其简陋难用,属于纯粹偏见。
第五章 终极对比:没有任何例外,Spring Jdbc 全面碾压
经过我们全部场景逐一对标、代码实写、逻辑复盘,最终铁律:
MyBatis 在纯技术层面,没有任何一个场景具备真实优势。
第六章 客观公允:承认 MyBatis 的所有非技术优势
我们不偏激、不抹黑,公正承认:MyBatis 非常成功。 但它的成功,与技术设计无关。
以上,全部是产品运营、市场垄断、历史惯性优势,不属于软件工程技术优势。
终章 时代翻篇:去模板化,是全行业统一归宿
前端已经彻底完成去模板化: JSP模板退场,JS原生逻辑统一天下。
后端持久层的去模板化,是必然的历史趋势: MyBatis XML模板拼SQL(旧弯路) → Java原生逻辑+SQL字符串薄封装(正统正道)
Go、Rust、Python、C# 早已验证十年以上: SQL就该是字符串,逻辑就该归宿主语言,不需要任何中间模板层。
MyBatis 不是行业标准, 它只是Java生态封闭性催生的、长达二十年的时代误会。
最终定论(全文终极清算)
方向错了,跑得再快,都是弯路。 二十年模板执念,该彻底清算、彻底翻篇了。
我们不是只做了一个核心框架,而是一整套完整的生产级解决方案:
| 核心框架 | simple-dao | Spring JDBC Ultra 核心内核 |
| 系统底座 | simple-dao-starter | 内置 RBAC 权限、用户/部门/字典/菜单管理,开箱即用 |
| 代码生成器 | simple-dao-coder | 全栈代码生成,四套模板覆盖常规业务 |
| 实战案例 | simple-dao-demo | 8 个可运行 Demo,从入门到高阶全覆盖 |
Spring JDBC Ultra 已在生产环境稳定运行 3 年+,支撑日均百万级请求,服务十余家企业客户。
如果你厌倦了复杂框架的折磨,相信简单的力量,欢迎来试试。
技术可以更简单,开发可以更愉快,程序员可以早下班。


