规则系统简介
在 dbVisitor 中,规则 (Rules) 是一套嵌入在 SQL 中的轻量级 DSL(领域特定语言),通过 @{...} 语法调用。
它的出现旨在替代繁琐的 XML 标签(如 <if>、<where>),让开发者能以更接近原生 SQL 的方式编写动态查询。
适用范围
由于规则解析是 dbVisitor 执行引擎的底层核心能力,因此您可以在任何定义 SQL 的地方使用它:
- Java 注解:在
@Query,@Insert,@Update,@Delete等注解中直接编写。 - 代码构建:通过
LambdaTemplate或JdbcTemplate执行的任意 SQL 字符串。 - XML Mapper:在 Mapper
.xml文件中定义复杂查询。
提示
规则名不区分大小写,@{AND}、@{And}、@{and} 等价。
使用限制
请勿在 SQL 字符串字面量中使用规则。
dbVisitor 的解析器在扫描 SQL 时会识别并跳过由单引号 ' 包裹的字符串内容。这意味着,如果您将 @{...} 写在单引号内部,它会被当作普通文本原样输出,而不会被当作规则执行。
错误示例:
-- 这里的 @{uuid32} 不会被解析,数据库最终收到的字符串就是 '... @{uuid32}'
SELECT * FROM users WHERE name = 'user_@{uuid32}'
正确做法:
应当将规则放在引号外部,利用数据库的字符串连接函数(如 concat)或者通过参数占位符来实现。
-- 方式 1: 使用 concat 函数拼接
SELECT * FROM users WHERE name = concat('user_', @{uuid32})
工作原理
当 dbVisitor 接收到一条带有 @{...} 的 SQL 时,会经历以下步骤:
- 解析:扫描 SQL 文本,提取所有的规则标记。
- 求值:根据传入的参数上下文,计算规则中的 条件表达式(如果有)。
- 转换:根据规则的类型和参数,生成对应的 SQL 片段。
语法结构
规则的解析结构如下,具体参数含义由各规则决定。只有 if、ifand 等条件规则会把第二项作为 OGNL 条件;and、in 等普通规则把它作为 SQL 内容:
@{ 规则名 [, 条件表达式 [, 规则内容 ]] }
| 组成部分 | 必须 | 说明 | 示例 |
|---|---|---|---|
| 规则名 | ✅ 是 | 规则的标识符,不区分大小写。 | and, or, uuid32 |
| 条件表达式 | ❌ 否 | 在条件规则中是 OGNL 布尔表达式;普通规则中的这一项通常属于 SQL 内容。 | age > 18, name != null |
| 规则内容 | ❌ 否 | 规则要操作的 SQL 片段或参数。部分规则(如 UUID)不需要此部分。 | age = :age, order by id |
常见变体
-
无参调用:仅调用规则生成数据。
-- 生成 UUID@{uuid32} -
带内容调用:通常用于动态 SQL 拼接,隐含判空逻辑。
-- 当 :name 不为空时,自动追加 AND name = :name@{and, name = :name} -
带条件调用:显式指定生效条件 (规则名通常以
if开头)。-- 当 age > 18 时,追加 SQL@{ifand, age > 18, age = :age}
使用指引
dbVisitor 提供了丰富的内置规则,满足不同场景的需求: