使用Quill infix操作时遇到问题(Scala 2.12.4 + Quill 2.3.3)
解决Quill自定义Infix操作的查询过滤异常问题
我来帮你搞定这个问题!你遇到的异常核心原因是:你的隐式类StringQuotes是给普通Scala String扩展方法,但在Quill的quote块里,user.name其实是Quill封装的Quoted[String]类型,不是原生String,所以直接调用equalTest会找不到对应的方法,导致编译或运行时异常。
修复方案
我们需要把隐式类的作用对象改成Quill的Quoted[String],同时调整infix的写法,确保Quill能正确解析这个自定义操作。
下面是修复后的完整代码:
import io.getquill._ val ctx = new SqlMirrorContext(PostgresDialect, SnakeCase) import ctx._ // 调整隐式类,针对Quill的Quoted[String]扩展方法 implicit class QuotedStringOps(left: Quoted[String]) { def equalTest(right: String): Quoted[Boolean] = quote { infix"$left = $right".as[Boolean] } // 如果需要支持右边也是Quoted[String]的场景,可以再加一个重载方法 def equalTest(right: Quoted[String]): Quoted[Boolean] = quote { infix"$left = $right".as[Boolean] } } case class User(name: String) object User { // 普通查询(对比用) def filter1() = quote { query[User].filter(user => user.name == "Cool") } // 使用自定义infix方法的查询 def filterWithInfix() = quote { query[User].filter(user => user.name.equalTest("Cool")) } } // 验证生成的SQL println(ctx.run(User.filterWithInfix())) // 输出应该是类似:SELECT x.name FROM user x WHERE x.name = 'Cool'
关键说明
- 隐式类的目标类型:把原来的
String改成Quoted[String],这样在quote块里的user.name(Quill的引号变量)就能找到这个扩展方法了。 - Infix的变量替换:
$left和$right会被Quill正确替换成对应的SQL参数或列名,避免SQL注入风险。 - 重载支持:如果你的场景需要右边也是数据库列(比如
user.name.equalTest(user.nickname)),可以添加针对Quoted[String]的重载方法,让自定义操作更灵活。
额外检查点
- 确保你的Quill版本(2.3.3)支持这种infix写法,2.x系列是兼容的。
- 如果你还是遇到异常,可以检查是否正确导入了
ctx._,这个导入会引入Quill的核心隐式转换和语法支持。
内容的提问来源于stack exchange,提问作者WeiChing 林煒清
相关产品推荐
相关产品推荐

