Slick 3.0 使用过滤器查询数据

Slick 3.0 Using Filters to Query data

我有一个案例class如下:

case class PowerPlantFilter(
  powerPlantType: Option[PowerPlantType],
  powerPlantName: Option[String],
  orgName: Option[String],
  page: Int,
  onlyActive: Boolean
)

我的 Table 映射如下所示:

class PowerPlantTable(tag: Tag) extends Table[PowerPlantRow](tag, "powerPlant") {
    def id            = column[Int]("powerPlantId", O.PrimaryKey)
    def orgName       = column[String]("orgName")
    def isActive      = column[Boolean]("isActive")
    def minPower      = column[Double]("minPower")
    def maxPower      = column[Double]("maxPower")
    def powerRampRate = column[Option[Double]]("rampRate")
    def rampRateSecs  = column[Option[Long]]("rampRateSecs")
    def powerPlantType= column[PowerPlantType]("powerPlantType")
    def createdAt     = column[DateTime]("createdAt")
    def updatedAt     = column[DateTime]("updatedAt")

    def * = {
      (id, orgName, isActive, minPower, maxPower,
        powerRampRate, rampRateSecs, powerPlantType, createdAt, updatedAt) <>
        (PowerPlantRow.tupled, PowerPlantRow.unapply)
    }
  }

我想检查过滤器并填充动态查询!此外,我想在结果 SQL 中为字符串类型使用 like 语句。

所以在我上面的例子中,应该检查我的 PowerPlantFilter 中的 orgName 是否存在,如果是,它应该在结果 SQL!

中生成类似的语句

这是我的第一次尝试,但显然失败了!

val q4 = all.filter { powerPlantTable =>
    List(
      criteriaPowerPlantType.map(powerPlantTable.powerPlantType === _),
      criteriaOrgName.map(powerPlantTable.orgName like s"%${criteriaOrgName}%") // fails to compile here!
    ).collect({case Some(criteria)  => criteria}).reduceLeftOption(_ && _)
  }

Slick 中是否内置了某些功能来执行此操作?

这就是我得出的结果并且有效,但不确定这是否有效:

def powerPlantsFor(criteriaPowerPlantType: Option[PowerPlantType], criteriaOrgName: Option[String], onlyActive: Boolean) = {
  val query = for {
    filtered <- all.filter(f =>
      criteriaPowerPlantType.map(d =>
        f.powerPlantType === d).getOrElse(slick.lifted.LiteralColumn(true)) &&
        criteriaOrgName.map(a =>
          f.orgName like s"%$a%").getOrElse(slick.lifted.LiteralColumn(true))
    )
  } yield filtered

  query.filter(_.isActive === onlyActive)
}

但是当我检查生成的 SQL 查询时,我看到两个语句正在数据库中执行,如下所示:

[debug] s.j.J.statement - Preparing statement: select `powerPlantId`, `orgName`, `isActive`, `minPower`, `maxPower`, `rampRate`, `rampRateSecs`, `powerPlantType`, `createdAt`, `updatedAt` from `powerPlant` where (true and (`orgName` like '%Organization-%')) and (`isActive` = true) limit 0,5
[debug] s.j.J.statement - Preparing statement: select `powerPlantId`, `orgName`, `isActive`, `minPower`, `maxPower`, `rampRate`, `rampRateSecs`, `powerPlantType`, `createdAt`, `updatedAt` from `powerPlant` where `isActive` = true

我该如何优化它?