【问题标题】:How do I cast Any returned from executeInsert in Anorm to Long如何从 Anorm 中的 executeInsert 返回的 Any 转换为 Long
【发布时间】:2013-03-06 14:47:56
【问题描述】:

在我的 Scala Playframework 应用程序中,我尝试使用 executeInsert 创建一个 sms_token(class)。 然后使用主键创建一个唯一令牌,将其添加到 sms_token 并使用executeUpdate 保存。

case class SmsToken(id: Option[Long], token: String, phoneNumber: String, startDate: Option[Date], endDate: Option[Date], used: Boolean, tempReviewGrade: Option[Int], tempReviewText: Option[String])

object SmsToken {
  val simple = {
    get[Option[Long]]("id") ~
      get[String]("token") ~
      get[String]("phone_number") ~
      get[Option[Date]]("start_date") ~
      get[Option[Date]]("end_date") ~
      get[Boolean]("used") ~
      get[Option[Int]]("temp_review_grade") ~
      get[Option[String]]("temp_review_text") map {
      case id ~ token ~ phone_number ~ start_date ~ end_date ~ used ~ temp_review_grade ~ temp_review_text => SmsToken(id, token, phone_number, start_date, end_date, used, temp_review_grade, temp_review_text)
    }
  }
}

方法:

 def createToken(n: String): Option[Long] = {

    var addedTokenPk = 0L

    val result = DB.withConnection {
      implicit connection =>
        SQL("insert into sms_token(token, phone_number, start_date, end_date, used, temp_review_grade, temp_review_text) values({token},{phone_number},{start_date},{end_date},{used}, {temp_review_grade}, {temp_review_text})").on(
          'token -> "",
          'phone_number -> n,
          'start_date -> new Date(),
          'end_date -> new Date(),
          'used -> 0,
          'temp_review_grade -> 0,
          'temp_review_text -> ""
        ).executeInsert()
    }
    result match {
      case Some(pk) => {
        addedTokenPk = pk.asInstanceOf[Long]
      }
      case None => println("YAAARRRRR")
    }

    if (addedTokenPk != 0L) {

      val token = Util.createUniqueToken(addedTokenPk)

      DB.withConnection {
        implicit connection =>
          SQL("update sms_token s set s.token={token} where s.id={id}").on(
            'id -> ("" + addedTokenPk).toLong,
            'token -> token
          ).executeUpdate()
      }
      return Some(addedTokenPk)
    }
    None
  }

我的问题是关于这部分的:

result match {
    case Some(pk) => {
        addedTokenPk = pk.asInstanceOf[Long]
    }
    case None => println("YAAARRRRR")
}

executeInsert 返回一个 Any 对象,因为键是 Long 我正在做 asInstanceOf[Long] 因为我稍后在更新部分需要它。我是 Scala 菜鸟,所以我不确定这是否正确。也许有更好的 Scala 方式?

【问题讨论】:

    标签: scala playframework-2.1 anorm


    【解决方案1】:

    如果您在 executeInsert 结果上调用 map,您将获得 Long id

    DB.withConnection { implicit connection =>
       SQL("...").executeInsert().map(id => println(id))
    }
    

    【讨论】:

    • 嗯,我的 executeInsert() 没有方法 .map 。我想我错过了什么?
    • executeInsert() 返回一个 Option[Long] 并且 Option 有一个 map 方法
    • 我刚刚注意到您的解析器看起来很奇怪:get[Option[Long]]("id") 应该是 get[Pk[Long]]("id") 可能会有所不同。
    • 您使用的是哪些库?我正在使用 import anorm._ import anorm.SqlParser._ import anorm.~ import play.api.db._ 如果我检查方法: def executeInsert[A](generatedKeysParser : anorm.ResultSetParser[A] = { / * 编译代码 / })(隐式连接 : java.sql.Connection) : A = { / 编译代码 */ }
    • 一定是我的 Intellij IDEA 太疯狂了......它适用于你的例子......这很奇怪
    【解决方案2】:

    另一种方法是将simple 解析器传递给executeInsert:

    val result: SmsToken = DB.withConnection {
      implicit connection =>
        SQL("insert into sms_token(token, phone_number, start_date, end_date, used, temp_review_grade, temp_review_text) values({token},{phone_number},{start_date},{end_date},{used}, {temp_review_grade}, {temp_review_text})").on(
          'token -> "",
          'phone_number -> n,
          'start_date -> new Date(),
          'end_date -> new Date(),
          'used -> 0,
          'temp_review_grade -> 0,
          'temp_review_text -> ""
        ).executeInsert(simple.single)
    }
    

    这通常允许您一次性完成上述操作,在这种情况下,您将有权访问 pk 和允许您在数据库查询中引用 result 属性的令牌。

    注意:我正在寻找尝试并做到这一点并偶然发现了这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-27
      • 1970-01-01
      • 2015-09-24
      • 2011-11-21
      相关资源
      最近更新 更多