在Slick 3中构建动态UPDATE查询

时间:2015-09-24 05:22:49

标签: scala slick slick-3.0

我正在寻找一种在多个列上生成UPDATE查询的方法,这些列只在运行时才知道。

例如,给定List[(String, Int)],如何为列表中的所有键/值对生成UPDATE <table> SET k1=v1, k2=v2, kn=vn形式的查询?

我发现,给定一个键/值对,可以将纯SQL查询构建为sqlu"UPDATE <table> SET #$key=$value(其中密钥来自可靠来源以避免注入),但我已经将此概括为更新列表而不为每个更新运行查询失败。

这可能吗?

1 个答案:

答案 0 :(得分:0)

这是一种方法。我在这里创建一个表定义T,其中表和列名称(TableDesc)作为隐式参数。我本以为应该可以明确地设置它们,但我找不到它。对于示例,创建表查询实例,aTable和bTable。然后我插入并选择一些值,最后我更新了bTable中的一个值。

import slick.driver.H2Driver.api._
import scala.concurrent.Await
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration
import scala.util.{Failure, Success}

val db = Database.forURL("jdbc:h2:mem:test1;DB_CLOSE_DELAY=-1", "sa", "", null, "org.h2.Driver")

case class TableDesc(tableName: String, intColumnName: String, stringColumnName: String)

class T(tag: Tag)(implicit tableDesc: TableDesc) extends Table[(String, Int)](tag, tableDesc.tableName) {
    def stringColumn = column[String](tableDesc.intColumnName)

    def intColumn = column[Int](tableDesc.stringColumnName)

    def * = (stringColumn, intColumn)
}

val aTable = {
    implicit val tableDesc = TableDesc("TABLE_A", "sa", "ia")
    TableQuery[T]
}

val bTable = {
    implicit val tableDesc = TableDesc("TABLE_B", "sb", "ib")
    TableQuery[T]
}

val future = for {
    _ <- db.run(aTable.schema.create)
    _ <- db.run(aTable += ("Hi", 1))
    resultA <- db.run(aTable.result)
    _ <- db.run(bTable.schema.create)
    _ <- db.run(bTable ++= Seq(("Test1", 1), ("Test2", 2)))
    _ <- db.run(bTable.filter(_.stringColumn === "Test1").map(_.intColumn).update(3))
    resultB <- db.run(bTable.result)
} yield (resultA, resultB)
Await.result(future, Duration.Inf)
future.onComplete {
    case Success(a) => println(s"OK $a")
    case Failure(f) => println(s"DOH $f")
}
Thread.sleep(500)

我最后得到了sleep语句断言Future.onComplete在应用程序结束之前有时间完成。还有其他办法吗?