22 ограничение по колонке для процедур


Как мы можем преодолеть ограничение 22 при вызове процедур с помощью Slick?

В настоящее время мы имеем:

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

Проблема в том, что мы должны возвращать более 22 столбцов, а класс Transaction case не может иметь более 22 столбцов, так как при выполнении JSONFormat мы получаем ошибку:

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

Есть предложения?

1 3

1 ответ:

Хорошо-так что если вы действительно можете изменить свой класс Transaction case, то есть лучшее решение, чем HList (которое, честно говоря, может быть немного громоздким, чтобы работать с ним позже).

Итак, вот что: давайте представим, что у вас есть User таблица со следующими атрибутами:

  • id
  • имя
  • фамилия
  • факультет
  • finalGrade
  • улица
  • число
  • город
  • почтовый индекс

Вышеуказанные столбцы могут не имеет смысла, но давайте использовать их в качестве примера. Самый простой способ разобраться с вышеизложенным-создать класс case:

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/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, и ваша проблема должна исчезнуть (с дополнительным преимуществом улучшенной читаемости). Если вы это сделаете, то приближение к пределу класса кортежа / случая практически никогда не будет проблемой (и вам даже не нужно использовать HList).