scala – 以干式方式扩展SLICK表
我有一个关于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中已知) 至: (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中的类型参数,或使用抽象类型成员) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |