[英]Turn Scala Anorm record into a specific object
使用如下所示的findBy
,我可以通過key
和value
在Authentications
表中搜索記錄
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.