Skip to content

脚本标签

SmartSql 内置的 XML 标签(<IsNotEmpty><IsEqual><Switch> 等)能处理大多数条件 SQL 生成,但有时你需要更具表达力的逻辑。SmartSql.ScriptTag 包添加了 <Script> 标签,使用 Jint 引擎执行 JavaScript 表达式,让你直接在 XML 映射中对 SQL 生成拥有完全的编程控制。

一览表

特性描述
包名SmartSql.ScriptTag
JS 引擎Jint(纯 C# JavaScript 解释器)
标签名<Script>
属性Test -- 求值为布尔值的 JavaScript 表达式
运算符映射自动将文本运算符转换为 JS 运算符

工作原理

Script 标签扩展了 SmartSql 的 Tag 基类。当中间件管线处理语句时,Script 标签会根据当前请求参数对其 Test 表达式求值:

mermaid
sequenceDiagram
autonumber
    participant Pipeline as Middleware Pipeline
    participant Tag as Script Tag
    participant Jint as Jint Engine
    participant Context as RequestContext

    Pipeline->>Tag: IsCondition(requestContext)
    Tag->>Jint: new Engine()
    Tag->>Context: Read Parameters
    loop Each parameter
        Tag->>Jint: engine.SetValue(key, value)
    end
    Tag->>Jint: Execute(Test expression)
    Jint-->>Tag: boolean result
    Tag-->>Pipeline: true (include SQL) or false (skip)

运算符映射

Script 标签自动将人类友好的文本运算符转换为 JavaScript 运算符。这使 XML 更具可读性:

mermaid
flowchart LR
    subgraph Mapping["Operator Mapping"]
        style Mapping fill:#161b22,stroke:#30363d,color:#e6edf3
        A["and"] --> A2["&&"]
        B["or"] --> B2["||"]
        C["gt"] --> C2[">"]
        D["gte"] --> D2[">="]
        E["lt"] --> E2["<"]
        F["lte"] --> F2["<="]
        G["eq"] --> G2["=="]
        H["neq"] --> H2["!="]
    end

    style A fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style A2 fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style B fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style B2 fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style C fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style C2 fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style D fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style D2 fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style E fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style E2 fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style F fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style F2 fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style G fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style G2 fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style H fill:#2d333b,stroke:#6d5dfc,color:#e6edf3
    style H2 fill:#2d333b,stroke:#6d5dfc,color:#e6edf3

该映射在构造时通过正则替换应用,因此你可以这样写:

xml
<Script Test="age gt 18 and status neq 'inactive'">

它会在内部转换为:

javascript
age > 18 && status != 'inactive'

在 XML 映射中的用法

基本条件子句

xml
<Statement Id="QueryUsers">
  SELECT * FROM Users
  <Where>
    <Script Test="age gt 0">
      AND Age > ?Age
    </Script>
    <IsNotEmpty Prepend="And" Property="Name">
      AND Name LIKE CONCAT('%', ?Name, '%')
    </IsNotEmpty>
  </Where>
</Statement>

复杂表达式

Script 标签支持 Jint 能执行的任何 JavaScript 表达式:

xml
<Script Test="minPrice neq null and maxPrice neq null and minPrice lt maxPrice">
  AND Price BETWEEN ?MinPrice AND ?MaxPrice
</Script>

与其他标签组合

Script 标签可以像其他 SmartSql 标签一样嵌套在 <Where><Switch> 或其他动态标签中:

xml
<Statement Id="AdvancedQuery">
  SELECT * FROM Products
  <Where>
    <Script Test="categoryIds.length gt 0">
      AND CategoryId IN
      <For Property="categoryIds" Open="(" Close=")" Separator=",">
        ?categoryIds
      </For>
    </Script>
    <IsEqual Property="Status" CompareValue="1">
      AND IsActive = 1
    </IsEqual>
  </Where>
</Statement>

标签构建器注册

ScriptBuilder 类将 <Script> 标签注册到 SmartSql 的标签构建器系统。它继承 AbstractTagBuilder 并从 XML 节点创建 Script 实例:

方法描述
Build(XmlNode, Statement)从 XML 节点的 Test 属性创建 Script 标签

要启用 Script 标签,在配置中注册标签构建器:

xml
<SmartSqlMapConfig>
  <TagBuilders>
    <TagBuilder Name="Script"
      Type="SmartSql.ScriptTag.ScriptBuilder, SmartSql.ScriptTag"/>
  </TagBuilders>
</SmartSqlMapConfig>

或通过 Options 模式:

json
{
  "TagBuilders": [
    {
      "Name": "Script",
      "Type": "SmartSql.ScriptTag.ScriptBuilder, SmartSql.ScriptTag"
    }
  ]
}

Jint 引擎配置

Script 标签使用以下设置创建 Jint 引擎:

设置用途
Strictfalse允许非严格 JavaScript
DebugModefalse无调试支持
AllowDebuggerStatementfalse防止 debugger 语句

context.Parameters 为 null 时,表达式将在不设置任何变量的情况下求值。

交叉参考

参考资料

基于 MIT 许可证发布。