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 ответ:
Хорошо-так что если вы действительно можете изменить свой класс
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
).