Skip to content

死代码与接口一致性——冗余 Mapper 的识别与清理

技术栈:MyBatis + MyBatis-Plus 适合谁读:需要清理 XML 死代码、保持 Mapper 接口与 XML 一一对应的开发者

1. 问题背景

前面几篇讲活着的的问题 SQL。还有一类容易被忽视:死代码,XML 里被注释掉的语句、没人调用的孤儿语句,以及接口与 XML 对不上。它们不执行,却会误导维护者、干扰自查、甚至藏着未被发现的注入点。

2. 死代码是怎么来的

  1. 重构遗留:旧语句被新写法替代后,原作者用 <!-- --> 把旧版注释在旁边备个份,结果一留就是两年
  2. 试错残留:调试时复制一份改着试,试成功的留下来,失败的变成注释躺在那
  3. 接口删了 XML 没删:接口方法改名或删除后,XML 里的 <select id="..."> 没同步删,成了孤儿

危害不在于执行,而在于:

  • 污染自查:扫描工具会把注释里的 ${} 也算进去,虚报风险、分散注意力
  • 误导维护:新人看到两段相似 SQL,分不清哪段在用,改错对象
  • 藏污纳垢:被注释或孤立的语句里可能藏着含 ${} 的注入写法,它暂时没被调用不代表永远安全

3. 接口一致性模型

MyBatis 要求 XML 语句的 id 和 Mapper 接口方法一一对应。这是个双向关系,哪边失衡都会出问题:

text
理想: Mapper 接口方法  <── id 一一对应 ──>  XML 语句

失衡的两种情况:
  · XML 有 / 接口无  → 孤儿语句(多半是死代码)
  · 接口有 / XML 无  → 缺实现(运行报 BindingException)

MyBatis-Plus 的内置方法,selectByIdinsertupdateById 等,由框架运行时提供,本来就没有 XML。自查脚本不认识就会把它误报成缺实现,这类清单必须人工复核或加入忽略清单,不能直接删。

4. 如何识别与清理

4.1 找到死代码

  • 注释死代码:在 XML 中搜 <!-- 包裹的 <select>/<update> 等标签
  • 孤儿语句:把每个 XML id 和接口方法名比对,接口里没有的就是候选

4.2 删除注释死代码

确认新版本已上线、旧版无人引用后,直接删掉整段注释。保留方式应交给 Git 历史,而不是躺在 XML 里。

xml
<!-- 旧代码(已删除):被新实现替代,仅留 Git 历史 -->
<!--
<select id="queryById" resultMap="BaseResultMap">
    select * from operation_log where id = #{id}
</select>
-->

4.3 核实孤儿语句

对每个 XML 有、接口无的 id,全局搜引用:

  • 有调用方但接口签名不匹配 → 修正接口
  • 全仓无引用 → 确认是死代码,删除

4.4 核实缺实现

对每个接口有、XML 无的方法:

  • 是 MyBatis-Plus 内置 → 标记为误报,忽略
  • 是手写的 → 补 XML 实现,否则运行时会 BindingException

4.5 用脚本持续校验

把自查脚本纳入 CI,每次提交都重跑,确保注入点、孤儿语句不新增。

5. 清理对照

现象处理
XML 注释掉的旧语句确认新版在用 → 删注释,Git 留痕
XML 有 / 接口无搜引用,无引用则删 XML
接口有 / XML 无(手写)补 XML 实现
接口有 / XML 无(MP 内置)标记误报,忽略

6. 注意事项

  1. 删之前先全局搜引用。尤其 @Select 注解、Service 里按名调用的地方,确认零引用再删,避免编译或运行报错
  2. MyBatis-Plus 误报要白名单化。把 selectById/insert/... 等内置方法加入脚本忽略清单,减少人工复核噪音
  3. XML 解析测试兜底。删除或改动后,用 SqlSessionFactoryBuilder 加载全部 mapper,验证 XML 无语法错误
  4. 改动同步接口。删 XML 语句时,记得同步删除或保留对应接口方法,保持一一对应

7. 总结

维度改造前改造后
死代码注释残留 + 孤儿语句删除,Git 留痕
注入隐患藏在注释里的 ${}暴露并清除
一致性接口/XML 不匹配噪音大人工复核 + 脚本复跑
维护成本新人分不清在用哪段一份干净、对应明确的 XML

至此,物联网平台 SQL 治理手记完结:从注入、SELECT *、性能反模式到死代码与一致性,每一类都顺着是什么、怎么来的、为什么、危害、如何解决讲清楚。把文中的思路跑起来,你的项目也能拥有一份干净、安全、高性能的 Mapper 层。