Slick 3使用原生SQL插入时如何正确指定PostgreSQL自定义schema
核心原因说明
Slick 原生SQL的$默认是参数绑定逻辑,仅支持传递查询值,会自动给传入内容加转义引号,不能用来传递schema、表名这类SQL标识符,所以直接拼接${schema}会生成语法错误的SQL语句。
可行解决方案
方案1:使用Slick标识符插值语法(最便捷)
Slick 3 原生提供#$语法,专门用于插入不需要转义的SQL标识符,直接修改语句即可:
// schema为你自定义的schema变量,示例值为local sqlu"INSERT INTO #$schema.schedule(user_id, product_code, run_at) VALUES ($userId, $code, $nextRun)"
注意:该方式不会对插入内容做转义,需确保schema变量为你可控的配置常量,不要使用外部用户传入的值,避免SQL注入风险
方案2:修改JDBC连接默认schema(一劳永逸)
如果你的业务所有表都在local schema下,直接在PostgreSQL JDBC连接参数中指定默认schema,不需要修改任何SQL语句:
修改你的JDBC URL,添加currentSchema参数:
jdbc:postgresql://<数据库地址>:<端口>/<数据库名>?currentSchema=local
配置后所有不加schema前缀的表查询,都会默认在local schema下查找,和你直接写local.表名效果一致。
方案3:预拼接SQL字符串再生成查询
如果需要更灵活的SQL拼接逻辑,也可以先手动拼接好SQL语句文本,再转成Slick的静态查询:
val insertSql = s"INSERT INTO ${schema}.schedule(user_id, product_code, run_at) VALUES (?, ?, ?)" sqlu"#$insertSql".bind(userId, code, nextRun)
同样需要注意拼接的SQL部分的注入风险。
内容的提问来源于stack exchange,提问作者Michal Ostruszka
相关产品推荐
相关产品推荐

