【问题标题】:How does scala slick determin which rows to update in this queryscala slick 如何确定要在此查询中更新哪些行
【发布时间】:2017-06-07 20:08:59
【问题描述】:

有人问我 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) 查找所有具有“certificateState”“条件”的行
  • b) 为所述列创建查询
  • c) 创建了一个包含我要更新到的值的元组

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

背景

我想知道 slick 是否会跟踪要更新的行的 ID。

我想知道什么

  • 幕后发生了什么?
  • “val a: Query[CertificateStatuses, CertificateStatus, Seq]”中的 Seq 是什么
  • 有人能指出移动部件所在的光滑源吗?

【问题讨论】:

    标签: scala slick slick-2.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 来源的链接。

    什么是“val a:Query[CertificateStatuses, CertificateStatus, Seq]”中的 Seq

    它是集合类型。查询指定了 3 个类型参数:

    • mixed type - 表格(或列 - Rep)的流畅表示

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

    • collection type - 集合类型高于 unpacked types 作为查询的结果为您放置。

    举个例子:

    • 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

    可能还值得强调一点:

    我想知道 slick 是否会跟踪要更新的行的 ID。

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

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

    (我在上面假设logback)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-18
      • 2021-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-06-28
      • 2014-07-22
      相关资源
      最近更新 更多