分离不等于解耦

发布时间:2026/6/26 3:26:48

分离不等于解耦 一个被说错了二十年的词“SQL 跟 Java 分离”——这个说法在 MyBatis 的推广中被反复提及。听起来很合理SQL 放在 XML 里Java 代码里没有 SQL 字符串这就是解耦。但事实是分离不等于解耦。把两样东西分开存放不等于它们之间的依赖关系消失了。耦合的标准定义耦合是一个模块的变化导致另一个模块必须跟着变化。按这个标准MyBatis 的 SQL 跟 Java 之间存在清晰的耦合链你改了实体类的字段名Java→ XML 里的resultMap要改#{}里的属性名要改if里的test表达式要改你改了方法名Java→ XML 里的id必须同步改你加了查询参数Java→ XML 里的#{xxx}要加参数顺序要对你一动 JavaXML 必动。这叫“跨文件的强耦合”。为什么叫“耦合 Plus”打开任何一个 MyBatis 的 XML 文件你会发现一个事实它里面只有三分之一是 SQL另外三分之二是标签和表达式。1/3 是 SQL 语句本身1/3 是标签if、foreach、where、set、choose1/3 是 OGNL 表达式test、item、index、collection你为了维护这个 XML 文件需要同时处理三种不同的语法SQL 语法、MyBatis 标签语法、OGNL 表达式语法。这三者之间的关系决定了最终生成的 SQL 是否正确。任何一个环节出错整个查询失败。你把一个 Java 方法里本来可以写清楚的逻辑拆成了一个 Java 接口 一个 XML 文件XML 里还要塞进三种不同语法。这不是解耦这是“耦合 Plus”。既然要破就要立如果你把条件写在 Java 里用语义化的方式组织会是什么样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);// 子查询 动态开关}}六个条件六行全是add()和and()没有 XML没有 OGNL没有标签没有三个文件来回跳。你写的每一行都是业务条件没有一行是在伺候框架。条件层的完整实现BaseCondition自动收集参数、自动拼接WHERE、自动管理占位符顺序。你只需要关心“这个条件要不要加”不需要关心“第几个问号对应第几个参数”。RepositorypublicclassOrderDaoextendsBaseDaoOrder{// 完整的联表 SQL直接写在常量里privatestaticfinalStringJOIN_SQL SELECT t.*, u.name user_name, u.phone user_phone FROM bus_order t LEFT JOIN sys_user u ON t.user_id u.id ;// 联表分页——跟单表分页是同一个 APIpublicPageOrderVOpageJoin(OrderCondcond){returnpage(JOIN_SQL,cond,OrderVO.class);}}这才是解耦SQL 稳定部分SELECT/FROM/JOIN写在常量里动态部分WHERE用 Java 语义单元管理二者通过BaseCondition桥接互不干扰。开源地址核心框架https://gitee.com/gao_zhenzhong/simple-dao系统底座https://gitee.com/gao_zhenzhong/simple-dao-starter代码生成器https://gitee.com/gao_zhenzhong/simple-dao-coder实战案例https://gitee.com/gao_zhenzhong/simple-dao-demo

相关新闻