我有一张桌子:
trait Schema {
val db: Database
class CoffeeTable(tag: Tag) extends Table[Coffee](tag, "coffees") {
def from = column[String]("from")
def kind = column[String]("kind")
def sold = column[Boolean]("sold")
}
protected val coffees = TableQuery[Coffee]
}
我想更新已售出的条目。这是我最终得到的方法:
def markAsSold(soldCoffees: Seq[Coffee]): Future[Int] = {
val cmd = coffees
.filter { coffee =>
soldCoffees
.map(sc => coffee.from === sc.from && coffee.kind === sc.kind)
.reduceLeftOption(_ || _)
.getOrElse(LiteralColumn(false))
}
.map(coffee => coffee.sold)
.update(true)
db.db.stream(cmd)
}
虽然它适用于一个小的soldCoffee
集合,但它输入了数百个元素后严重失败:
java.lang.StackOverflowError
at slick.ast.TypeUtil$$colon$at$.unapply(Type.scala:325)
at slick.jdbc.JdbcStatementBuilderComponent$QueryBuilder.expr(JdbcStatementBuilderComponent.scala:311)
at slick.jdbc.H2Profile$QueryBuilder.expr(H2Profile.scala:99)
at slick.jdbc.JdbcStatementBuilderComponent$QueryBuilder.$anonfun$expr$8(JdbcStatementBuilderComponent.scala:381)
at slick.jdbc.JdbcStatementBuilderComponent$QueryBuilder.$anonfun$expr$8$adapted(JdbcStatementBuilderComponent.scala:381)
at slick.util.SQLBuilder.sep(SQLBuilder.scala:31)
at slick.jdbc.JdbcStatementBuilderComponent$QueryBuilder.expr(JdbcStatementBuilderComponent.scala:381)
at slick.jdbc.H2Profile$QueryBuilder.expr(H2Profile.scala:99)
at slick.jdbc.JdbcStatementBuilderComponent$QueryBuilder.$anonfun$expr$8(JdbcStatementBuilderComponent.scala:381)
at slick.jdbc.JdbcStatementBuilderComponent$QueryBuilder.$anonfun$expr$8$adapted(JdbcStatementBuilderComponent.scala:381)
at slick.util.SQLBuilder.sep(SQLBuilder.scala:31)
所以问题是 - 还有另一种方法可以进行此类更新吗?
我想到的是使用简单的SQL查询或引入一些人工列,其中包含from
和type
列的连接值并对其进行过滤。