规则嵌套
在 dbVisitor 中,规则之间可以相互嵌套。解析引擎在递归遍历过程中遵循 "深度优先" 的策略。 利用这一特性,您可以组合不同的规则来实现参数预处理、条件组合等复杂逻辑,而无需在 Java 代码中编写额外的处理逻辑。
基本用法
嵌套语法的形式是在一个规则的参数或内容部分,再次调用另一个规则 @{...}。
@{ 外层规则名, ..., @{ 内层规则名, ... } ... }
示例 1:AND + MD5
将用户输入的明文密码转换为 MD5 后再拼接到 SQL 中。
-- 原始参数 :pwd = '123456'
@{and, password = @{md5, :pwd}}
执行流程:
- 内层求值:
@{md5, :pwd}被执行,计算 MD5 值并将其注册为 SQL 参数(生成占位符?)。 - 外层求值:内层生成的占位符文本参与外层
@{and}规则的拼接。 - 最终 SQL:
AND password = ?(实际执行时参数值为 MD5 后的字符串)。
示例 2:AND + IN
@{in} 规则不会自动补全 AND/OR 前缀,因此需要嵌套在 @{and} 中使用。
select * from users where status = :status
@{and, id IN @{in, :ids}}
生成的 SQL (ids=[1,2,3])
select * from users where status = ? and id IN (?, ?, ?)
嵌套层级
dbVisitor 对嵌套层级没有硬性限制,但出于可读性和维护性考虑,建议不要嵌套过深(超过 3 层)。
下面的例子展示了如何结合 @{and}、@{case} 和 @{md5} 实现复杂的动态 逻辑:
-- 场景:根据 encryptMode 参数决定是否对密码进行 MD5 加密查询
-- 且整个查询条件被包裹在 AND 中
-- 注意:@{case} 的第一个参数是 OGNL 表达式,直接引用变量名即可(无需冒号)
@{and, password = @{case, encryptMode,
@{when, true, @{md5, :pwd}}, -- 模式开启:使用 MD5 处理并绑定参数
@{else, :pwd} -- 模式关闭:直接绑定原始参数
}
}
解析过程:
- 分发逻辑:
@{case}根据encryptMode的值进行匹配。 - 值计算:
- 若匹配
true,执行@{when}内的@{md5, :pwd},计算 MD5 并生成参数占位符?。 - 否则(
@{else}),执行内含的:pwd,同样生成参数占位符?。
- 若匹配
- 最终拼接:
@{and}将结果拼接到 SQL:AND password = ?。
注意事项
避免单引号包裹规则
请勿在规则外层包裹单引号,尤其是当规则(如 @{md5}, @{uuid})本身是用来生成参数占位符的时候。
- 正确:
pwd = @{md5, :val}-> 生成pwd = ?(通过 PreparedStatement 传值,安全且正确) - 错误:
pwd = '@{md5, :val}'-> 生成pwd = '?'(被视为字符串字面量,导致功能失效)
执行顺序
规则总是先计算内层,再计算外层。如果内层规则因为条件不满足而未生成任何内容(返回空字符串),外层规则接收到的就是空字符串。