7.3 Rule Nesting
In dbVisitor, rules can be nested within each other. The outer rule determines whether to parse its content; inner rules are not all evaluated in advance. Using this feature, you can combine different rules to implement parameter pre-processing, conditional combinations, and other complex logic without writing additional processing logic in Java code.
Basic Usage
The nested syntax takes the form of calling another rule @{...} within the parameter or content part of a rule.
@{ OuterRuleName, ..., @{ InnerRuleName, ... } ... }
Example 1: AND + MD5
This example only illustrates parameter handling for existing MD5 fields. Do not use MD5 for new password storage.
-- Original parameter :pwd = '123456'
@{and, password = @{md5, :pwd}}
Execution Flow:
- Inner Evaluation:
@{md5, :pwd}is executed, calculating the MD5 value and registering it as a SQL parameter (generates placeholder?). - Outer Evaluation: The placeholder text generated by the inner layer participates in the splicing of the outer
@{and}rule. - Final SQL:
AND password = ?(The actual parameter value executed is the MD5 hashed string).
Example 2: AND + IN
The @{in} rule does not automatically complete AND/OR prefixes, so it needs to be nested inside @{and}.
select * from users where status = :status
@{and, id IN @{in, :ids}}
select * from users where status = ? and id IN (?, ?, ?)
Nesting Levels
dbVisitor does not strictly limit the nesting level, but for readability and maintainability, it is recommended not to nest too deeply (more than 3 levels).
The following example shows how to combine @{and}, @{case}, and @{md5} to implement complex dynamic logic:
-- Scenario: Decide whether to query with MD5 hashing based on the encryptMode parameter
-- And the entire query condition is wrapped in AND
-- Note: The first parameter of @{case} is an OGNL expression, referencing the variable name directly (no colon needed)
@{and, password = @{case, encryptMode,
@{when, true, @{md5, :pwd}}, -- Mode on: Use MD5 processing and bind parameters
@{else, :pwd} -- Mode off: Bind original parameters directly
}
}
Parsing Process:
- Dispatch Logic:
@{case}matches based on the value ofencryptMode. - Value Calculation:
- If matches
true, execute@{when}containing@{md5, :pwd}, calculating MD5 and generating parameter placeholder?. - Otherwise (
@{else}), execute the contained:pwd, also generating parameter placeholder?.
- If matches
- Final Splicing:
@{and}splices the result into SQL:AND password = ?.
Usage Notes
Do not wrap single quotes around rules, especially when the rule (such as @{md5}, @{uuid32}) itself is used to generate parameter placeholders.
- Correct:
pwd = @{md5, :val}-> Generatespwd = ?(Passed via PreparedStatement, safe and correct) - Incorrect:
pwd = '@{md5, :val}'-> Preserves the literalpwd = '@{md5, :val}'; the rule does not execute
Outer rules such as if check their condition before parsing content. Unselected CASE branches do not execute. Rules such as AND parse inner results, inspect parameters, and add a connector; without a preceding WHERE they add WHERE rather than always emitting AND.