6

是否可以更新变量列列表,该数字仅在运行时由 slick 3.0 知道?

下面是我想做的例子(不会编译)

var q: Query[UserTable, UserTable#TableElementType, Seq] = userTable
var columns = List[Any]()
var values = List[Any]()

if (updateCommands.name.isDefined) {
  columns = q.name :: columns
  values = updateCommands.name.get :: values
}

if (updateCommands.surname.isDefined) {
  columns = q.surname :: columns
  values = updateCommands.surname.get :: values
}
q = q.filter(_.id === updateCommands.id).map(columns).update(values)
4

3 回答 3

2

这是我在 Slick 3.1 中所做的。我不确定更糟糕的是,编辑普通的 SQL 语句或多个查询。所以我决定使用后者,假设 Postgres 优化器会WHERE在单个事务的更新查询中看到相同的子句。我的更新方法看起来像这样

def updateUser(user: User, obj: UserUpdate): Future[Unit] = {

  val actions = mutable.ArrayBuffer[DBIOAction[Int, NoStream, Write with Transactional]]()
  val query = users.withFilter(_.id === user.id)

  obj.name.foreach(v => actions += query.map(_.name).update(v))
  obj.email.foreach(v => actions += query.map(_.email).update(Option(v)))
  obj.password.foreach(v => actions += query.map(_.pwdHash).update(Option(encryptPassword(v))))

  slickDb.run(DBIO.seq(actions.map(_.transactionally): _*))
}
于 2015-12-23T06:32:59.273 回答
0

要更新可变数量的列,您可以使用我用于 slick 3 的这种方式:

  def update(id: Long, schedule: Schedule, fieldNames: Seq[String]): Future[_] = {
val columns = schedules.baseTableRow.create_*.map(_.name).toSeq.filter(fieldNames.map(_.toUpperCase).contains)
val toBeStored = schedule.withDefaults

val actions = mutable.ArrayBuffer[DBIOAction[Int, NoStream, Write with Transactional]]()
val query = schedules.withFilter(_.id === id)

//this is becasue of limitations in slick, multiple columns are not possible to be updated!

columns.find("NAME".equalsIgnoreCase).foreach(x => actions += query.map(_.name).update(toBeStored.name))
columns.find("NAMESPACE".equalsIgnoreCase).foreach(x => actions += query.map(_.namespace).update(toBeStored.namespace))
columns.find("URL".equalsIgnoreCase).foreach(x => actions += 

db.run(DBIO.seq(actions: _ *).transactionally.withPinnedSession)

}

于 2017-07-17T06:54:23.717 回答
0

在 Slick 3.0 中,他们采用了稍微不同的方法,而不是 updateAll 方法,就我而言,采用了组合器的用户立场路径。

所以主要思想是在数据上定义一些操作,然后将它们组合到数据库上以进行一次运行。例子:

// let's assume that you have some table classes defined somewhere

// then let's define some actions, they might be really different
val action: SqlAction = YourTable.filter(_id === idToAssert)
val anotherAction = AnotherTable.filter(_.pets === "fun")

// and then we can combine them on a db.run 
val combinedAction =  for {
  someResult <- action
  anotherResult <- anotherAction
} yeild (someResult,anotherResult)

db.run(combinedAction) // that returns actual Future of the result type

以同样的方式你可以处理列表和序列,请看这里:http : //slick.typesafe.com/doc/3.1.0-M1/dbio.html DBIO 有一些功能可以让你组合一个动作的动作列表。

我希望这个想法很清楚,如果您有任何问题,欢迎评论。

于 2015-10-14T09:23:41.407 回答