首页 文章

在Slick 3中构建动态UPDATE查询

提问于
浏览
3

我正在寻找一种方法来生成多个列的UPDATE查询,这些列只在运行时已知 .

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

我发现,给定一个键/值对,一个普通的SQL查询可以构建为 sqlu"UPDATE <table> SET #$key=$value (其中密钥来自可信来源以避免注入),但我没有成功将其推广到更新列表没有为每个运行查询 .

这可能吗?

1 回答

  • 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在应用程序结束之前有时间完成 . 还有其他方法吗?

相关问题