例如,我有一些带有一些参数的实体,以及两个表示该实体的数据库表:
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
是字符串的Seq,而不仅仅是String :
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
实例。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]
谢谢。
答案 0 :(得分:3)
您的案例类Entity
希望params
与id和name列一起分组为字符串列表,
而sql查询select e.id, e.name, p.value from entity e left join param p on e.id = p.entity_id
将返回包含ID,名称和值
joined entity
╔════╦═════════╦════════╗
║ id ║ name ║ value ║
╠════╬═════════╬════════╣
║ 1 ║ "One" ║ "aaa" ║
║ 1 ║ "One" ║ "bbb" ║
║ 1 ║ "One" ║ "ccc" ║
║ 2 ║ "Two" ║ ║
║ 3 ║ "Three" ║ ║
╚════╩═════════╩════════╝
这不是您想要的。 为此,我们需要像下面的
一样重写sql查询val entities = sql"select e.id, e.name, GROUP_CONCAT(p.value SEPARATOR ',') as params from entity e left join param p on e.id = p.entity_id group by e.id, e.name".query[Entity]
现在,您可以轻松地将sql查询输出映射到案例类。