Scala slick 2.0 updateAll 等同于 insertALL?

Posted

技术标签:

【中文标题】Scala slick 2.0 updateAll 等同于 insertALL?【英文标题】:Scala slick 2.0 updateAll equivalent to insertALL? 【发布时间】:2014-07-22 03:47:35 【问题描述】:

寻找一种使用 slick 进行批量更新的方法。是否有与 insertALL 等效的 updateAll?到目前为止,Goole 的研究让我失望了。

我有一个具有不同状态的案例类别列表。每个都有不同的数值,所以我无法运行典型的更新查询。同时,我想保存多个更新请求,因为我可能要同时更新数千条记录。

【问题讨论】:

有一张公开的票,我相信它打算解决你的问题:github.com/slick/slick/issues/1015 【参考方案1】:

很抱歉回答我自己的问题,但我最终所做的只是下降到 JDBC 并执行批处理更新。

  private def batchUpdateQuery = "update table set value = ? where id = ?"

  /**
   * Dropping to jdbc b/c slick doesnt support this batched update
   */
  def batchUpate(batch:List[MyCaseClass])(implicit subject:Subject, session:Session) = 
    val pstmt = session.conn.prepareStatement(batchUpdateQuery)

    batch map  myCaseClass =>
      pstmt.setString(1, myCaseClass.value)
      pstmt.setString(2, myCaseClass.id)
      pstmt.addBatch()
    

    session.withTransaction 
      pstmt.executeBatch()
    
  

【讨论】:

不要认为这里需要事务边界。我用它 b/c 这最初是一次运行 3 个批次。【参考方案2】:

我不清楚您要实现什么,插入和更新是两个不同的操作,对于插入具有批量功能是有意义的,对于更新它在我看来没有,实际上在 SQL 中您可以写这样的东西

UPDATE
  SomeTable
SET SomeColumn = SomeValue
WHERE AnotherColumn = AnotherValue

这意味着将 AnotherColumn 等于 AnotherValue 的所有行更新为 SomeValueSomeColumn

Slick 中,这是一个简单的filter 结合mapupdate

table
  .filter(_.someCulomn === someValue)
  .map(_.FieldToUpdate)
  .update(NewValue)

如果您想更新整行,只需删除 map 并将 Row 对象传递给 update 函数即可。

编辑:

如果您想更新不同的案例类,我会认为这些案例类是您的架构中定义的行,如果是这种情况,您可以将它们直接传递给更新函数,因为它是这样定义的:

def update(value: T)(implicit session: Backend#Session): Int

对于第二个问题,我无法为您提供解决方案,查看JdbcInvokerComponent trait 看起来更新函数会立即调用 execute 方法

def update(value: T)(implicit session: Backend#Session): Int = session.withPreparedStatement(updateStatement)  st =>
  st.clearParameters
  val pp = new PositionedParameters(st)
  converter.set(value, pp, true)
  sres.setter(pp, param)
  st.executeUpdate

可能是因为您实际上可以在每个表的时间运行一个更新查询,而不是像 SO question 中所述的那样对多个表进行多次更新,但您当然可以更新同一个表上的多行。

【讨论】:

但它不会仍然运行一个,只是每个会话更新一次? 对不起,应该在编辑中说清楚,我不能 100% 确定,但我相信它会在每次函数调用时执行一次更新(不是会话,会话打开直到你关闭它)。无论如何,这对Slick 有点深入,我会等待 slick 团队中的某个人看到问题并添加他们的选项,可能是我忽略了一些事情。

以上是关于Scala slick 2.0 updateAll 等同于 insertALL?的主要内容,如果未能解决你的问题,请参考以下文章

为不存在的表 slick scala (Slick 3.0.0, scala) 创建一个类 Table

如何使用嵌套元组或 HList 处理具有 Slick 的 > 22 列表?

Scala / Slick,“等待连接 20000 毫秒后超时”错误

在 Scala 中使用 Slick 库获取自动增量值

IDEA中搭建Scala + Play+Slick环境

Scala Slick 如何将 Scala 代码翻译成 JDBC?