gpt4 book ai didi

scala - 在 Anorm 2.4 中使用 Parser API 和可空列

转载 作者:行者123 更新时间:2023-12-01 03:37:48 24 4
gpt4 key购买 nike

现在我已经升级到 Anorm 2.4,我真的很难摆脱弃用警告。我看过 How to handle null in Anorm但这对我帮助还不够。

让我们举一个简单的例子:account数据库表:

  • id (bigint 不为空)
  • email_address (varchar 不为空)
  • first_name (varchar)
  • last_name (varchar)

  • 我的 Scala 代码中可以有 2 个函数: getAccountOfIdgetAccountsOfLastName .
  • getAccountOfId返回 0 或 1 个帐户,因此 Option[(Long, String, Option[String], Option[String])]保持我们的示例简单
  • getAccountsOfLastName返回一个账户列表(其大小可能为 0),因此 List[(Long, String, Option[String], String)]保持我们的示例简单

  • 这2个函数的部分代码:
    def getAccountOfId(id: Long): Option[(Long, String, Option[String], Option[String])] = {
    DB.withConnection { implicit c =>
    val query = """select email_address, first_name, last_name
    from account
    where id = {id};"""

    /* Rest of the code that I struggle with unless I use deprecated functions */
    }
    }

    def getAccountsOfLastName(lastName: String): List[(Long, String, Option[String], String)] = {
    DB.withConnection { implicit c =>
    val query = """select id, email_address, first_name
    from account
    where last_name = {lastName};"""

    /* Rest of the code that I struggle with unless I use deprecated functions */
    }
    }

    我希望这两个函数中的“其余代码”基于 Anorm's Parser API .

    最佳答案

    不确定这是否有帮助,但是使用 Anorm 2.4,我有一个看起来像这样的案例类:

     final case class Role(id: Int,
    label: String,
    roletype: Int,
    lid: Option[Int],
    aid: Option[Int],
    created: DateTime,
    modified: DateTime)

    然后只需为它设置解析器组合器,如下所示:
     val roleOptionRowParser = int("id") ~ str("label") ~ int("roletype") ~ (int("lid")?) ~ (int("vid")?) ~ get[DateTime]("created") ~
    get[DateTime]("modified") map {
    case id~label~roletype~lid~vid~created~modified ⇒ Some(Role(id, label, roletype, lid, vid, created, modified))
    case _ ⇒ None
    }

    所以你基本上只是使用 ?可选字段的组合器,然后根据您从 SQL 结果行中提取的内容进行匹配。然后,您可以通过以下方式将其应用于查询:
    SQL(s"""
    | select * from $source
    | where $clause
    """.stripMargin).on(params : _*).as(rowParser.single).get

    在这种情况下,'rowParser' 只是对在最后一段代码中定义的 roleOptionRowParser 的引用。

    如果您的查询返回了多行(或期望有多行),那么您可以在将它们传递给“as”函数之前应用相同的组合器(例如 ? 或 *),如下所示:
    SQL(s"""
    | select * from $source
    | where $clause
    """.stripMargin).on(params : _*).as(rowParser *).flatten

    或者
    SQL(s"""
    | select * from $source
    | where $clause
    """.stripMargin).on(params : _*).as(rowParser ?).flatten

    啊 - 忘了提到最后的“扁平化”是因为我在这个例子中的解析器返回一个 Option[Role],这取决于返回的行中是否存在所有必要的列值(这个位):
    case id~label~roletype~lid~vid~created~modified ⇒ Some(Role(id, label, roletype, lid, vid, created, modified))

    因此,当返回多行时,我只需应用 'flatten' 来提升 Option 类型,以便我最终得到实际的 'Role' 实例列表。

    干杯,

    哈。

    关于scala - 在 Anorm 2.4 中使用 Parser API 和可空列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33142489/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com