【问题标题】:SQL interpolation with ScalikeJDBC使用 ScalikeJDBC 进行 SQL 插值
【发布时间】:2018-05-17 20:42:32
【问题描述】:

我尝试使用库 ScalikeJDBC (here) 重现 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

【问题讨论】:

    标签: scala string-interpolation scalikejdbc


    【解决方案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 来执行此操作。这就是查询字符串被解析为占位符查询和单独的参数列表的原因。

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

    【讨论】:

    • 我编辑帖子以解释我的问题。感谢您的相关回答
    • @Thomas,您的真实案例可能需要也可能不需要createUnsafely,但根据您提供的信息无法猜测。请注意 createUnsafely 顾名思义是不安全的,因此您应该自己处理可能的 SQL 注入。
    • 是的,我明白了,如果不存在,我只想自动创建表。类似于:create table if not exists ${tableName},我必须这样做:val tableName = SQLSyntax.createUnsafely("myTable"),否则我会遇到 sql 语法错误
    • @Thomas,是的,DDL 不支持占位符。如果不知何故您有许多具有相同结构但名称不同的表,这可能是有道理的。但这在实践中可能很少见。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-08
    • 2012-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多