11

我有以下 SLICK 查询来获取名称字段匹配某些值条件并按名称列排序的数据表的分页结果

val q = ThirdParties.where(_.name like criteria).sortBy(_.name.asc.nullsLast).drop(offset).take(pageSize)
val thirdParties = (for(s <-q) yield(s)).list map { case t: ThirdParty => t }

这对我来说没问题,但现在我需要能够将运行时参数传递给 sortBy 方法,该方法标识要在其上执行排序的列。
我调用查询的方法将有一个int表示数据表中列的索引。

如何从 int 列索引获取 sortBy 方法所需的必要类型?

4

1 回答 1

11

这样做会失去一些类型安全性,但也许这样的方法伤害最小:

这是 Slick 文档中的咖啡示例。假设您希望通过'index'来处理列的子集。在我们的示例中,假设由于某种原因,我们有2 个价格列和销售列,Int我们将其称为 column或。. 如果您可以忍受轻微的 DRY 违规行为,例如:012

object Coffees extends Table[(String, Int, Double, Double, Int, Int)]("COFFEES") {
  def name = column[String]("COF_NAME", O.PrimaryKey)
  def supID = column[Int]("SUP_ID")
  def price1 = column[Double]("PRICE1")
  def price2 = column[Double]("PRICE2")
  def sales = column[Int]("SALES")
  def total = column[Int]("TOTAL")
  def * = name ~ supID ~ price1 ~ price2 ~ sales ~ total
  def nth = Vector(price1, price2, sales) // Your index-addressable columns 
}

Coffees.nth是一个包含Int和的列向量Double

scala> Coffees.nth
scala.collection.immutable.Vector[scala.slick.lifted.Column[_ >: Int with Double <: AnyVal]] = Vector(COFFEES.PRICE1, COFFEES.PRICE2, COFFEES.SALES)

当然,在运行时选择要排序的列意味着您必须处理虚假的列索引 - 如果您只有k列并且您要求k+1第 th 列,您要么必须抛出异常,要么默默地选择默认列。这是想要将动态输入转换为通常是静态的(并且类型安全)的结果。

如果您对虚假列索引的例外情况感到满意,那么(回到您的示例)

 def q(colIndx: Int) = ThirdParties.where(_.name like criteria).
       sortBy(_.nth(colIndx).asc.nullsLast).
       drop(offset).take(pageSize)

然后调用查询

 val colIndx: Int = // gotten at runtime
 val thirdParties = (for(s <-q(colIndx)) yield(s)).list map { case t: ThirdParty => t }
于 2013-01-29T15:42:09.277 回答