1

我尝试使用 ScalikeJDBC 库(此处)重现 SQL 插值示例。

val member = sql"select id, name from members where id = ${id}"
println(member.statement)

但我得到一个奇怪的结果:

select id, name from members where id = ?

我错过了什么?

编辑和回答:

Mea culpa,我试图调试为什么我的 sql 查询不适用于字符串插值,所以我打印了查询的值。我得到了这个结果,但我没有检查它是否正常。问题是我必须SQLSyntax.createUnsafely在要用于插值的字符串上使用。

4

1 回答 1

1

从这个问题中不清楚你在这里到底发现了什么令人惊讶。我想你觉得奇怪的?statement. 引用的文章显示了与占位符完全相同的查询,甚至明确提到了它的原因:

不用担心,此代码受到 SQL 注入攻击的安全保护。${id}将是一个占位符。

如果您查看 的来源SQL,它是所有sql""插值结果的基础,您可能会看到两个字段:

val statement: String,
private[scalikejdbc] val rawParameters: Seq[Any]

还有

  final lazy val parameters: Seq[Any] = rawParameters.map {
    case ParameterBinder(v) => v
    case x => x
  }

这样做是为了不在库中重新实现棘手的 SQL 转义逻辑。而是使用标准java.sql.PreparedStatement来做到这一点。这就是为什么将查询字符串解析为占位符查询和单独的参数列表的原因。

PS 如果为什么需要某种形式的转义来避免 SQL 注入,或者不清楚 SQL 注入的坏处,您可能应该阅读更多关于SQL 注入的信息。

于 2018-05-17T00:13:53.543 回答