跳到主要内容

规则系统

在 dbVisitor 中,规则 (Rules) 是一套嵌入在 SQL 中的轻量级 DSL(领域特定语言),通过 @{...} 语法调用。 它的出现旨在替代繁琐的 XML 标签(如 <if><where>),让开发者能以更接近原生 SQL 的方式编写动态查询。

适用范围

由于规则解析是 dbVisitor 执行引擎的底层核心能力,因此您可以在任何定义 SQL 的地方使用它:

  • Java 注解:在 @Select, @Insert, @Update, @Delete 等注解中直接编写。
  • 代码构建:通过 LambdaTemplateJdbcTemplate 执行的任意 SQL 字符串。
  • XML Mapper:在 .sql 文件中定义复杂查询。

使用限制

请勿在 SQL 字符串字面量中使用规则

dbVisitor 的解析器在扫描 SQL 时会识别并跳过由单引号 ' 包裹的字符串内容。这意味着,如果您将 @{...} 写在单引号内部,它会被当作普通文本原样输出,而不会被当作规则执行。

错误示例

-- 这里的 @{uuid} 不会被解析,数据库最终收到的字符串就是 '... @{uuid}'
SELECT * FROM users WHERE name = 'user_@{uuid}'

正确做法

应当将规则放在引号外部,利用数据库的字符串连接函数(如 concat)或者通过参数占位符来实现。

-- 方式 1: 使用 concat 函数拼接
SELECT * FROM users WHERE name = concat('user_', @{uuid})

工作原理

当 dbVisitor 接收到一条带有 @{...} 的 SQL 时,会经历以下步骤:

  1. 解析:扫描 SQL 文本,提取所有的规则标记。
  2. 求值:根据传入的参数上下文,计算规则中的 条件表达式(如果有)。
  3. 转换:根据规则的类型和参数,生成对应的 SQL 片段。

语法结构

规则的通用语法格式如下:

@{ 规则名 [, 条件表达式 [, 规则内容 ]] }
组成部分必须说明示例
规则名✅ 是规则的标识符,不区分大小写。and, or, uuid32
条件表达式❌ 否一个 OGNL 布尔表达式。当结果为 true 时规则生效。若省略或为空,默认为 trueage > 18, name != null
规则内容❌ 否规则要操作的 SQL 片段或参数。部分规则(如 UUID)不需要此部分。age = :age, order by id

常见变体

  1. 无参调用:仅调用规则生成数据。

    -- 生成 UUID
    @{uuid32}
  2. 带内容调用:通常用于动态 SQL 拼接,隐含判空逻辑。

    -- 当 :name 不为空时,自动追加 AND name = :name
    @{and, name = :name}
  3. 带条件调用:显式指定生效条件 (规则名通常以 if 开头)。

    -- 当 age > 18 时,追加 SQL
    @{ifand, age > 18, age = :age}

使用指引

dbVisitor 提供了丰富的内置规则,满足不同场景的需求:

  • 语句生成规则
    • 包含 动态 SQL 拼接@{and}, @{or}, @{set})、参数处理@{md5}, @{uuid})以及 宏与文本注入@{macro})等功能。
  • 结果处理规则
    • 用于对查询结果集进行后置处理,以及存储过程和多结果集查询的辅助配置(@{resultSet})。
  • 规则嵌套
    • 了解如何组合使用多个规则,实现参数预处理和复杂逻辑(如 @{and, col = @{md5, :val}})。