【问题标题】:Scala Slick: how to serialize the result of a query to a variable tableScala Slick:如何将查询结果序列化到变量表
【发布时间】:2017-03-18 13:55:06
【问题描述】:

我想为控制器提供一个选择方法,该方法将表名作为参数并将 SELECT 查询的结果作为 JSON 返回。到目前为止,我已经这样做了:

def specialSelect(tableName: String) = Action.async {
  val tq: TableQuery[_] = tableObjectFactory(tableName)
  val res: Future[Seq[_]] = db.run(tq.result)
  res.map { p:Seq[_] => Ok(p.toJson) }
}

tableObjectFactory 获取我的表名并返回特定类型的TableQuery

def tableObjectFactory(tableName: String): TableQuery[_] = {
  tableName match {
    case "users" => TableQuery[Users]
    case "projects" => TableQuery[Projects]
  }
}

如果失败是因为没有为通用 Seq[_] 定义 JSON 序列化程序(实际上 _ 应该是 Product with Serializable,不确定这是否有帮助)。

事先不知道表名(在URL中找到,比如"/special_select/<tableName>"),我有120个这样的表,所以我不能只为每个表实现它。

有没有办法序列化anySeq[_],知道_ 始终是一个Slick 行结果(例如,一个案例类UsersRow),不管表是什么?p>

我已经阅读了有关通用 DAO 和 ActiveSlick 的信息,但我不确定是否应该走这么远。

【问题讨论】:

  • 每个case类会有不同数量和类型的字段,所以很难写出一般的Json写法。尝试为每个模型提供implicit json formatJson.format[User] 在伴随对象内。
  • Scala 不在乎我为每个行对象提供什么 Json 格式化程序,因为它只看到 Seq[(Product with Serializable)] 或类似的东西。它无法知道我为其提供 Json 格式化程序的案例类是它唯一能看到的。
  • 没错,但 Product 中的元组数量会根据您传递的对象而有所不同。所以不可能有一种格式可以解释如何将产品转换为 JSON。您必须从使用反射的解决方案中使用。尝试使用 Gson 库
  • Gson 几乎可以工作。它返回一些超级奇怪的东西,但至少包含预期的结果!另一方面,我发现了一个能够将任何案例类(产品)转换为 Json 的函数,所以我有希望,但 Slick 说一行的类型为found : ((_$1$u#TableElementType) forSome ...),但我的函数为required: Product

标签: json scala serialization playframework slick


【解决方案1】:

Gson 工作,谢谢@pamu。添加

libraryDependencies += "com.google.code.gson" % "gson" % "2.8.0"

到 build.sbt,然后这会将任何 Seq[_] 或行转换为可以作为 http 响应给出的 JsArray:

import com.google.gson.Gson
import play.api.libs.json._

val gson: Gson = new Gson()

def slickToJson(res: Seq[_]): JsArray = {
  JsArray(res.map(gson.toJson).map(Json.parse))
}

// in controller Action.async:
db.run(...).map(p => Ok(slickToJson(p)))

行由Gson序列化为String,然后由Play api解析回JsObjects,然后放入一个JsArray。我找不到更好的了。

【讨论】:

    猜你喜欢
    • 2016-04-30
    • 1970-01-01
    • 1970-01-01
    • 2016-09-29
    • 1970-01-01
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多