例如,我有一些带有一些参数的实体,以及两个表示该实体的数据库表:
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]
可能没有通过单个查询获得的性能。 - 还有其他方法吗?
谢谢。