ScalikeJDBC SQL插值打印结果为占位符?问题排查与解决
问题:ScalikeJDBC SQL插值后打印语句显示
?而非实际参数值? 我尝试复现ScalikeJDBC的SQL插值功能,写了这段代码:
val member = sql"select id, name from members where id = ${id}" println(member.statement)
但输出结果却是:
select id, name from members where id = ?
我是不是哪里弄错了?
解答
其实你看到的结果完全是ScalikeJDBC的正常预期行为,这要从它的安全设计说起:
- 当你用
${id}这种插值语法时,ScalikeJDBC并没有直接把id的值拼进SQL字符串,而是将其处理为预编译SQL的占位符(也就是?)。这种做法是为了避免SQL注入,保证查询的安全性——实际参数值会在执行查询时由数据库驱动安全地传递。 - 你调用
member.statement获取的只是预编译用的SQL模板,所以看不到实际的参数值。
那如果确实需要把值直接嵌入SQL(比如动态指定表名、列名这类无法用预编译占位符的场景),才需要用到SQLSyntax.createUnsafely方法,示例代码如下:
import scalikejdbc.SQLSyntax.createUnsafely val id = 123 val member = sql"select id, name from members where id = ${createUnsafely(id)}" println(member.statement)
这时输出就会变成:
select id, name from members where id = 123
⚠️ 一定要注意:createUnsafely会直接把值拼入SQL,存在SQL注入风险,只有当你能100%控制输入内容、确保安全的情况下再使用它。
你之前调试时误以为插值不生效,其实是没搞清楚ScalikeJDBC默认插值语法的设计逻辑——它优先保证安全的预编译参数绑定,而非简单的字符串拼接。
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

