【问题标题】:Slick 3.0.0 Select and Create or UpdateSlick 3.0.0 选择并创建或更新
【发布时间】:2015-05-24 11:49:19
【问题描述】:

我的情况是,我必须先进行选择,然后使用该值进行创建。这是我正在尝试实施的一些版本控制。这是表定义:

  class Table1(tag: Tag) extends Table[(Int, String, Int)](tag, "TABLE1") {
    def id = column[Int]("ID")
    def name = column[String]("NAME")
    def version = column[Int]("VERSION")

    def indexCol = index("_a", (id, version))

    val tbl1Elems = TableQuery[Table1]
  }

所以当请求来创建或更新 Table1 中的条目时,我必须执行以下操作:

1. Select for the given id, if exists, get the version
2. Increment the version
3. Create a new entry

所有这些都应该发生在一个事务中。这是我到目前为止所得到的:

  // this entry should be first checked if the id exists and if yes get //the complete set of columns by applying a filter that returns the max //version
  val table1 = Table1(2, "some name", 1)
  for {
    tbl1: Table1 <- tbl1MaxVersionFilter(table1.id)
    maxVersion: Column[Int] = tbl1.version
    result <- tbl1Elems += table1.copy(version = maxVersion + 1) // can't use this!!!
  } yield result

稍后我会将整个区块包装在一个事务中。但我想知道如何完成这将创建一个新版本?如何从 Column 中获取值 maxVersion 以便将其递增 1 并使用它?

【问题讨论】:

    标签: scala slick


    【解决方案1】:

    我会使用静态查询,类似这样的查询

    import scala.slick.jdbc.{StaticQuery=>Q}
    def insertWithVersion(id: Int,name:String) = 
       ( Q.u + "insert into table1 select  " +?id + "," +?name + ", (
         select coalese(max(version),1) from table1 where id=" +?id +")" ).execute
    

    如果你想用圆滑的方式来写,那么看看下面的

    val tableOne = TableQuery[Table1]
    
    def updateWithVersion(newId:Int,name:String):Unit = {
        val version = tableOne.filter( _.id === newId).map( _.version).max.run.getOrElse(1)
        tableOne += (newId,name,version) 
    } 
    

    想法是在同一查询中选择最大版本,如果没有版本,则使用 1 并插入它。此外,由于整个逻辑是在单个语句中发出的,因此不需要额外的事务管理。

    附:可能有一些错误是sql和代码。

    【讨论】:

    • 这似乎是个好主意,但我正在构建的数据库层应该适用于任何数据库后端。如果我求助于编写 SLQL,我可能会将我的代码库绑定到我想避免的特定后端!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多