资讯动态

深入 MyBatis Mapper XML 审查规则:open-code-review 如何检测 SQL 注入、性能瓶颈与逻辑错误

发布时间:2026/9/13 14:10:08 来源:尧图企业网站定制
深入 MyBatis Mapper XML 审查规则open-code-review 如何检测 SQL 注入、性能瓶颈与逻辑错误【免费下载链接】open-code-reviewFast, efficient, battle-tested at Alibabas scale. Hybrid architecture code review tool: deterministic pipelines LLM Agent, precise line-level comments, built-in multi-language ruleset (NPE, thread-safety, XSS, SQL injection), OpenAI Anthropic compatible.项目地址: https://gitcode.com/GitHub_Trending/op/open-code-reviewopen-code-reviewOCR内置了一套面向 MyBatis 风格 Mapper/DAO XML 文件的专用审查规则mapper_dao_xml.md当 diff 中出现文件名形如*mapper*.xml或*dao*.xml的改动时这套规则会作为{{system_rule}}注入 LLM 审查提示词指导模型聚焦拼写、SQL 逻辑、性能与注入安全四类问题。读完本文你将掌握该规则的全部检查项、判定边界哪些该报、哪些不该报以及如何用ocr rules check验证规则命中、用rule.json自定义团队专属的 Mapper 审查规范。一、规则何时生效路径模式匹配机制Mapper/DAO 规则由内置的系统规则映射表system_rules.json声明触发条件**/*{mapper,dao}*.xml: mapper_dao_xml.md即路径中任意位置包含mapper或dao且以.xml结尾的文件如src/main/resources/mapper/UserMapper.xml、com/example/dao/UserDao.xml都会命中该规则。匹配逻辑位于 system_rules.go 的resolveDetail匹配使用bmatcuk/doublestar/v4实现完整 glob 语法**可跨目录递归匹配花括号模式如{mapper,dao}会先由expandBraces展开为**/*mapper*.xml与**/*dao*.xml两个独立模式再逐一匹配见 system_rules.go匹配是大小写不敏感的路径在匹配前会被统一小写化先匹配先赢path_rule_map保持声明顺序第一个命中的模式决定规则文本没有任何模式命中时回退到default.md。该规则与内置审查review模式配合时mapper_dao_xml.md的规则文本会作为{{system_rule}}占位符注入主任务提示词main_task_user.md成为 LLM 对该文件的审查清单。从源码结构看规则解析层composedResolver采用四层优先级--rule自定义 项目.opencodereview/rule.json 全局~/.opencodereview/rule.json 内置系统规则。因此mapper_dao_xml.md是兜底的系统层规则任何一层用户规则命中都会覆盖或合并它详见第五节。二、审查维度总览该规则将 Mapper XML 审查划分为四个递进维度维度关注点风险等级拼写错误检测SQL 关键字、方法名与id的一致性、动态 SQL 属性名低级但高频SQL 逻辑错误检测WHERE 条件、JOIN 条件、if求值、语法中高风险关键性能问题全表扫描、无分页大查询、重复子查询高风险SQL 注入安全风险${}字符串拼接、LIKE 拼接最高风险四个维度共同构成基础质量 → 逻辑正确 → 性能 → 安全的完整审查链下文逐一拆解。三、明显的拼写错误检测拼写错误是 Mapper XML 中最隐蔽也最常见的低级问题模型需重点检查三类SQL 关键字的拼写错误如SELCT、FOMR、WHRER、UPDAT等。这类错误在编译期不会被 Java 侧拦截XML 字符串通常运行时才解析会导致线上 SQL 解析直接失败。Mapper 接口方法名与 XMLid属性不一致MyBatis 通过命名空间 id将接口方法与 SQL 语句绑定mapper namespacecom.example.UserMapper中的idselectByUserId需与接口方法User selectByUserId(...)对应。拼写错位会产生经典的Invalid bound statement (not found)运行时异常是 MyBatis 项目最高发的故障之一。动态 SQL 标签内属性名的拼写错误如if testuserName ! null中test条件引用的字段名与参数对象属性不一致如写成userNmae条件将恒为 false 或直接求值失败。这类问题规则要求明显Obvious才报即存在明确拼写差异、有足够证据支撑时才提交评论避免因大小写约定差异或缩写造成误报。四、SQL 逻辑错误检测逻辑层是 Mapper 审查的核心规则细分四个子类4.1 条件错误Condition ErrorsWHERE 条件中逻辑运算符的误用典型如 AND/OR 混淆。最常见的场景是多重条件中 OR 与 AND 的优先级陷阱select idselectByStatus resultTypeUser SELECT * FROM user WHERE status #{status} OR name #{name} AND deleted 0 !-- 实际语义是 status#{status} OR (name#{name} AND deleted0) -- /select模型需要判断条件组合是否与业务意图一致警惕括号缺失导致的语义漂移。4.2 JOIN 条件错误JOIN Condition Errors两类典型问题JOIN 使用的字段不正确如ON a.user_id b.id写成ON a.user_id b.user_id两表关联字段本身不对称缺少必要的 JOIN 条件多表连接只写了部分关联条件形成笛卡尔积或结果集膨胀。规则建议结合表结构上下文判断确认关联字段在两侧语义对等。4.3 动态 SQL 逻辑错误Dynamic SQL Logic Errorsif test条件求值错误典型如if testuser ! null !-- 只判断了对象非空未判断内部字段 -- AND name #{user.name} /if if testtype 1 !-- 类型检查错误Integer 与字符串/其他数值比较 -- AND category #{type} /if规则重点关注null 检查错误对象空而字段访问、! null与 null写反、![CDATA[ ]]中转义问题与类型检查错误数值类型比较、test中字符串字面量缺少引号等。4.4 SQL 语法错误SQL Syntax Errors明显的语法问题缺少逗号如 SELECT 列清单中漏逗号、括号不匹配未闭合的(或foreach中IN (#{...})的括号层级错误、多余或缺失关键字等。这类错误通常导致整条 SQL 无法执行属于必须拦截的硬伤。五、关键性能问题检测性能问题是 Mapper 审查中报得最有价值的部分规则明确三个高价值信号5.1 全表扫描风险Full Table Scan Risk缺少 WHERE 条件的查询尤其是SELECT *类语句例如select idselectAllUsers resultTypeUser SELECT * FROM user /select当selectAll类方法被业务循环调用或接口暴露给前端时可能造成灾难性慢查询。规则建议核查该方法是否存在误用风险必要时提示增加条件或加索引。5.2 无分页的大查询Large Query Without Pagination可能返回大数据集却没有LIMIT/ 分页的查询select idselectOrders resultTypeOrder SELECT * FROM orders WHERE status #{status} !-- 缺少 LIMIT 或分页参数 -- /select生产系统最常见的 OOM / 慢 SQL 源头之一。模型需结合业务场景判断返回量级建议补充分页。5.3 重复子查询Repeated Subqueries同一子查询在多个位置重复使用SELECT * FROM order o WHERE o.user_id IN (SELECT id FROM user WHERE dept_id #{deptId}) AND o.total (SELECT AVG(total) FROM order WHERE user_id IN (SELECT id FROM user WHERE dept_id #{deptId}))规则建议提取到临时表或优化 SQL 结构如JOIN派生表、公共 CTE避免数据库重复执行同一子查询。六、SQL 注入安全风险检测重点报与不报的边界这是 Mapper 审查中最关键的维度规则对该报与不该报划出了清晰边界。6.1 应当报告的真实安全风险直接字符串拼接${}拼接用户输入参数select idselectByKeyword resultTypeUser SELECT * FROM user WHERE name LIKE %${keyword}% !-- 危险${} 直接拼入 SQL -- /select select idselectByTable resultTypejava.util.Map SELECT * FROM ${tableName} !-- 危险表名/排序字段经 ${} 拼接 -- /selectMyBatis 中#{}是预编译占位符底层PreparedStatement参数绑定而${}是字符串直接替换——用户输入原样拼入 SQL 文本可被构造出 OR 11等注入载荷。规则要求凡是${}拼接了任何可能受用户控制的输入查询参数、请求字段、外部配置一律作为注入风险上报。LIKE 查询拼接select idsearch resultTypeUser SELECT * FROM user WHERE name LIKE % #{keyword} % !-- 某些数据库方言下仍是拼接 -- /select直接拼接 LIKE 条件而非通过安全参数绑定 数据库层转义同样属于注入面规则要求改用手动拼接通配符但保留参数绑定或使用数据库内置的LIKE转义函数select idsearch resultTypeUser SELECT * FROM user WHERE name LIKE CONCAT(%, #{keyword}, %) /select6.2 不应当报告的安全用法#{}参数绑定的正确使用MyBatis 自动对#{}参数做转义预编译机制保证安全不报静态 SQL 语句不含动态参数的固定 SQL无${}、无拼接不报。这一边界定义极其重要它直接遏制了看到${}一律报警的误报倾向——${}拼接常量如固定的表名白名单、内部常量并不构成注入面只有拼接用户可控输入才构成风险。模型必须结合上下文判断${}的数据来源。6.3 审查原则Review Principles规则在最后给出五条总原则规范整体审查行为聚焦关键问题优先报告可能导致数据损坏、性能劣化或安全风险的核心问题不纠缠琐碎细节考虑实际执行效率结合 SQL 的实际执行代价及其对数据库性能的影响优先识别生产故障级问题把可能引发线上故障的缺陷放在最前面上下文不明时保持谨慎无法确定 SQL 的完整执行上下文时选择忽略而非误报要求充分证据只有存在明确问题证据时才上报宁漏报、勿误报宁可漏掉真实问题也要保持高精度避免大量噪音评论淹没真正的问题。七、从规则文本到审查评论规则的运行时路径理解规则如何跑起来有助于判断其在实际 review 中的行为。核心调用链如下加载LoadDefault()system_rules.go通过go:embed内嵌system_rules.json与rule_docs/*把mapper_dao_xml.md文本读入PathRules解析NewResolver()system_rules.go按 custom → project → global → system 组装四层composedResolvermapper_dao_xml.md位于最底层的 system 层命中对每个 diff 文件路径调用Resolve()命中**/*{mapper,dao}*.xml后返回规则文本注入规则文本填入 main_task_user.md 的{{system_rule}}随完整 diff 一起交给审查 Agent审查 Agent 的角色与行为约束见 main_task_system.md产出Agent 依据规则逐条核验确认问题后调用code_comment工具生成行级评论。此外规则文本参与了运行清单manifest的rule_config_sha256哈希计算CanonicalConfig见 system_rules.go因此修改规则内容会改变每次运行的配置指纹便于审计本次审查用的哪一版规则。八、验证与调试用ocr rules check确认命中当你不确定某个 Mapper XML 文件是否命中该规则时使用rules check子命令实现在 rules_cmd.go# 检查系统内置规则是否命中 $ ocr rules check src/main/resources/mapper/UserMapper.xml File: src/main/resources/mapper/UserMapper.xml Source: System built-in Pattern: **/*{mapper,dao}*.xml Rule: ──────────────────────────────────────── …mapper_dao_xml.md 的完整文本… ────────────────────────────────────────# 结合 --rule 自定义规则文件一起验证优先级 $ ocr rules check --rule custom.json src/main/resources/dao/UserDao.xml File: src/main/resources/dao/UserDao.xml Source: Custom (--rule) Pattern: **/*mapper*.xml Rule: ──────────────────────────────────────── …你的自定义规则… ────────────────────────────────────────该命令输出命中的来源层级Source与匹配模式Pattern是排查规则为何没按预期生效的第一手段。规则测试在 system_rules_test.go 中也有直接证据src/main/resources/mapper/usermapper.xml与src/main/resources/dao/userdao.xml两条路径均断言命中包含 SQL Logic Error Detection 的规则文本——即本规则mapper_dao_xml.md的核心章节。九、自定义团队级 Mapper 审查规则内置规则是全语言兜底团队可在项目根目录创建.opencodereview/rule.json覆盖或强化 Mapper 审查格式定义见 system_rules.go 的ProjectRule结构{ rules: [ { path: **/*mapper*.xml, rule: Check SQL for injection risks, missing parameter binding, and unclosed XML tags. } ] }三个进阶要点默认替换 vs 合并默认用户规则替换系统规则如需保留mapper_dao_xml.md的内容同时追加团队要求给条目加merge_system_rule: true此时规则文本会合并为System-Specific Rules User-Specific Rules两段合并实现在 system_rules.go--rule单次覆盖ocr review --rule ./security-only.json可对单个 PR 做只审查注入风险的专项检查如path: **/*{mapper,dao}*.xml 仅注入检查规则绕过项目与全局层include/exclude 过滤rule.json顶层的include/excludeglob 用于过滤文件exclude优先级最高例如排除生成目录的 Mapperexclude: [**/generated/**]。规则文件的rule字段支持直接书写文本也支持引用.md文件路径仅允许.md/.txt/.markdown且受 512KB 大小与仓库目录越界校验约束见 system_rules.go。十、小结与进一步阅读mapper_dao_xml.md用四层维度拼写 → SQL 逻辑 → 性能 → 注入安全加五条审查原则为 MyBatis Mapper/DAO XML 审查建立了高精度、低误报的行为规范其核心设计哲学是宁漏报、勿误报——只有证据充分的问题才上报把真实缺陷从噪音中捞出来。规则本体internal/config/rules/rule_docs/mapper_dao_xml.md路径映射internal/config/rules/system_rules.json解析与合并实现internal/config/rules/system_rules.go命中测试internal/config/rules/system_rules_test.go审查 Agent 行为约束internal/config/template/prompts/main_task_system.md完整规则体系文档pages/src/content/docs/en/review-rules.md【免费下载链接】open-code-reviewFast, efficient, battle-tested at Alibabas scale. Hybrid architecture code review tool: deterministic pipelines LLM Agent, precise line-level comments, built-in multi-language ruleset (NPE, thread-safety, XSS, SQL injection), OpenAI Anthropic compatible.项目地址: https://gitcode.com/GitHub_Trending/op/open-code-review创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价