private def buildQuery(query: TweetQuery) = {
var q = Tweets.map { t =>
t
}
query.isLocked.foreach { isLocked =>
q = q.filter(_.isLocked === isLocked)
}
query.isProcessed.foreach { isProcessed =>
q = q.filter(_.processFinished === isProcessed)
}
query.maxScheduleAt.foreach { maxScheduleAt =>
q = q.filter(_.expectScheduleAt < maxScheduleAt)
}
query.minScheduleAt.foreach { minScheduleAt =>
q = q.filter(_.expectScheduleAt > minScheduleAt)
}
query.status.foreach { status =>
q = q.filter(_.status === status)
}
query.scheduleType.foreach { scheduleType =>
q = q.filter(_.scheduleType === scheduleType)
}
q
}
我正在写上面的内容来做动态查询。真的很无聊,还有什么方法可以做到这一点?
答案 0 :(得分:7)
也许MaybeFilter可以帮助你https://gist.github.com/cvogt/9193220
答案 1 :(得分:2)
我修改了 cvogt 的答案,以便使用 slick 2.1.0 。有关变更的说明见here。
希望它可以帮助某人:)
case class MaybeFilter[X, Y](val query: scala.slick.lifted.Query[X, Y, Seq]) {
def filter(op: Option[_])(f:(X) => Column[Option[Boolean]]) = {
op map { o => MaybeFilter(query.filter(f)) } getOrElse { this }
}
}
问候。
//Class definition
import scala.slick.driver.H2Driver.simple._
import scala.slick.lifted.{ProvenShape, ForeignKeyQuery}
// A Suppliers table with 6 columns: id, name, street, city, state, zip
class Suppliers(tag: Tag)
extends Table[(Int, String, String, String, String, String)](tag, "SUPPLIERS") {
// This is the primary key column:
def id: Column[Int] = column[Int]("SUP_ID", O.PrimaryKey)
def name: Column[String] = column[String]("SUP_NAME")
def street: Column[String] = column[String]("STREET")
def city: Column[String] = column[String]("CITY")
def state: Column[String] = column[String]("STATE")
def zip: Column[String] = column[String]("ZIP")
// Every table needs a * projection with the same type as the table's type parameter
def * : ProvenShape[(Int, String, String, String, String, String)] =
(id, name, street, city, state, zip)
}
//I changed the name of the def from filter to filteredBy to ease the
//implicit conversion
case class MaybeFilter[X, Y](val query: scala.slick.lifted.Query[X, Y, Seq]) {
def filteredBy(op: Option[_])(f:(X) => Column[Option[Boolean]]) = {
op map { o => MaybeFilter(query.filter(f)) } getOrElse { this }
}
}
//Implicit conversion to the MaybeFilter in order to minimize ceremony
implicit def maybeFilterConversor[X,Y](q:Query[X,Y,Seq]) = new MaybeFilter(q)
val suppliers: TableQuery[Suppliers] = TableQuery[Suppliers]
suppliers += (101, "Acme, Inc.", "99 Market Street", "Groundsville", "CA", "95199")
//Dynamic query here
//try this asigment val nameFilter:Option[String] = Some("cme") and see the results
val nameFilter:Option[String] = Some("Acme")
//also try to assign None in here like this val supIDFilter:Option[Int] = None and see the results
val supIDFilter:Option[Int] = Some(101)
suppliers
.filteredBy(supIDFilter){_.id === supIDFilter}
.filteredBy(nameFilter){_.name like nameFilter.map("%" + _ + "%").getOrElse("")}
.query.list
答案 2 :(得分:2)
我认为这是光滑的2.1.0的正确迁移代码
case class MaybeFilter[X, Y](val query: Query[X, Y, Seq]) {
def filter[T, R: CanBeQueryCondition](data: Option[T])(f: T => X => R) = {
data.map(v => MaybeFilter(query.withFilter(f(v)))).getOrElse(this)
}
}
答案 3 :(得分:0)
isLocked,isProcessed等选项?
然后你也可以写像
这样的东西for (locked <- query.isLocked) { q = q.filter(_.isLocked is locked) }
如果有任何安慰: - }
答案 4 :(得分:-2)
好吧,看起来这段代码违反了OCP。试着看看this article - 尽管它不在Scala上,它解释了如何正确设计这些方法。