【问题标题】:Mapping Slick SQL Query results to case classes将 Slick SQL 查询结果映射到案例类
【发布时间】:2015-11-14 16:24:16
【问题描述】:

我有一个由多个连接/左连接组成的复杂 sql 查询,其结果类型如下所示:

val query = sql"""
     // body of query
   """.as[(Long, String, String, Int, Long, Long, String, Int, Option[Int], Option[Int], Option[String], Option[Timestamp], Option[Timestamp])]

运行此查询的结果是具有 10 多个属性的元组列表。 处理该列表以生成案例类:

 db.run(query).map(_.groupBy { case (p1, p2, p3, p4, _, _, _, _, _, _, _, _, _) =>
  (p1, p2, p3, p4)
 }.map { case ((o1, co2, o3, o4), o5) =>
  CaseClass1(o1, co2, o3, Seq(o4), o5.groupBy {
    case (_, _, _, _, u1, _, _, _, _, _, _, _, _) => u1
  }.map { case (t1, t2) =>
    CaseClass2(t1, t2.flatMap {
      case (_, _, _, _, _, _, _, _, Some(n1), Some(n2), Some(n3), Some(n4), Some(n5)) => Some(CaseClass3(n1, n2, n3, n4, n5))
      case _ => None
    }, t2.map {
      case (_, _, _, _, _, m1, m2, m3, _, _, _, _, _) => CaseClass4(m1, m2, m3, l1)
    })
  }.toSeq)
}

将结果集映射到案例类本身的过程不是很可扩展,每次添加要从查询中选择的新属性时都让我头疼。有没有更简单的方法将结果集映射到案例类?

【问题讨论】:

    标签: sql scala slick


    【解决方案1】:

    是的,当然有。

    首先创建一个案例类来替换你的元组,我们称之为MyMatch

    case class MyMatch( p1: Long, p2: String ...)
    

    然后,创建一个GetResult 并使用此类检索您的结果

    implicit val getMyMatch = GetResult(r => MyMatch(r.<<, r.<<, r.<<, ...)
    
    
    val query = sql"""
         // body of query
       """.as[MyMatch]
    

    然后您可以将 groupBy 与新的案例类属性一起使用。

    db.run(query).map(_.groupBy { x => (x.p1, x.p2, x.p3, x.p4) }
    

    平面图可以变成

    flatMap { x => for { n1 <- x.n1; n2 <- x.n2 ...} yield CaseClass3(n1, n2, ...) }
    

    【讨论】:

    • 您不需要GetResult[MyMatch] 才能使用吗?
    • 是的,但这比 (_, _, _) 的长列表更容易维护。我会编辑添加这个
    • 这看起来很棒!我会试一试,然后告诉你进展如何。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-13
    • 2011-01-06
    • 2018-08-16
    • 1970-01-01
    • 2021-08-13
    • 2013-01-14
    • 1970-01-01
    相关资源
    最近更新 更多