【问题标题】:How to output JSON from Slick query result?如何从 Slick 查询结果中输出 JSON?
【发布时间】:2016-02-17 13:56:26
【问题描述】:

我是 Scala 的新手,现在正在尝试学习 Slick。我在 Slick 教程中设置了一个数据库,并使用

val users:TableQuery[user] = TableQuery[user]

如何从 Play 框架将 users -value 输出到 JSON?我已经尝试为用户定义案例类并为 userFormat = Json.format[user] 制作阅读器+编写器,但我不知道我哪里出错了。我用 Spray.IO 做过类似的事情,在那里看起来很简单直接,但我想学习如何用 Play 和 Slick 来做这件事,我完全迷失了:(

这是我的 Tables.scala:

    package assets

    import org.joda.time.DateTime
    import play.api.libs.json._
    import scala.slick.driver.MySQLDriver.simple._
    import com.github.tototoshi.slick.MySQLJodaSupport._
    import scala.slick.lifted.{ProvenShape}

    case class user
      (
      id:Int,
      textId:String,
      sessionId:String,
      stamp:DateTime
    )

    class users(tag: Tag) extends Table[(Int, String, String, DateTime)](tag, "USER") {

      implicit object userFormat extends Format[user] {

        def writes(a: user): JsValue = {
          Json.obj(
            "id" -> JsNumber(a.id),
            "textId" -> JsString(a.textId),
            "sessionId" -> JsString(a.sessionId),
            "stamp" -> JsString(a.stamp.toString())
          )
        }

        def reads(json: JsValue): user = user(
          (json \ "id").as[Int],
          (json \ "textId").as[String],
          (json \ "sessionId").as[String],
          (json \ "stamp").as[DateTime]
        )
      }

      def id: Column[Int] = column[Int]("id", O.PrimaryKey)
      def textId: Column[String] = column[String]("textId")
      def sessionId: Column[String] = column[String]("sessionId")
      def stamp: Column[DateTime] = column[DateTime]("stamp")

      def * : ProvenShape[(Int, String, String, DateTime)] = (id,textId,sessionId,stamp)
    }

【问题讨论】:

    标签: json scala playframework slick


    【解决方案1】:

    首先,请在您的问题中添加一些上下文,因为很难看出什么不起作用(例如,您是否遇到编译错误?您是否遇到异常?)。

    关于问题内容,​​你应该把从 slick 中获取数据并将其转换为 JSON 作为两个完全独立的步骤;事实上,slick 中没有任何东西可以帮助您从案例类中生成 JSON。

    鉴于此,您将需要运行灵活的查询并从中获取您的类型的 case class 实例,例如你应该得到一个Seq[user]。要将其转换为 JSON,您应该调用 Json.toJson(myUserSeq)。对于我在您的代码中看到的内容,有一件事可能会妨碍您:要将Format 正确地放在范围内,您应该将它放在案例类的伴随对象中,例如:

    case class User(...)
    
    object User {
      implicit object format extends Format[User] { ... }
    }
    

    顺便说一句,如果您希望人们为您提供帮助并且您的代码可读(例如,在您的代码中使用小写的类名,很难理解),请注意该语言的 coding standards

    【讨论】:

    • 我尝试创建一个案例类然后反对,但它没有帮助。网络上充满了将 Slick 版本从 1 到 3 混合的指南,因此尝试 google 寻求帮助也非常可怕。我得到的错误是:No Json serializer found for type slick.driver.MySQLDriver.simple.TableQuery[assets.users]. Try to implement an implicit Writes or Format for this type. Ok(Json.toJson(users))
    • 该错误表明您没有运行查询并且您正在尝试将其转换为 JSON 而不是转换结果;您可以发布引发此错误的代码以及您使用的是哪个版本的 slick?
    • 我刚刚遇到了同样的问题,为了解决它,我使用了类似的方法 (github.com/playframework/play-samples/blob/…)。但在User.tupled 停止工作后,我发现的唯一解决方法是(User.apply _).tupled
    • @sentenza 我认为这是因为您为User 定义了一个伴随对象。这是定义伴侣的 scala 特质之一,因此 User 对象不被视为函数(尽管具有 apply 方法)。这是解决此问题的一种方法(即明确引用 apply 并使用 (X.apply _) 语法强制 eta 扩展)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-09
    • 2020-12-03
    • 1970-01-01
    相关资源
    最近更新 更多