scala slick如何确定在此查询中要更新的行

时间:2017-01-23 10:35:45

标签: scala slick slick-2.0

我被问到scala slick如何根据此代码确定哪些行需要更新

      def updateFromLegacy(criteria: CertificateGenerationState, fieldA: CertificateGenerationState, fieldB: Option[CertificateNotification]) = {
        val a: Query[CertificateStatuses, CertificateStatus, Seq] = CertificateStatuses.table.filter(status => status.certificateState === criteria)
        val b: Query[(Column[CertificateGenerationState], Column[Option[CertificateNotification]]), (CertificateGenerationState, Option[CertificateNotification]), Seq] = a.map(statusToUpdate => (statusToUpdate.certificateState, statusToUpdate.notification))
        val c: (CertificateGenerationState, Option[CertificateNotification]) = (fieldA, fieldB)
        b.update(c)
      }

以上代码是(我认为)

  • a)寻找具有"标准的所有行" for" certificateState"
  • b)创建了对所述列的查询
  • c)创建了一个包含我想要更新的值的元组

然后查询用于查找需要应用元组的行。

背景

我不知道是光滑的跟踪要更新的行的ID。

我想知道的是什么

  • 封面背后发生了什么?
  • 什么是Seq in" val a:查询[CertificateStatuses,CertificateStatus,Seq]"
  • 有人可以指出移动部件所在的光滑来源吗?

1 个答案:

答案 0 :(得分:1)

好的 - 我重新格式化了你的代码,以便在这里更容易看到并将其分成块。让我们逐一介绍:

    val a: Query[CertificateStatuses, CertificateStatus, Seq] = 
        CertificateStatuses.table
            .filter(status => status.certificateState === criteria)

上面是一个大致翻译成这些内容的查询:

SELECT *  // Slick would list here all your columns but it's essiantially same thing
FROM certificate_statuses
WHERE certificate_state = $criteria

在此查询下面映射,即应用了SQL投影:

    val b: Query[
        (Column[CertificateGenerationState], Column[Option[CertificateNotification]]), 
        (CertificateGenerationState, Option[CertificateNotification]), 
        Seq] = a.map(statusToUpdate =>
            (statusToUpdate.certificateState, statusToUpdate.notification))

因此,您将拥有以下内容而不是*

SELECT certificate_status, notification
FROM certificate_statuses
WHERE certificate_state = $criteria

最后一部分是重用这个构造的查询来执行更新:

    val c: (CertificateGenerationState, Option[CertificateNotification]) = 
        (fieldA, fieldB)

    b.update(c)

转换为:

UPDATE certificate_statuses
SET certificate_status = $fieldA, notification = $fieldB
WHERE certificate_state = $criteria

我理解最后一步可能比其他人稍微简单一点,但这基本上就是你如何使用Slick进行更新(here - 尽管它是monadic版本)。

关于你的问题:

  

封面背后发生了什么?

这实际上超出了我的专业领域。据说这是相对简单的代码,我想更新转换可能会引起一些兴趣。在本回答的最后,我为您提供了相关Slick来源的链接。

  

什么是Seq in" val a:查询[CertificateStatuses,CertificateStatus,Seq]"

它的收藏类型。 Query指定3个类型参数:

  • mixed type - 表格的滑动表示(或列 - Rep

  • unpacked type - 执行查询后获得的类型

  • collection type - 作为查询结果,为您放置了unpacked type以上的集合类型。

举个例子:

  • CertificateStatuses - 这是您的Slick表定义

  • CertificateStatus这是你的案例类

  • Seq - 这就是检索结果的方式(基本上是Seq[CertificateStatus]

我在此解释:http://slides.com/pdolega/slick-101#/47(以及下一张幻灯片3张)

  

有人可以指出移动部件所在的光滑源吗?

我认为这部分可能很有意义 - 它显示了如何在更新语句中转换查询:https://github.com/slick/slick/blob/51e14f2756ed29b8c92a24b0ae24f2acd0b85c6f/slick/src/main/scala/slick/jdbc/JdbcActionComponent.scala#L320

也值得强调一点:

  

我不知道是光滑的跟踪要更新的行的ID。

它没有。查看生成的SQL。您可以通过在日志记录中添加以下配置来查看它们(但您也可以在此答案中使用它们):

<logger name="slick.jdbc.JdbcBackend.statement" level="DEBUG" />

(我假设上面有logback)。