尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

给 Spring JDBC 正名

给 Spring JDBC 正名
📅 发布时间:2026/6/24 10:26:41

它被误解了多年,却是持久层唯一的事实标准

一、三分天下的历史格局

Spring JDBC 和 iBatis(MyBatis 的前身)几乎同时代诞生,Hibernate 也差不多同时期崛起。二十年前,持久层领域确实是三分天下的局面。

但二十年后,格局发生了明显变化:

  • Hibernate被 MyBatis 蚕食了大部分市场。因为 Hibernate 太重——对象映射、关系管理、缓存机制、代理生成,每一步都在增加黑盒。遇到复杂查询,你往往退回原生 SQL,框架的存在意义被打了个折扣。
  • MyBatis蚕食的是 Hibernate 的市场,而不是 Spring JDBC 的市场。因为 iBatis/MyBatis 本质上是一个封装层——它做的事情,Spring JDBC 本来就能做,只是需要多写几行样板代码。真正用惯 Spring JDBC 的人,没有必要跳到另一个也要写 SQL 的框架里。
  • Spring JDBC的市场被蚕食的比例远没有舆论说的那么大。它一直是那个“被低估但从未消失”的选项。

今天的实际使用比例,做一个粗略估算:

  • 直接显式使用 Spring JDBC:约 20%
  • 使用 MyBatis 及其衍生品:约 60-70%
  • 其他(JPA/Hibernate、jOOQ、原生 JDBC、自研框架等):约 10-20%

Spring JDBC 这 20% 的使用者,几乎不在社交媒体上发声。

二、为什么互联网上讨论的全是 MyBatis?

不是因为 MyBatis 更好,是因为它坑多。

越多人踩坑,越多人提问,越多人写博客教怎么填坑。问题越多,讨论越多,社区看起来越“繁荣”。

Spring JDBC 没坑,所以没人讨论它。

没有 N+1 问题需要规避,没有懒加载需要配置,没有一级二级缓存需要理解,没有拦截器需要学习。你写什么 SQL,它就执行什么 SQL。你遇到问题,问题就是 SQL 本身的问题。

所以你没有写博客的必要。你只需要去查 SQL 语法,去查执行计划,去加索引。这些不需要一个 Spring JDBC 专属的社区来帮你。

一个不需要填坑的框架,天然没有社区热度。

三、Spring JDBC 是持久层唯一的事实标准

不管你的项目用的是 MyBatis、JPA、Hibernate 还是其他持久层框架,只要你跑在 Spring 生态里,底层一定有一层 Spring JDBC。

数据源管理、事务管理、连接池、多数据源、分库分表、分布式事务——这些能力全部建立在 Spring JDBC 之上。它不是“可选组件”,它是 Spring 生态中关系型数据库访问的基础设施,是事实标准。

MyBatis 要在 Spring 生态里用,得额外加一个 MyBatis-Spring 桥接层。JPA 要在 Spring 生态里用,得额外配EntityManagerFactory和JpaTransactionManager。

Spring JDBC 不需要适配任何人,别人需要适配它。

这就是基础设施和插件的区别。

四、白盒:全程透明,全程可控

Spring JDBC 的行为是透明的。

你写SELECT * FROM user WHERE id = ?,它就执行SELECT * FROM user WHERE id = ?。框架不帮你改字段名,不帮你加额外的查询条件,不趁你不注意发一条额外的 SQL。

它的执行链路最多三层:JdbcTemplate→PreparedStatement→ 数据库。没有动态代理,没有拦截器链,没有黑盒翻译。

白盒的最大优势,不在于“你看到 SQL 长什么样”,而在于“你可以零成本介入 SQL 的生命周期”。

你想加数据权限、多租户过滤、动态表名、审计日志——直接在 Java 里用if和字符串拼接就能完成。

Stringsql="SELECT * FROM user WHERE 1=1";if(需要数据权限){sql+=" AND school_id = "+currentUser.getSchoolId();}jdbcTemplate.query(sql,...);

不需要学拦截器接口,不需要操作MetaObject,不需要理解BoundSql的内部结构。

全程白盒 = 你随时有介入点,且介入成本就是写一行 Java 代码。

五、异常:你定位的是数据库错误,不是框架错误

