将 DBIO 值转换为自定义大小写 Class
Transform DBIO Value to Custom Case Class
我有一个 DBIO[Seq[tuple]]
,我想将它映射到 DBIO[Seq[customCaseClass]]
。
我知道我可以对 db.run()
结果进行转换,例如:customCaseClass.tupled(row)
(see this answer)。但是,我有兴趣在不同的函数中组合 DBIO
return 值。
您可以在三个地方执行此操作:在 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 * ...
) 可能就是这样做的地方。
如果您需要对转换逻辑进行更多控制,可以使用较低级别的 <>
代替 mapTo
。 Section 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))
)。
您在此级别获得的两大好处是:
- 您可以访问这些值,例如
(a,b)
,因此可以决定要对这些值执行的操作。
- 成为行动的一部分意味着您可以参与交易。
Chapter 4 of Essential Slick lists out many of the DBIO combinators. The Slick Manual 也描述了组合器。
未来
最后一个位置在 Future
中,它看起来非常像 DBIO
版本,但在 db.run
之后(如您所见)。
我有一个 DBIO[Seq[tuple]]
,我想将它映射到 DBIO[Seq[customCaseClass]]
。
我知道我可以对 db.run()
结果进行转换,例如:customCaseClass.tupled(row)
(see this answer)。但是,我有兴趣在不同的函数中组合 DBIO
return 值。
您可以在三个地方执行此操作:在 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 * ...
) 可能就是这样做的地方。
如果您需要对转换逻辑进行更多控制,可以使用较低级别的 <>
代替 mapTo
。 Section 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))
)。
您在此级别获得的两大好处是:
- 您可以访问这些值,例如
(a,b)
,因此可以决定要对这些值执行的操作。 - 成为行动的一部分意味着您可以参与交易。
Chapter 4 of Essential Slick lists out many of the DBIO combinators. The Slick Manual 也描述了组合器。
未来
最后一个位置在 Future
中,它看起来非常像 DBIO
版本,但在 db.run
之后(如您所见)。