You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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'

关键说明

  1. 隐式类的目标类型:把原来的String改成Quoted[String],这样在quote块里的user.name(Quill的引号变量)就能找到这个扩展方法了。
  2. Infix的变量替换:$left和$right会被Quill正确替换成对应的SQL参数或列名,避免SQL注入风险。
  3. 重载支持:如果你的场景需要右边也是数据库列(比如user.name.equalTest(user.nickname)),可以添加针对Quoted[String]的重载方法,让自定义操作更灵活。

额外检查点

  • 确保你的Quill版本(2.3.3)支持这种infix写法,2.x系列是兼容的。
  • 如果你还是遇到异常,可以检查是否正确导入了ctx._,这个导入会引入Quill的核心隐式转换和语法支持。

内容的提问来源于stack exchange,提问作者WeiChing 林煒清

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:30:02