【问题标题】:Slick 2.10-RC1, Scala 2.11.x, bypassing 22 arity limit with case class (heterogenous)Slick 2.10-RC1,Scala 2.11.x,使用案例类(异构)绕过 22 arity 限制
【发布时间】:2014-07-27 04:54:15
【问题描述】:

假设您有以下代码,我在将具有 > 22 列的表专门映射到 case class 时遇到问题

import slick.driver.PostgresDriver
import scala.slick.collection.heterogenous._
import syntax._
import shapeless.Generic

case class TwentyThreeCaseClass(
    val id:Option[Long],
    val one:String,
    val two:String,
    val three:String,
    val four:String,
    val five:String,
    val six:String,
    val seven:String,
    val eight:String,
    val nine:String,
    val ten:String,
    val eleven:String,
    val twelve:String,
    val thirteen:String,
    val fourteen:String,
    val fifteen:String,
    val sixteen:String,
    val seventeen:String,
    val eighteen:String,
    val nineteen:String,
    val twenty:String,
    val twentyOne:String,
    val twentyTwo:String,
    val twentyThree:String,
    val twentyFour:String
)

class TwentyThreeTable(tag:Tag) extends Table[TwentyThreeCaseClass](tag,"twenty_three_table") {
    def id = column[Long]("id",O.PrimaryKey,O.AutoInc)
    def one = column[String]("one")
    def two = column[String]("two")
    def three = column[String]("three")
    def four = column[String]("four")
    def five = column[String]("five")
    def six = column[String]("six")
    def seven = column[String]("seven")
    def eight = column[String]("eight")
    def nine = column[String]("nine")
    def ten = column[String]("ten")
    def eleven = column[String]("eleven")
    def twelve = column[String]("twelve")
    def thirteen = column[String]("thirteen")
    def fourteen = column[String]("fourteen")
    def fifteen = column[String]("fifteen")
    def sixteen = column[String]("sixteen")
    def seventeen = column[String]("seventeen")
    def eighteen = column[String]("eighteen")
    def nineteen = column[String]("nineteen")
    def twenty = column[String]("twenty")
    def twentyOne = column[String]("twentyOne")
    def twentyTwo = column[String]("twentyTwo")
    def twentyThree = column[String]("twentyThree")
    def twentyFour = column[String]("twentyFour")

    private def iso[L <: HList, M <: HList](l: L)
                                 (implicit iso: Generic.Aux[TwentyThreeCaseClass, M], eq: L =:= M): TwentyThreeCaseClass = iso.from(l)

    def * =
        id.? ::
        one ::
        two ::
        three ::
        four ::
        five ::
        six ::
        seven ::
        eight ::
        nine ::
        ten ::
        elven ::
        twelve ::
        thirteen ::
        fourteen ::
        fifteen ::
        sixteen ::
        seventeen ::
        eighteen ::
        nineteen ::
        twenty ::
        twentyOne ::
        twentyTwo ::
        twentyThree ::
        twentyFour ::
        HNil
        // Do stuff here to map to a case class

}

您将如何将表构造/提取到TwentyThreeCaseClass 中。给出了如何将光滑的Table 映射到 HList 的示例代码,但没有给出关于如何通过 HList 将 Table 映射到案例类 > 22 个参数的代码(您不能使用元组,因为Scala 中的数量限制仍然适用于元组,你不能创建一个包含超过 22 个元素的元组)

iso 就在那里,因为我们使用这个通用的 iso 代码从 HList 映射到 case class,在我们的无形代码中具有相同的形状,所以理论上你应该能够使用iso 从HList 构造案例类,我只是不知道如何在光滑形状的上下文中使用iso

编辑: 在 slick github 上提出了与https://github.com/slick/slick/issues/519#issuecomment-48327043 中的问题相同的问题@

【问题讨论】:

    标签: scala slick case-class shapeless


    【解决方案1】:

    想通了,虽然它很丑,因为它不是通用的。

    def * =
        (id.? ::
        one ::
        two ::
        three ::
        four ::
        five ::
        six ::
        seven ::
        eight ::
        nine ::
        ten ::
        elven ::
        twelve ::
        thirteen ::
        fourteen ::
        fifteen ::
        sixteen ::
        seventeen ::
        eighteen ::
        nineteen ::
        twenty ::
        twentyOne ::
        twentyTwo ::
        twentyThree ::
        twentyFour ::
        HNil).shaped <>
              ({case x => TwentyThreeCaseClass(
                x(0),
                x(1),
                x(2),
                x(3),
                x(4),
                x(5),
                x(6),
                x(7),
                x(8),
                x(9),
                x(10),
                x(11),
                x(12),
                x(13),
                x(14),
                x(15),
                x(16),
                x(17),
                x(18),
                x(19),
                x(20),
                x(21),
                x(22),
                x(23),
                x(24)
                )}, ({x:TwentyThreeCaseClass =>
                Option((
                  x.id ::
                  x.one ::
                  x.two ::
                  x.three ::
                  x.four ::
                  x.five ::
                  x.six ::
                  x.seven ::
                  x.eight ::
                  x.nine ::
                  x.ten ::
                  x.eleven ::
                  x.twelve ::
                  x.thirteen ::
                  x.fourteen ::
                  x.fifteen ::
                  x.sixteen ::
                  x.seventeen ::
                  x.eighteen ::
                  x.nineteen ::
                  x.twenty ::
                  x.twentyOne ::
                  x.twentyTwo ::
                  x.twentyThree ::
                  x.twentyFour ::
                  HNil
                ))
              }))
    

    原来有几件事

    1. 这与 shapeless 无关,Slick 使用自己的 HList 实现(与 shapeless 的语法完全相同!)
    2. 据我所知,Slick HList 似乎没有任何通用方法来处理诸如映射到 case class(以及从案例类到 Slick `HLIst)之类的东西
    3. 将 Slick Hlist 转换为无形状 HList 的库会很方便,或者 Slick Hlist 的通用功能。前者可能是更好的选择,因为 shapeless 已经比 Slick 做得更好,而且它可能超出了 Slicks 的范围

    做类似的事情

    def gen = Generic[TwentyThreeCaseClass]
    ...
    .shaped <>
          ({case x => gen.from(x)}, {TwentyThreeCaseClass => Option(gen.to(x))})
    

    会更理想

    这里还有一个例子

    https://github.com/playframework/play-slick/issues/214

    【讨论】:

    • 您可以将x.apply(1) 缩短为x(1)
    • @mdedetrich 这样的代码确实让我质疑 Slick 作为现实世界、数据库密集型应用程序的可行选择。它似乎造成了混乱,并且缺少许多必需的功能(fetch-size/batch-size、乐观/悲观锁定、事务传播等......)
    猜你喜欢
    • 2013-12-28
    • 2014-06-27
    • 2014-09-03
    • 2017-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多