【问题标题】:22 Column limit for procedures22 程序的列限制
【发布时间】:2017-02-22 18:26:40
【问题描述】:

在使用 Slick 调用过程时,我们如何克服 22 个限制?

我们目前有:

val q3 = sql"""call getStatements(${accountNumber})""".as[Transaction]

问题是我们必须返回超过 22 列,而 Transaction 案例类不能超过 22 列,因为当我们执行 JSONFormat 时会出现错误:

[error] E:\IdeaProjects\admin\Transaction.scala:59: No unapply or unapplySeq function found
[error]   implicit val jsonFormat = Json.format[Transaction]

有什么建议吗?

【问题讨论】:

标签: scala playframework slick


【解决方案1】:

好吧 - 如果你真的可以修改你的 Transaction 案例类,那么有比 HList 更好的解决方案(老实说,以后操作可能有点麻烦)。

所以事情是这样的:假设你有 User 具有以下属性的表:

  • 身份证
  • 姓名
  • 教师
  • 最终成绩
  • 街道
  • 号码
  • 城市
  • 邮政编码

上面的列可能没有意义,但让我们以它们为例。处理上面最直接的方法是创建一个案例类:

case class User(
   id: Long,
   name: String,
   ...  // rest of the attributes here
   postCode: String)

将从应用程序端的表映射。

现在你还可以这样做:

case class Address(street: String, number: String, city: String, postCode: String)

case class UniversityInfo(faculty: String, finalGrade: Double)

case class User(id: Long, name: String, surname: String, uniInfo: UniversityInfo, address: Address)

这种组合将帮助您避免列过多的问题(这基本上是您的案例类/元组中属性过多的问题)。 除此之外 - 我认为如果您有很多列,这样做总是(经常?)有益的 - 如果只是为了可读性目的。

如何进行映射

class User(tag: Tag) extends Table(tag, "User") {

  // cricoss info
  def id = column[Long]("id")
  def name = column[String]("name")

  // ... all the other fields
  def postCode = column[String]("postCode")

  def * = (id, name, surname, uniInfoProjection, addressProjection) <>((User.apply _).tupled, User.unapply)

  def uniInfoProjection = (faculty, finalGrade) <>((UniversityInfo.apply _).tupled, UniversityInfo.unapply)

  def addressProjection = (street, number, city, city) <>((Address.apply _).tupled, Address.unapply)
}

自定义SQL 映射也可以做到这一点。

implicit val getUserResult = GetResult(r => 
    User(r.nextLong, r.nextString, r.nextString, 
         UniversityInfo(r.nextString, r.nextDouble),
         Adress(r.nextString, r.nextString, r.nextString, r.nextString))
)         

所以简单地说 - 尝试将您的字段分成多个嵌套案例类,您的问题应该会消失(增加了可读性的好处)。如果你这样做,接近元组/案例类限制几乎不会成为问题(你甚至不需要使用HList)。

【讨论】:

  • 非常好,这正是我们用于其他型号的。但是,当结果也来自程序时,我可以这样做吗?我可以将过程的结果放入扩展 Table 类的类中吗?
  • 当然,只要关注Slick——它只是一个查询结果。
  • 我可以将过程的结果放入扩展 Table 类的类中吗?如果是,那就太棒了。
  • 这是一个令人困惑的问题 - Table 类用于指定映射,而不是用于表示实际的数据库元组。您通常有一对: - 扩展 Table 的类(映射定义)和一个用于表示 db 元组的 case class(它不需要是案例类 - 但通常是)
  • 是的,我们使用生成器自动为所有表执行此操作。我们根据我们的需要对其进行了修改,它的效果非常好。但是对于该过程的结果,我只使用了一个简单的case class,效果非常好。
猜你喜欢
  • 2013-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-31
  • 1970-01-01
  • 2017-05-19
  • 1970-01-01
相关资源
最近更新 更多