将[String,Object]从DB(或键值存储)映射到无形可扩展记录

时间:2014-06-28 13:44:52

标签: scala shapeless

将[String,Object]从DB(或键值存储)映射到无形可扩展记录

示例:

让我们说我有一张地图

val fromDB: Map[String, Any] = Map("name" -> "John", "age" -> 25)

知道字段“name”应该是一个字符串而字段“age”应该是一个整数,我如何将其转换为如下所示的无形可扩展记录?

val user = ("name" ->> "John") :: ("age"  ->> 25) :: HNil

我的最终目标是创建一个如下对象,可以使用字段“fromDB”转换Map。

object User {

  object name extends FieldOf[String]
  object age extends FieldOf[Int]

  def fromDB(data: Map[String,Any]) = {
    //TODO
  }
}

我也愿意接受其他建议以及这样做的方法。感谢。

1 个答案:

答案 0 :(得分:10)

你可以使用TypeCase提取器来写得非常干净:

import shapeless._, syntax.singleton._

val StrCase = TypeCase[String]
val IntCase = TypeCase[Int]

def toUserRecord(m: Map[String, Any]) = for {
   StrCase(name) <- m.get("name")
   IntCase(age)  <- m.get("age")
} yield ("name" ->> name) :: ("age" ->> age) :: HNil

或者你可以让演员更加明确:

import syntax.typeable._

def toUserRecord(m: Map[String, Any]) = for {
  name <- m.get("name").flatMap(_.cast[String])
  age  <- m.get("age").flatMap(_.cast[Int])
} yield ("name" ->> name) :: ("age" ->> age) :: HNil

请注意,我正在返回Option[LongRecordTypeHere]以保持此类型安全 - 如果地图中不存在键或者值无法转换为正确类型,我们将获得None