Например, у меня есть несколько сущностей с некоторыми параметрами и две таблицы базы данных, представляющие эти сущности:
entity param
╔════╦═════════╗ ╔═══════════╦════════╗
║ id ║ name ║ ║ entity_id ║ value ║
╠════╬═════════╣ ╠═══════════╬════════╣
║ 1 ║ "One" ║ ║ 1 ║ "aaa" ║
║ 2 ║ "Two" ║ ║ 1 ║ "bbb" ║
║ 3 ║ "Three" ║ ║ 1 ║ "ccc" ║
╚════╩═════════╝ ╚═══════════╩════════╝
И модель scala:
case class Entity(id: Long, name: String, params: Seq[String])
И я хочуполучить эти данные через Doobie
, но я не могу сделать это напрямую с экземпляром Entity
, потому что params
- это последовательность строк, а не просто строка:
val sql = sql"select e.id, e.name, p.value from entity e left join param p on e.id = p.entity_id"
sql.query[Entity].to[Seq] //Error Cannot find or construct a Read instance for type: Entity
Где-нибудьтрюк для предоставления Get
экземпляра для Seq
?
Если нет, то какой способ, Doobie
предлагает получить такие данные:
- Записывать примитивы вместо
Entity
введите:
sql.query[(Long, String, String)].to[Seq]
и скомпонуйте этот Seq кортежей с экземпляром Entity
.
Потенциально не удобно, потому что в таблицах может быть много столбцов, что приводит к копированию этого длинного кортежа в каждый новыйquery. - Составьте эти примитивы для аннотаций классов дел:
case class EntityRow(id: Long, name: String)
case class ParamRow(value: String)
sql.query[(EntityRow, ParamRow)].to[Seq]
и составьте для экземпляра Entity
, как в 1.
. - Как и
2.
, но с использованием HNil
:
val entity = Long :: String :: HNil
val param = String :: HNil
sql.query[entity ++ param].to[Seq]
и составление в Entity
например, как 1.
.
Я не знаю никаких преимуществ или недостатков этого способа, так как shapeless
для меня новость. - Извлечение данных двумя отдельными запросами:
val entities = sql"select id, name from entity".query[EntityRow].to[Seq]
val params = sql"select value from param".query[ParamRow].to[Seq]
Скорее всего, не такой, как с помощью одного запроса. - Как-нибудь иначе?
Спасибо.