【问题标题】:Generic CRUD operations using Slick 2.0使用 Slick 2.0 的通用 CRUD 操作
【发布时间】:2014-03-11 22:28:33
【问题描述】:

我正在尝试为 Slick 2.0 编写一个通用的 CRUD 特征。 trait 应该 a) 提供通用方法来读取/更新/删除实体以及 b) 从数据库中抽象。在this slick example(数据库抽象)和this article(CRUD trait)之后,我想出了以下(缩短的)代码sn-p:

trait Profile {
  val profile: JdbcProfile
}

trait Crud[T <: AbstractTable[A], A] { this: Profile =>
  import profile.simple._

  val qry: TableQuery[T]

  def countAll()(implicit session: Session): Int = {
    qry.length.run
  }

  def getAll()(implicit session: Session): List[A] = {
      qry.list // <-- type mismatch; found: List[T#TableElementType] required: List[A]
  }
}

由于类型不匹配,代码无效。第二个函数的返回类型似乎是 List[T#TableElementType] 类型,但需要是 List[A]。关于如何解决问题的任何想法。也欢迎对通用 Slick 2.0 操作的进一步阅读提供其他参考。

【问题讨论】:

  • 如果你使用Table而不是AbstractTable,它会起作用,但为此,你需要一个具体的Profile。我很困惑 slick 2.0 中的配置文件是如何使用的。

标签: scala crud slick slick-2.0


【解决方案1】:

type TableElementTypeclass AbstractTable[A] 内部的抽象。 Scala 不知道ATableElementType 之间的任何关系。另一方面,class Table 定义了final type TableElementType = A,它告诉 Scala 这种关系(显然 Scala 足够聪明,可以使用final 注释知道这种关系甚至适用于子类型T &lt;: Table[A],尽管Table[A] 是在A 中不是协变的)。

所以你需要使用T &lt;: Table[A] 而不是T &lt;: AbstractTable[A]。而且因为Table 在 Slick driver cake 中(如蛋糕模式中),您还需要将 Crud 移动到蛋糕中。蛋糕是病毒式的。

trait Profile {
  val profile: JdbcProfile
}
trait CrudComponent{ this: Profile =>
  import profile.simple._

  trait Crud[T <: Table[A], A] {

    val qry: TableQuery[T]

    def countAll()(implicit session: Session): Int = {
      qry.length.run
    }

    def getAll()(implicit session: Session): List[A] = {
        qry.list // <-- works as intended
    }
  }
}

【讨论】:

    猜你喜欢
    • 2014-06-14
    • 2015-06-01
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    • 2023-03-20
    • 2015-03-28
    • 1970-01-01
    • 2016-08-03
    相关资源
    最近更新 更多