Spring JDBC 的异常体系极其精简。数据库报什么错,你就看到什么错。

SQL 语法错误 →SQLException。字段不存在 →SQLException。主键冲突 →SQLException。不需要额外学 31 类异常的含义。

对比:MyBatis 源码里有几十种异常类,BindingException、ExecutorException、TooManyResultsException、ReflectionException、CacheException……你花时间学的不是“数据库出了什么问题”,而是“框架的哪一层又炸了”。

Spring JDBC 不制造异常,它只传递异常。一个不会自己制造异常的框架,调试成本天然就低。

六、性能:没有中间层,就没有损耗

Spring JDBC 的JdbcTemplate是 Spring 执行 SQL 的最后一层。到了它这里,参数已经绑定了,SQL 已经完整了,剩下的就是发给数据库。

不用经过MapperProxy的代理调用,不用经过SqlSession的会话管理,不用经过Executor的缓存判断,不用经过StatementHandler的预编译包装,不用经过ResultSetHandler的结果集二次封装。

多一层抽象,就多一层损耗。多一层黑盒,就多一层排查成本。

Spring JDBC 的链路最短,性能天花板最高。

七、扩展成本:Spring AOP vs MyBatis 拦截器

Spring JDBC 的扩展,用 Spring AOP 就能完成:

