如何在Play 2.1.4中添加其他隐式提取器并实际使用它?

时间:2013-09-16 22:20:41

标签: postgresql playframework uuid anorm

我正在使用Play 2.1.4对postgresql数据库。在postgresql db中,我使用uuid作为我的pk数据类型,它与java.util.UUID相关。 anorm中的SqlParser.getT函数没有java.util.UUID的隐式提取器。这是有道理的,因为我不认为很多人会使用它;但是,我似乎无法找到如何添加一个的说明。有没有人知道如何在Play中为anorm.SqlParser添加一个额外的隐式提取器?

我得到的错误如下:

  

找不到参数提取器的隐式值:anorm.Column [java.util.UUID]

我对Scala和Play真的很陌生,所以如果我的方法完全错误,请告诉我,但我真的希望能够像你在下面看到的那样做。

case class App(appId: UUID, appName: String, appServerName: String,
               appComponent: String, appDescription: String,
               appDateCreated: DateTime, appDateModified: DateTime,
               appValidated: Boolean)

val app = {
    get[UUID]("app_id") ~
    get[String]("app_name") ~
    get[String]("app_server_name") ~
    get[String]("app_component") ~
    get[String]("app_description") ~
    get[java.util.Date]("app_date_created") ~
    get[java.util.Date]("app_date_modified") ~
    get[Boolean]("app_validated") map {
      case id ~ name ~ serverName ~ component ~ description ~ dateCreated ~
        dateModified ~ validated  => App(id, name, serverName, component,
      description, new DateTime(dateCreated.getTime),
        new DateTime(dateModified.getTime), validated)
    }
  }

def all(): List[App] = DB.withConnection { implicit conn =>
  SQL("SELECT * FROM apps").as(app *)
}

2 个答案:

答案 0 :(得分:7)

以下是返回java.util.UUID的JDBC驱动程序的@ r.piesnikowski答案的简化变体,就像PostgreSQL一样:

  /**
   * Implicit conversion from UUID to Anorm statement value
   */
  implicit def uuidToStatement = new ToStatement[UUID] {
    def set(s: java.sql.PreparedStatement, index: Int, aValue: UUID): Unit = s.setObject(index, aValue)
  }

  /**
   * Implicit conversion from Anorm row to UUID
   */
  implicit def rowToUUID: Column[UUID] = {
    Column.nonNull[UUID] { (value, meta) =>
      value match {
        case v: UUID => Right(v)
        case _ => Left(TypeDoesNotMatch(s"Cannot convert $value:${value.asInstanceOf[AnyRef].getClass} to UUID for column ${meta.column}"))
      }
    }
  }

答案 1 :(得分:5)

也许this post会有所帮助。 (在我的项目中使用。工作正常)

 /**
   * Attempt to convert a SQL value into a UUID
   *
   * @param value value to convert
   * @return UUID
   */
  private def valueToUUIDOption(value: Any): Option[UUID] = {
    try {
      valueToByteArrayOption(value) match {
        case Some(bytes) => Some(UUIDHelper.fromByteArray(bytes))
        case _ => None
      }
    }
    catch {
      case e: Exception => None
    }
  }
/**
   * Implicit conversion from UUID to anorm statement value
   */
  implicit def uuidToStatement = new ToStatement[UUID] {
    def set(s: java.sql.PreparedStatement, index: Int, aValue: UUID): Unit = s.setObject(index, aValue)
  }
 /**
   * Implicit converstion from anorm row to uuid
   */
  implicit def rowToUUID: Column[UUID] = {
    Column.nonNull[UUID] { (value, meta) =>
      val u = UUID.fromString(value.toString)
      val MetaDataItem(qualified, nullable, clazz) = meta
      valueToUUIDOption(value) match {
        case Some(uuid) => Right(uuid)
        case _ => Left(TypeDoesNotMatch("Cannot convert " + value + ":" + value.asInstanceOf[AnyRef].getClass + " to UUID for column " + qualified))
      }
    }
  }