如何在Scala Slick中按数组索引查询?支持纯文本过滤吗?
在Scala Slick中实现数组列指定位置元素过滤
针对你提出的需求和疑问,解决方案如下:
1. 是否可以仅注入文本字符串作为过滤元素?
可以。无需使用Slick SQL插值器构建完整查询,直接用LiteralColumn注入纯文本形式的过滤条件即可,这种方式能灵活嵌入原生SQL片段作为过滤逻辑。
示例代码:
val query = blahs.filter { b => b.name === "somename" && LiteralColumn("my_array_field[2]") === "bar" }
如果想避免硬编码列名,还可以结合表映射的columnName属性动态生成:
val query = blahs.filter { b => b.name === "somename" && LiteralColumn(s"${b.myArrayField.columnName}[2]") === "bar" }
2. Slick或slick-pg中是否有数组元素检索的相关实现?
slick-pg默认没有提供直接按索引访问数组元素的API,但可以通过两种方式实现:
方式一:自定义扩展算子
通过扩展slick-pg的数组列操作,添加索引访问的支持,让代码更符合Slick的链式调用风格:
import slick.ast.Library.SqlOperator import slick.lifted.Column // 给数组列添加索引访问的扩展方法 implicit class ArrayColumnOps[T](col: Column[List[T]]) { def apply(index: Int): Column[T] = { val arrayIndexOp = new SqlOperator("[]") Column(arrayIndexOp.node(col.toNode, LiteralColumn(index).toNode)) } }
之后就可以像操作普通数组一样访问指定位置的元素:
val query = blahs.filter { b => b.name === "somename" && b.myArrayField(2) === "bar" }
方式二:直接嵌入原生SQL片段
即前面提到的LiteralColumn方式,直接把数组索引访问的SQL片段注入到过滤条件中,适合快速实现需求的场景。
完整表映射示例
配合slick-pg的数组支持,完整的表映射代码如下:
import slick.jdbc.PostgresProfile.api._ import com.github.tminglei.slickpg._ // 自定义支持数组和UUID的Postgres Profile trait CustomPostgresProfile extends ExPostgresProfile with PgArraySupport with PgUUIDSupport { override val api = CustomAPI object CustomAPI extends API with ArrayImplicits with UUIDImplicits } object CustomPostgresProfile extends CustomPostgresProfile import CustomPostgresProfile.api._ case class Blah(id: UUID, name: String, myArrayField: List[String]) class BlahTable(tag: Tag) extends Table[Blah](tag, "BLAH") { def id = column[UUID]("id") def name = column[String]("name") def myArrayField = column[List[String]]("my_array_field") def * = (id, name, myArrayField) <> (Blah.tupled, Blah.unapply) } val blahs = TableQuery[BlahTable]
内容的提问来源于stack exchange,提问作者Steve B.
相关产品推荐
相关产品推荐

