22列限制的过程。

7

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

我们目前有:

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

问题在于我们需要返回超过22个列,但是Transaction case类不能有超过22个列,因为当我们进行JSON格式化时会出现错误:

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

有什么建议吗?


你正在使用哪个版本的Scala? - sun_dare
你可以在这里使用HList来处理超过22个列,以下是一个示例: https://gist.github.com/davegurnell/8dd7d01eff8e59877abb - Sami Badawi
不了解 slick,但是可以使用 https://github.com/xdotai/play-json-extensions 来处理 JSON 中的超过22个字段。 - Andriy Kuba
重要问题 - 你能修改你的Transaction案例类吗? - Paul Dolega
当然可以,我可以随意操作那个类。 - user836845
请点击此处查看Slick 3.2.3:https://dev59.com/XJbfa4cB1Zd3GeqPoBB9#49659436 这个问题有很多重复。 - ecoe
1个回答

16

好的 - 如果您可以修改您的Transaction case class,那么有一个比HList更好的解决方案(说实话,后者可能稍微有些麻烦)。

所以这是问题:假设您有以下属性的User表:

  • id
  • name
  • surname
  • faculty
  • finalGrade
  • street
  • number
  • city
  • postCode

上述列可能没有意义,但让我们将它们用作示例。处理上述内容最直接的方法是创建一个case class:

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)

这篇文章将帮助您避免过多列(基本上是指您的case class / tuple中有太多属性的问题)。除此之外 - 我认为如果您有很多列,这样做总是(经常?)有益的 - 至少仅仅是出于可读性的考虑。

如何进行映射

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))
)         
所以简单来说 - 尝试将您的字段分成多个嵌套的case类,这样您的问题应该就会消失(并且有改进可读性的好处)。如果您这样做,接近元组/ case类限制几乎永远不会是问题(甚至不需要使用HList)。

太好了,这正是我们用于其他模型的内容。但是,如果结果也来自过程,我可以这样做吗?我能将过程的结果放入扩展Table类的类中吗? - user836845
当涉及到 Slick 时,它只是一个查询结果。 - Paul Dolega
我能否将一个过程的结果获取到扩展Table类的类中?如果可以,那太棒了。 - user836845
这是一个令人困惑的问题 - Table类用于指定映射,而不是表示实际的数据库元组。通常你会有一对:继承Table类(映射定义)的类和一个用于表示数据库元组的case class(它不需要是case class,但大多数情况下都是)。 - Paul Dolega
是的,我们使用生成器自动为所有表执行此操作。我们根据自己的需求进行了修改,并且它运行得非常好。但是对于存储过程的结果,我只是使用了一个简单的case class,它也运行得非常好。 - user836845

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接