跳到主要内容

规则嵌套

在 dbVisitor 中,规则之间可以相互嵌套。解析引擎在递归遍历过程中遵循 "深度优先" 的策略。 利用这一特性,您可以组合不同的规则来实现参数预处理、条件组合等复杂逻辑,而无需在 Java 代码中编写额外的处理逻辑。

基本用法

嵌套语法的形式是在一个规则的参数或内容部分,再次调用另一个规则 @{...}

@{ 外层规则名, ..., @{ 内层规则名, ... } ... }

例如,将用户输入的明文密码转换为 MD5 后再拼接到 SQL 中。

-- 原始参数 :pwd = '123456'
@{and, password = @{md5, :pwd}}

执行流程:

  1. 内层求值@{md5, :pwd} 被执行,计算 MD5 值并将其注册为 SQL 参数(生成占位符 ?)。
  2. 外层求值:内层生成的占位符文本参与外层 @{and} 规则的拼接。
  3. 最终 SQLAND password = ? (实际执行时参数值为 MD5后的字符串)。

嵌套层级

dbVisitor 对嵌套层级没有硬性限制,但出于可读性和维护性考虑,建议不要嵌套过深(超过 3 层)。

下面的例子展示了如何结合 @{and}@{case}@{md5} 实现复杂的动态逻辑:

-- 场景:根据 encryptMode 参数决定是否对密码进行 MD5 加密查询
-- 且整个查询条件被包裹在 AND 中
-- 注意:@{case} 的第一个参数是 OGNL 表达式,直接引用变量名即可(无需冒号)
@{and, password = @{case, encryptMode,
@{when, true, @{md5, :pwd}}, -- 模式开启:使用 MD5 处理并绑定参数
@{else, :pwd} -- 模式关闭:直接绑定原始参数
}
}

解析过程

  1. 分发逻辑@{case} 根据 encryptMode 的值进行匹配。
  2. 值计算
    • 若匹配 true,执行 @{when} 内的 @{md5, :pwd},计算 MD5 并生成参数占位符 ?
    • 否则(@{else}),执行内含的 :pwd,同样生成参数占位符 ?
  3. 最终拼接@{and} 将结果拼接到 SQL:AND password = ?

注意事项

避免单引号包裹规则

请勿在规则外层包裹单引号,尤其是当规则(如 @{md5}, @{uuid})本身是用来生成参数占位符的时候。

  • 正确pwd = @{md5, :val} -> 生成 pwd = ? (通过 PreparedStatement 传值,安全且正确)
  • 错误pwd = '@{md5, :val}' -> 生成 pwd = '?' (被视为字符串字面量,导致功能失效)
执行顺序

规则总是先计算内层,再计算外层。如果内层规则因为条件不满足而未生成任何内容(返回空字符串),外层规则接收到的就是空字符串。