将DBIO值转换为自定义案例类

时间:2018-09-17 21:43:19

标签: scala slick

我有一个DBIO[Seq[tuple]],我想将其映射到DBIO[Seq[customCaseClass]]

我知道我可以对db.run()结果进行转换,例如:customCaseClass.tupled(row)see this answer)。但是,我有兴趣在各种函数中组成DBIO返回值。

1 个答案:

答案 0 :(得分:1)

您可以在三个地方进行此操作:Query级别,DBIO级别,以及Future级别(如您所指出并拒绝的)。

查询

在查询级别,转换将作为在Slick自己的执行上下文上执行查询的一部分进行。

它看起来像这样:

// Given some query that returns a tuple...
val tupleQ: Query[(Rep[String],Rep[String]), (String,String), Seq] =
   table.map{ row => (row.column1, row.column2) }

// ...which we'd like to project into this:
case class SomeCaseClass(v1: String, v2: String)

// ...we can use the mapTo macro to generate the conversion:
val ccQ: Query[Rep[SomeCaseClass], SomeCaseClass, Seq] =
   tupleQ.map{ _.mapTo[SomeCaseClass] }

如果这就是您要做的一切,那么也许可以使用默认投影(def * ...)。

如果您需要对转换逻辑的更多控制,则可以使用较低级别的<>代替mapToSection 5.2 of Essential Slick对此提供了更多详细信息。

DBIO

问题特别是关于DBIO。那里的转换将在您自己的执行上下文中运行。

这看起来像这样:

// Given a DBIO that returns a tuple...
val tupleD: DBIO[Seq[(String,String)]] =
  table.map(row => (row.column1, row.column2)).result

// ... we can use any of the DBIO combinators to convert it, such as map:
val ccD: DBIO[Seq[SomeCaseClass]] =
  dQ.map{ pairs => pairs.map{ case (a, b) => SomeCaseClass(a,b) } }

(...或您注意到的dQ.map(pairs => pairs.map(SomeCaseClass.tupled))。)

在此级别上获得的两个大好处是:

  1. 您可以访问值,例如(a,b),因此可以决定要使用这些值做什么。
  2. 参与某项行动意味着您可以参与交易。

Chapter 4 of Essential Slick列出了许多DBIO组合器。 Slick Manual还描述了组合器。

未来

最后一个地方是Future,它看起来很像DBIO版本,但在db.run之后(如您所见)。