可用版本: Dev (3.21) | 最新 (3.20) | 3.19 | 3.18 | 3.17 | 3.16 | 3.15 | 3.14 | 3.13 | 3.12 | 3.11

纯SQL模板语言

适用于 ✅ 开源版   ✅ 专业版   ✅ 企业版

正如上一章中记录的那样,plain SQL API 支持一种字符串模板迷你语言,允许从较小的部分构造复杂的 SQL 字符串内容。下面可以看到一个简单的例子,例如,当寻找对 PostgreSQL 的各种供应商特定运算符类型的支持时

ARRAY[1,4,3] && ARRAY[2,1]
condition("{0} && {1}", array1, array2);

这样的 plain SQL 模板总是由两件事组成

  • 包含 {number} 样式占位符的 SQL 字符串片段。
  • 一组 org.jooq.QueryPart 参数,这些参数预计会嵌入到 SQL 字符串中

SQL 字符串可以通过基于 0 的索引引用参数。每个参数可以被引用多次。例如,SQLite 对 REPEAT(string, count) 函数的模拟可能如下所示

Field<Integer> count = val(3);
Field<String> string = val("abc");
field("replace(substr(quote(zeroblob(({0} + 1) / 2)), 3, {0}), '0', {1})", String.class, count, string);
//                                     ^                  ^          ^                   ^^^^^  ^^^^^^
//                                     |                  |          |                     |       |
// argument "count" is repeated twice: \------------------+----------|---------------------/       |
// argument "string" is used only once:                              \-----------------------------/

为了方便起见,还有一个 DSL.list(QueryPart...) API,它允许将逗号分隔的查询部分列表包装在单个模板参数中

Field<String> a = val("a");
Field<String> b = val("b");
Field<String> c = val("c");

// These two produce the same result:
condition("my_column IN ({0}, {1}, {2})", a, b, c); // Using distinct template arguments
condition("my_column IN ({0})", list(a, b, c));    // Using a single template argument

解析规则

在处理这些 plain SQL 模板时,会运行一个迷你解析器来处理以下事项

  • 'abc'$$abc$$ 这样的字符串文字
  • "name", `name`, 或 [name] 这样的带引号的名称
  • /* block */-- line 这样的注释
  • {d '2000-01-01'} 这样的 JDBC 转义序列
  • 索引 (?) 或命名 (:identifier) 绑定变量占位符

以上内容会被模板引擎识别,并且在替换编号的占位符和/或绑定变量时,其中的内容会被忽略。例如

query(
  """
  SELECT /* In a comment, this is not a placeholder: {0}. And this is not a bind variable: ? */ title AS `title {1} ?`
  -- Another comment without placeholders: {2} nor bind variables: ?
  FROM book
  WHERE title = 'In a string literal, this is not a placeholder: {3}. And this is not a bind variable: ?'
  """
);

上面的查询不包含任何编号的占位符或绑定变量,因为会被搜索的标记包含在注释、字符串文字或带引号的名称中。

反馈

您对此页面有任何反馈吗? 我们很乐意听取您的意见!

The jOOQ Logo