Anorm模式匹配和不推荐使用的列表方法

时间:2015-07-29 10:08:14

标签: json scala anorm

我使用PlayFramework和Anorm一起构建一个带有JSON数据的REST服务。

由于我事先并不知道所有数据库列,因此我使用模式匹配将Row映射到JSON对象。

我已将文档(Using-Pattern-Matching)中的示例用作起点。

def any2jsValue(v: Any): JsValue = v match {
    case v2: String => JsString(v2)
    case v2: Long => JsNumber(v2)
    case v2: Int => JsNumber(v2)
    case v2: Double => JsNumber(v2)
    case v2: Float => JsNumber(v2)
    case v2: Some[Any] => any2jsValue(v2.get)
    case None => JsNull
    case v2: Any => JsString("MAPPING NOT IMPLEMENTED: " + v2.getClass()     + "  Value: " + v2.toString)
  }

def row2jsObject(row: Row): JsObject = row.asMap.map({
  case (k: String, v: Any) => Json.obj(k -> any2jsValue(v))
}).foldLeft(Json.obj())((r: JsObject, c: JsObject) => r ++ Json.obj(c.keys.head -> c.values.head))

val sql = SQL("SELECT * FROM world.City WHERE name = 'Milano'")

val cities = sql.map({
  case row: Row => row2jsObject(row)
}).list

Json.obj("cities" -> cities)

代码工作正常,但编译器警告我:

  不推荐使用类SimpleSql中的

方法列表:使用SQL("...").as(parser.*)

如果没有弃用的列表方法,如何进行相同的工作?

我已经尝试过实现解析器,并在API中搜索其他方法,但没有成功。

1 个答案:

答案 0 :(得分:1)

不使用已弃用的.list,必须定义RowParser并与.*组合使用; e.g:

import java.sql.Connection
import anorm._

trait Country
case class SmallCountry(name:String) extends Country
case class BigCountry(name:String) extends Country
case object France extends Country

val patternParser = RowParser[Country] {
  case Row("France", _) => Success(France)
  case Row(name:String, pop:Int) if (pop > 1000000) => Success(BigCountry(name))
  case Row(name:String, _) => Success(SmallCountry(name))
  case row => Error(TypeDoesNotMatch(s"unexpected: $row"))
}

def countries(implicit con: Connection): List[Country] =
  SQL("SELECT name,population FROM Country WHERE id = {i}").
    on("i" -> "id").as(patternParser.*)

在你的情况下:

import anorm.{ RowParser, SqlResult, Success }

def row2jsObject(row: Row): SqlResult[JsObject] = Success(row.asMap.map({
  case (k: String, v: Any) => Json.obj(k -> any2jsValue(v))
}).foldLeft(Json.obj())((r: JsObject, c: JsObject) => r ++ Json.obj(c.keys.head -> c.values.head)))

val parser: RowParser[JsObject] = RowParser(row2jsObject(_))
val cities: List[JsObject] =
  SQL("SELECT * FROM world.City WHERE name = 'Milano'").as(parser.*)