【问题标题】:Build dynamic UPDATE query in Slick 3在 Slick 3 中构建动态 UPDATE 查询
【发布时间】:2015-09-24 05:22:48
【问题描述】:

我正在寻找一种方法来针对仅在运行时知道的多个列生成 UPDATE 查询。

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

我发现,给定一个键/值对,可以将纯 SQL 查询构建为sqlu"UPDATE <table> SET #$key=$value(其中键来自受信任的来源以避免注入),但我未能成功概括这一点到更新列表,而无需为每个更新运行查询。

这可能吗?

【问题讨论】:

    标签: scala slick slick-3.0


    【解决方案1】:

    这是一种方法。我在这里创建了一个表定义 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 在应用程序结束之前有时间完成。有没有其他办法?

    【讨论】:

      猜你喜欢
      • 2015-01-20
      • 2016-07-25
      • 2021-09-09
      • 2018-04-09
      • 1970-01-01
      • 1970-01-01
      • 2012-11-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多