簡體   English   中英

將Scala Anorm記錄轉換為特定對象

[英]Turn Scala Anorm record into a specific object

使用如下所示的findBy ,我可以通過keyvalueAuthentications表中搜索記錄

def findBy(key: String, value: String): Any = DB.withConnection { implicit connection =>
  SQL("select * from authentications where {key}={value} limit 1").on('key -> key, 'value -> value)
}

例:

Authentication.findByMe("email", "toot@toot.com")

返回:

res1: Any = SimpleSql(SqlQuery(select * from authentications where ?=? limit 1,List(key, value),None),List((key,ParameterValue(email,anorm.ToStatement$$anon$3@4ca9aed5)), (value,ParameterValue(toot@toot.com,anorm.ToStatement$$anon$3@18154945))),<function1>)

如何將其重新轉換為Authentication對象? 包含我從查詢中返回的所有字段的對象。

我已經嘗試了以下內容,但是當其中一列中存在null時,我無法通過可以為空的對象錯誤。 我無法弄清楚如何使用這里提供的解決方案

val authentication_parser =
  get[String]("email") ~
  get[String]("encrypted_password") ~
  get[String]("user_id") ~
  get[String]("token") ~
  get[Date]("created_at") ~
  get[Date]("updated_at")

val authentication = {
  authentication_parser map {
    case email~encrypted_password~user_id~token~created_at~updated_at => Authentication(email, encrypted_password, user_id, token, created_at, updated_at)
  }
}

像這樣使用它:

def findBy(key: String, value: String): Any = DB.withConnection { implicit connection =>
  SQL("select * from authentications where {key}={value} limit 1").on('key -> key, 'value -> value).as(authentication *)
}

我也是Scala的新手,所以我一直充斥着像這樣的問題。

表中可以為空的任何列都應該是Authentication對象中的Option 例如,如果您的表是這樣的:

`email` varchar(255) NOT NULL,
`encrypted_password` varchar(255) NULL,
`user_id` int(11) NOT NULL,
`token` varchar(255) NULL,
`created_at` datetime NOT NULL,
`updated_at` datetime NULL

那你應該有:

case class Authentication(email: String, password: Option[String], userId: Int, token: Option[String], createdAt: Date, updatedAt: Option[Date])

你的解析器看起來像:

val authentication_parser = {
   get[String]("email") ~
   get[Option[String]]("encrypted_password") ~
   get[String]("user_id") ~
   get[Option[String]]("token") ~
   get[Date]("created_at") ~
   get[Option[Date]]("updated_at") map {
       case email~encrypted_password~user_id~token~created_at~updated_at => 
           Authentication(email, encrypted_password, user_id, token, created_at, updated_at)
   }
}

如果由於某種原因你不想在Authentication類中使用Option ,那么在map部分中使用getOrElse並用默認值填充它(更加丑陋):

case email~encrypted_password~user_id~token~created_at~updated_at => 
           Authentication(email, encrypted_password.getOrElse(""), user_id, token.getOrElse(""), created_at, updated_at.getOrElse(new Date())

對於偏執狂,您可能希望在從數據庫檢索時從解析器中排除散列密碼:

val authentication_parser = {
   get[String]("email") ~
   get[String]("user_id") ~
   get[Option[String]]("token") ~
   get[Date]("created_at") ~
   get[Option[Date]]("updated_at") map {
       case email~user_id~token~created_at~updated_at => 
           Authentication(email, None, user_id, token, created_at, updated_at)
   }
}

我還建議您更改.as()參數。 SQL("....").on(...).as(authentication_parser *)將解析為List[Authentication] 由於您在查詢中使用LIMIT 1 ,因此最好使用authentication_parser.single (解析為Authentication )或authentication_parser.singleOpt (解析為Option[Authentication] )。 singleOpt實際上是單個記錄的方法,因為如果沒有找到任何內容, single將引發異常。

最后,你應該使你的函數的返回類型不是Any (無論與解析器匹配)對不起文本牆。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM