我遇到的情况是,我必须先进行选择,然后使用该值来发布创建。这是我试图实现的一些版本控制。这是表定义:
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
我稍后会将整个块包装在一个事务中。但是我想知道如何完成它会创建一个新版本?如何从列中获取值maxVersion,以便我可以向其递增1并使用它?
答案 0 :(得分: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并插入它。此外,由于整个逻辑是在单个语句中发布的,因此不需要额外的事务管理。
P.S。可能有一些错误是sql和代码。