【问题标题】:Scala Anorm - how use it properlyScala Anorm - 如何正确使用它
【发布时间】:2015-10-16 22:45:30
【问题描述】:

Scala 的游戏框架声称 Anorm,编写自己的 SQL 比 ORM 更好。原因之一是您通常只希望在数据库和前端之间以 json 格式传输数据。但是,大多数教程,甚至 Play 文档都给出了将 sql 的返回值解析为 case 类的示例,以便再次将其解析为 json。无论如何,我们仍然有一个对象关系映射,还是我漏掉了一点?

在我的数据库中存在一个包含 33 列的表。声明一个 case 类需要 33 行,使用 ~ 运算符声明一个解析器需要另外 33 行。使用 case 语句创建一个 Object,另外 66 行!说真的,我做错了什么?有什么捷径吗?在 django 中,同样的事情只需要 33 行。

【问题讨论】:

  • 您错过了 Anorm 和 ORM 之间的真正区别:ORM 根据映射描述符动态生成查询。使用 Anorm,您可以执行查询,因为您最了解您的数据库,它只提供方便的结果解析。

标签: scala anorm


【解决方案1】:

如果您在 Play 应用程序中使用 Anorm,那么映射到您的案例类的 Json 对象(假设它具有为其定义的相当正常的应用和取消应用函数,大多数情况下)应该非常简单定义一个使用 >2.10 基于宏的 Json-inception 方法的隐式......所以你真正需要的是这样的定义:

implicit val myCaseFormats = Json.format[MyCaseClass]

其中“MyCaseClass”是您的案例类型的名称。您甚至可以将其烘焙到用于从数据库中反序列化行集的解析器组合器中......这将大大清理您的代码并减少您必须编写的代码量。

有关 Json 宏的详细信息,请参见此处: https://www.playframework.com/documentation/2.1.1/ScalaJsonInception

我在一个相当大的代码库中非常广泛地使用它,它确实使事情变得非常干净。

就您的 Anorm 解析器而言,请记住您没有作为解析的结果来生成案例类实例...您实际上可以返回任何您喜欢的东西,这可能只是您的列值的索引序列(如果您使用诸如无形之类的东西来允许混合类型列表等......)或其他一些结构。

您在 Anorm 中也有宏支持,因此您的案例类的解析器可以是这样的一个内衬:

import norm.{Macro, Rowset}

val parser = Macro.namedParser[MyCaseClass] 

如果您想做一些自定义的事情(例如直接解析为 JsValue),那么您可以灵活地手工制作一个更狡猾的解析器。

HTH

【讨论】:

  • 哇,很好的答案,谢谢!但是,在我的数据库中,我有列数 > 22 的表,并且由于 json 宏在我的案例类上使用 apply + unapply 函数,我不能使用宏,也不能使用 json play library...
  • 但是,您可以在两个案例类之间拆分列(如果有意义的话),利用宏来解析它们,然后使用 ~ 或 ~> 将两个解析器组合成一个解析器,然后返回一个元组(一对案例类 A 和案例类 B),甚至将它们嵌入到容器案例类中?
  • 对于 JSON 方面的事情,您可能可以使用 JSON 转换来做一些事情 - 请查看 Play 网站上的文档 - 取决于您想要对结果数据结构做什么......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-15
  • 2015-06-07
  • 1970-01-01
  • 2020-11-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多