@Around("execution(* com.example..*Dao.*(..))")publicObjectinjectDataAuth(ProceedingJoinPointpjp)throwsThrowable{// 拿到 SQL,追加条件,继续执行}

不需要学框架内部的拦截器接口,不需要操作框架内部对象,就是 Spring 原生的 AOP 能力。

对比 MyBatis 的扩展成本:

MyBatis 也留了口子——拦截器。但这个口子的门槛极高。

你要写一个数据权限拦截器,需要:

  • 实现Interceptor接口
  • 在intercept()方法里拿到Invocation对象
  • 从Invocation里取出MappedStatement和BoundSql
  • 用反射或者MetaObject修改BoundSql里的 SQL
  • 还要处理分页、缓存等边缘情况

光是把 SQL 取出来就要 5 行以上的反射代码。想改参数?还要处理ParameterHandler。想改返回值?还要处理ResultSetHandler。

在没有大语言模型的时代,这套东西能挡住 80% 的程序员。你写 20 行代码,可能连业务的边都摸不着。

这就是为什么 MyBatis 有庞大的插件市场:分页插件、数据权限插件、多租户插件、脱敏插件……不是因为 MyBatis 生态好,而是因为它的扩展口成本太高,大部分人自己写不出来,只能等社区出方案。

这不是生态繁荣,这是缺口清单。

八、MyBatis 社区的本质:受害者联盟

MyBatis 的 SQL 编写是白盒的,你可以在 XML 里看到完整的 SQL 文本。但 SQL 的执行是黑盒的,你无法在它发往数据库之前直接介入它。你想加一个条件,必须绕过框架的限制。

这个矛盾催生了大量插件。分页、数据权限、脱敏、多租户……每一个都是因为框架本身没有提供直接的能力,只能靠社区插件来补。

所以 MyBatis 社区的繁荣,本质上是“受害者联盟”的自我强化。大家聚在一起不是因为“这玩意儿真好用”,而是因为“这个问题你怎么解决的?那个坑你怎么填的?”。

越多人用,就有越多人踩坑;越多人踩坑,就有越多人写博客教填坑;越多人教填坑,看起来就越“繁荣”。

Spring JDBC 不需要这个繁荣。因为全程白盒,全部可控,不需要插件来补缺口。一个不需要补坑的框架,天然没有“繁荣”的社区。但它的沉默,不代表它不存在。

九、哪些场景在用 Spring JDBC?

互联网上讨论最多的永远是 MyBatis,但 Spring JDBC 在多个重要场景里一直在稳定使用:

企业内部自研框架:很多中大型企业内部都有自研的持久层封装,全部基于 Spring JDBC。连接池、数据源、分布式事务这些基础设施,没有谁会重新发明一遍。

银行、金融系统:对黑盒零容忍。SQL 必须完全可控,执行路径必须完全清晰,异常必须直接透传。Spring JDBC 是这类场景最顺理成章的选择。

报表场景:SQL 本身就是核心资产。复杂报表的 SQL 往往是 DBA 专门优化过的,直接拿过来用就行,不需要被任何框架再翻译一遍。

性能敏感场景:执行链路最短,损耗最小。少一层抽象就少一层开销。

在这些场景里,Spring JDBC 不是“备选方案”,是“最佳选项”。

十、用 Spring JDBC 的人为什么不说话?

有一个事实需要面对:使用 Spring JDBC 的人在技术社区的声量很低。

不是因为用的人少,而是因为他们被长期“鄙视”。“你怎么还在用 Spring JDBC?太原始了。”“这么老的 API 还在用?”时间久了,他们就习惯了沉默。

他们不在 CSDN 写“Spring JDBC 真香”,因为他们觉得这是常识,不需要讨论。他们也不跟人争论 MyBatis 好还是 Spring JDBC 好,因为他们知道争论没有意义——项目跑得好好的,不需要证明给谁看。

沉默不代表不存在。20% 的直接使用率,加上所有基于 Spring JDBC 封装的自研框架,实际覆盖的项目比例远超舆论所反映的数字。

十一、那么,Spring JDBC 的“繁琐”是什么?

客观承认:Spring JDBC 在使用层面确实存在繁琐性。

因为它是 JDBC 的本质——它不可能提供单表对象化,更不可能自动简化条件拼接。JdbcTemplate本身就是极其简洁的 API,但在实际业务中,你仍然需要写大量的:

StringBuildersql=newStringBuilder("SELECT * FROM user WHERE 1=1");List<Object>params=newArrayList<>();if(name!=null&&!name.isEmpty()){sql.append(" AND name = ?");params.add(name);}if(age!=null){sql.append(" AND age = ?");params.add(age);}// ... 更多条件Object[]paramArray=params.toArray();

这是样板代码。不是框架的问题,是你需要但不该自己写的东西。

Spring JDBC 没有做错什么,它只是“干净”到了没有帮你简化这一步的程度。

所以,你需要的是一个工具类,而不是一个新的框架。

十二、三个方法,覆盖 90% 的重复工作

你只需要封装三个方法:

  • addCondition():拼接条件 + 自动收集参数
  • addIf():条件判断 + 自动决定是否拼接
  • page():分页 + 自动处理 COUNT 和 LIMIT

全工程复用,覆盖 90% 以上的业务场景。

你不需要 Mapper 接口,不需要 XML 文件,不需要 namespace,不需要几十个标签,不需要上百个属性,不需要十几个注解,不需要 31 类异常。

你只需要能写 SQL,能调方法。

好,我把第十三节完整重写,把BaseCondition代码示例嵌入进去,让读者直观看到“条件层到底长什么样”。


十三、SimpleDAO 就是那个工具类的增强版

前面说了,Spring JDBC 的繁琐在于条件拼接和参数管理。你真正需要的不是另一个框架,而是一个能把样板代码收走的工具类。

SimpleDAO 就是这样一个工具类。

它的核心设计是:把 SQL 的稳定部分(SELECT、FROM、JOIN)留给你手写,把高动态部分(WHERE、排序、分页)封装成可复用的 Java 语义单元。

举个例子,你在 Spring JDBC 里要写一个带 5 个条件的查询,需要手动拼接字符串、手动管理参数列表。在 SimpleDAO 里,你只需要继承BaseCondition,在addCondition()方法里一行一个条件:

publicclassUserCondextendsBaseCondition{privateStringname;privateIntegerageMin;privateIntegerageMax;privateObject[]ids;privateBooleanhasOrder;@OverrideprotectedvoidaddCondition(){and("name LIKE",name,3);// 模糊查询and("age >=",ageMin);// 大于and("age <=",ageMax);// 小于in("id",ids);// IN 集合add("AND EXISTS (SELECT 1 FROM order WHERE user_id = t.id)",hasOrder);// 子查询 + 动态开关}}

六个条件,六行代码。没有if判空,没有字符串拼接,没有params.add()。条件成立就拼接,不成立就跳过,参数自动收集,顺序自动对齐。

这个UserCond可以同时服务于单表查询、联表查询、子查询、报表统计——条件层不关心你查的是几张表,它只关心“这个条件要不要加”。

再看它怎么跟 SQL 配合。你写一个联表查询,SQL 写在常量里,条件用UserCond传进去:

@RepositorypublicclassUserDaoextendsBaseDao<User>{privatestaticfinalStringJOIN_SQL=""" SELECT t.*, o.order_name FROM sys_user t LEFT JOIN bus_order o ON t.id = o.user_id """;publicPage<UserVO>pageJoin(UserCondcond){returnpage(JOIN_SQL,cond,UserVO.class);}}

看到区别了吗?联表查询的代码量跟单表查询没有任何区别。你不需要学新的 API,不需要配额外的映射,不需要装插件。SQL 是你写的,条件是 Java 对象,分页是page()方法。

这就是把样板代码收走之后的样子。你写的每一行代码都在表达业务意图,没有一行是在伺候框架。

SimpleDAO 在 Spring JDBC 基础上做的增强,用一张表列清楚:

你原本需要手写的事SimpleDAO 做了什么
条件拼接 + 参数管理add()、and()、in()一行搞定,参数自动收集
单表 CRUD继承BaseDao,零代码,零 SQL
分页page()一行,自动处理 COUNT 和 LIMIT
联表查询完整 SQL 手写,list()自动映射 VO
数据权限Spring AOP 切面注入
逻辑删除delete()自动处理
审计字段save()、update()自动填充

SimpleDAO 没有替换 Spring JDBC 的任何能力,它只是把你本来要手写的样板代码自动化了。你不需要离开 Spring JDBC 的生态,因为 SimpleDAO 就长在它上面。

十四、知识寿命

用 Spring JDBC,你学的是 JDBC、SQL、事务边界、连接池管理。这些知识二十年不变。你去任何一个 Java 项目,这套东西依然管用。

用 MyBatis,你学的是 XML 标签、OGNL 表达式、拦截器机制。换个框架,这套知识就作废了。

用 JPA,你学的是 JPQL 语法、Criteria API、实体生命周期管理。换个语言或框架,这套知识也作废了。

Spring JDBC 给你的不是“框架知识”,是“数据库开发的基础认知”。这笔账,你自己算。

开源地址

  1. 核心框架:https://gitee.com/gao_zhenzhong/simple-dao
  2. 系统底座:https://gitee.com/gao_zhenzhong/simple-dao-starter
  3. 代码生成器:https://gitee.com/gao_zhenzhong/simple-dao-coder
  4. 实战案例:https://gitee.com/gao_zhenzhong/simple-dao-demo

写在最后

Spring JDBC 被误解了二十年。它不是什么“原始的工具”,它是持久层唯一的事实标准。

MyBatis 社区的繁荣是“受害者联盟”的自我强化。Spring JDBC 不需要这种繁荣,因为它是完整的、自洽的、全程透明的。一个不需要补坑的框架,自然没有那种靠填坑撑起来的社区热度。

SimpleDAO 只是帮 Spring JDBC 补上了样板代码那层薄薄的手套,不需要你离开这个标准。

你在 Spring JDBC 里写的每一行代码,都是在巩固你二十年不变的知识积累。这笔账,自己算。

相关新闻

  • 水管漏水检测数据集基础信息表YOLO模型如何训练这个数据集
  • AISMM认证体系深度解码(2026奇点大会官方背书版):覆盖5类岗位、4级能力模型、12项实操考核标准
  • AISMM认证全流程图谱:从报名→能力测评→实战沙盒→伦理审查→发证,98.7%通过率背后的5个隐藏关键节点

最新新闻

  • Claude Opus 4.8 动态工作流:从提示词到意图建模的范式升级
  • ChatGPT国内分层服务技术本质解析:Go/Plus/Pro/Business底层架构与接入避坑指南
  • Claude Code 省钱实战:Token 消耗优化的四大工程方法
  • OpenClaw 配置指南:飞书×Claude 网关调试与生产部署
  • MySQL 4.0.26 官方源码包:含完整编译脚本、命令行工具源码及 man 手册模板
  • SOUL.md:用纯Markdown为Hermes智能体注入人格

日新闻

  • 终极指南:如何用shadPS4在电脑上免费畅玩PS4游戏
  • 打造个性化Instagram Clone:主题定制与用户体验优化技巧
  • 未来展望:RoseTTAFold-All-Atom的发展路线图与社区支持资源汇总

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号