加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 以干式方式扩展SLICK表

发布时间:2020-12-16 19:03:32 所属栏目:安全 来源:网络整理
导读:我有一个关于Slick / Scala的有趣的问题,我希望你们中的一个可以帮助我. 我在SLICK案例类中有几个表和扩展名 case class A(...)case class B(...)case class C(...) 这些共同的领域 (id: String,livemode: Boolean,created: DateTime,createdBy : Option[Acc
我有一个关于Slick / Scala的有趣的问题,我希望你们中的一个可以帮助我.

我在SLICK案例类中有几个表和扩展名

case class A(...)
case class B(...)
case class C(...)

这些共同的领域

(id: String,livemode: Boolean,created: DateTime,createdBy : Option[Account]) .

因为这些字段在每个案例类中都是重复的,所以我想探索将它们提取到单个对象或类型中的可能性.

然而,当创建SLICK表对象时,我希望结束这些常见字段的包含,因此我可以在每个表中保留其各自的值.

object AsTable extends Table[A]("a_table") { 
  ...
  def id = column[String]("id",O.PrimaryKey)
  def livemode = column[Boolean]("livemode",O.NotNull)
  def created = column[DateTime]("created",O.NotNull)
  def createdBy = column[Account]("created_by",O.NotNull)
  ... 
}

有效地,我正在寻找的最终结果是允许我更改公共字段,而不必更新每个表.

有没有办法做到这一点?

提前致谢

解决方法

我没有尝试过这个,但是你的混合特性如何?

trait CommonFields { this: Table[_] =>
  def id = column[String]("id",O.NotNull)

  protected common_* = id ~ livemode ~ created ~ createdBy 
}

那你可以做:

object AsTable extends Table[(String,Boolean,DateTime,Account,String)]("a_table") 
    with CommonFields { 
  def foo = column[String]("foo",O.NotNull)
  def * = common_* ~ foo
}

现在唯一需要重复的是元素的类型.

UPDATE

如果你想做对象映射和:

>你映射到案例类
>您的案例类中的字段的顺序相同

做就是了:

case class A(
    id: String,createdBy: Account,foo: String)

object AsTable extends Table[A]("a_table") with CommonFields { 
  def foo = column[String]("foo",O.NotNull)
  def * = common_* ~ foo <> (A.apply _,A.unapply _)
}

这似乎是最经济的解决方案(而不是试图在CommonFields中定义*并添加一个类型参数).但是,如果您的字段更改,则需要更改所有案例类.

我们可以尝试通过在案例类中使用组合来缓解这一点:

case class Common(
    id: String,createdBy: Account)

case class A(
    common: Common,foo: String)

然而,在构建mapper函数时,我们将(某处)最终必须转换以下形式的元组:

(CT_1,CT_2,... CT_N,ST_1,ST_2,...,ST_M)

CT通用型(CommonFields中已知)
ST特定类型(在AsTable中已知)

至:

(CT_1,... CT_N),(ST_1,ST_M)

为了将它们传递给子程序,将Common和A单独转换为它们的元组.

我们必须这样做,而不必知道CT(在AsTable中实现)或ST(在CommonField中实现时)的数量或确切类型. Scala标准库中的元组无法做到这一点.您将需要使用HList作为shapeless提供的示例来执行此操作.

这是值得的努力是值得怀疑的.

基本大纲可能看起来像这样(不需要所有隐含的混乱).这段代码不会像这样编译.

trait CommonFields { this: Table[_] =>
  // like before

  type ElList = String :: Boolean :: DateTime :: Account :: HNil

  protected def toCommon(els: ElList) = Common.apply.tupled(els.tupled)
  protected def fromCommon(c: Common) = HList(Common.unapply(c))
}

object AsTable extends Table[A] with CommonFields {
  def foo = column[String]("foo",O.NotNull)

  def * = common_* ~ foo <> (x => toA(HList(x)),x => fromA(x) tupled)

  // convert HList to A
  protected def toA[L <: HList](els: L) = {
    // Values for Common
    val c_els = els.take[Length[ElList]]
    // Values for A
    val a_els = toCommon(c_els) :: els.drop[Length[ElList]]

    A.apply.tupled(a_els.tupled)
  }

  // convert A to HList
  protected def fromA(a: A) =
    fromCommon(a.common) :: HList(A.unapply(a)).drop[One]

}

使用更多类型的魔法,您可以解决最后两个问题:

>将A和fromA放入基本特征(通过使用trait中的类型参数,或使用抽象类型成员)
>避免通过使用this technique从Common.apply中提取它来显式定义ElList

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读