仅在满足条件时更新行

Update a row only if condition is met

我只想在行中有有效数据时更新行中的特定列。具体来说:我有一个 table 和 Event,它存储 startstopisActive 标志。 我想通过将 isActive 设置为 true 来激活某些 Events,但是我需要检查开始日期和停止日期是否有效。 型号:

 case class Event {start:DateTime, stop:DateTime, isActive:Boolean}

我的验证方法签名:

validateEvent(ev: Event): Boolean

我的第一个方法:

def activateEv() = Action.async(parse.json) { request => { ... val ev = db.run(dao.findEvById(poid, uid)) val ret = ev.flatMap { case st: Option[Event] => if (validateEvent(st.get)) { db.run(dao.updateActivity(poid, true).map { case 0 => false case other => true } } else Future(false) } ... } }

我认为这不是解决这个问题的方式。 你能建议吗? 也许只有一个 db.run 就足够了?

这可以通过在 DBIOAction 对象上使用组合器(例如 flatMap)在单个 db.run 中实现。假设您的 dao 方法如下所示:

case object dao {
  def findEvById(poid: Int, uid: Int): DBIOAction[Option[Event], NoStream, Effect.Read] = ???

  // In your case `updateActivity` returns an `Int` and you're mapping it to a `Boolean`.
  // That mapping could be placed here, so `updateActivity` would return `Boolean` now.
  def updateActivity(poid: Int, bool: Boolean): DBIOAction[Boolean, NoStream, Effect.Write] = ???
}

这就是我们如何实现您正在寻找的东西:

...
val action = dao.findEvById(poid, uid).flatMap {
  case Some(event) if validateEvent(event) => dao.updateActivity(poid, true)
  case _ => DBIO.successful(false)
}.transactionally

db.run(action)
...

如您所见,我们这里有一个事务,它会先进行选择,然后进行更新(仅当 event 有效时)。此外,整个 select then update 操作可能是您 dao.

中的一个单独方法