跳到主要内容

6.7 参数符号转义

命令本身含有 ?:&,又不希望它们被识别为参数时,可以在前面加反斜杠。dbVisitor 解析后移除这个反斜杠,输出符号本身,不占用绑定参数。

要输出的符号命令模板写法Java 字符串写法
?\?"\\?"
:\:"\\:"
&\&"\\&"

原生命令中的问号

例如 Elasticsearch 请求地址中的 ?refresh=true 是 URL 参数,不是 JDBC 绑定参数。使用位置参数时:

jdbcTemplate.executeUpdate(
"PUT /users/_doc/1\\?refresh=true {\"id\":?,\"name\":?}",
new Object[] { 1, "Alice" });

驱动收到的命令如下,只有 JSON 中的两个 ? 需要绑定值:

PUT /users/_doc/1?refresh=true {"id":?,"name":?}

同样支持名称参数:

jdbcTemplate.executeUpdate(
"PUT /users/_doc/1\\?refresh=true {\"id\":#{id},\"name\":#{name}}",
Map.of("id", 1, "name", "Alice"));

多个 URL 参数之间的 & 也可以转义,例如 Java 字符串中的 "\\?op_type=create\\&refresh=true"

冒号与绑定参数相邻

冒号后紧贴 ?#{...} 时,不需要为冒号加转义或空格:

{"id":?,"name":?}
{"id":#{id},"name":#{name}}

使用 :name 时,字段冒号与参数冒号之间用空格分隔:

{"id": :id,"name": :name}

如果命令中的 :name 本来就是普通文本,则写为 \:name;普通文本 &name 同理写为 \&name

注意事项

  • 转义的是命令模板中的符号。传入参数的值无需这样处理,仍通过 ?:name#{...} 绑定。
  • Java 字符串需要写 \\?;Mapper XML 的普通文本中直接写 \?。XML 中的 & 还需写为 &,例如 \&pretty
  • 引号和 SQL 注释内的内容保持原样,不应用上述转义规则。PostgreSQL 的 :: 类型转换也无需转义。
  • 连续反斜杠紧接参数符号时,奇数个中的最后一个用于转义;偶数个全部保留,后面的符号仍作为参数解析。其他反斜杠保持原样。