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

scala – 映射投影与SLICK中的伴侣对象

发布时间:2020-12-16 18:59:57 所属栏目:安全 来源:网络整理
导读:我有嵌套类/对象,并希望通过使用SLICK将它们存储(并检索)到数据库中.我知道用SLICK映射的投影将是关键.此外,我使用一个伴随对象来映射嵌套对象和平面结构(要存储在数据库表中).我想做这样的事情(简化的例子): case class Foo(id: Int,myBar: Bar)case class
我有嵌套类/对象,并希望通过使用SLICK将它们存储(并检索)到数据库中.我知道用SLICK映射的投影将是关键.此外,我使用一个伴随对象来映射嵌套对象和平面结构(要存储在数据库表中).我想做这样的事情(简化的例子):

case class Foo(id: Int,myBar: Bar)

case class Bar(myInt: Int,myString: String)

object Foo {
  def apply(id: Int,myInt: Int,myString: String): Foo = Foo(id,Bar(myInt,myString))

  override def unapply(f: Foo) = (f.id,f.myBar.myInt,f.myBar.myString)
}

object TTable extends Table[Foo]("FOO") {
    def id = column[Int]("id",O.PrimaryKey)
    def myInt = column[Int]("myInt",O NotNull)
    def myString = column[String]("myString",O NotNull)

    def * = id ~ myInt ~ myString <> (Foo.apply _,Foo.unapply _)

    def query(db: Database,id: Int): Option[Foo] = db withSession { //s: Session =>
        (for { b <- TTable if b.id is id} yield b).firstOption
    }
}

但是编译失败,出现了几个错误:“方法未应用定义两次”,“重载定义的模糊引用,两种方法适用[…]匹配预期类型?和“替代方法的过载方法值”

我发现这个映射投影“scala slick method I can not understand so far”和“Mapped projection with <> to a case class with companion object in Slick”的很好的解释,但没有一个建议的解决方案适用于我.

解决方法

而不是取消应用和申请,你可以通过做你想做的羊羔

def * = id ~ myInt ~ myString <> (
    (id,myInt,myString) => Foo(id,myString)),/* from a row to a Foo */
    (f:Foo) => Some((f.id,f.myBar.myString)) /* and back */)

这样,从表格到案例类的映射就停留在表的定义中,case类保持为简单的case类,这不是太糟糕.

另一种方式是不要为Foo使用一个case类,而是使用一个常规类,这样可以让你自由地在一个配对对象中定义你自己的应用和取消应用,如下所示:

// untested code
class Foo private (val id: Int,val myBar: Bar) 
case class Bar(myInt: Int,myString: String)
object Foo {
  def apply(id: Int,myString: String): Foo = new Foo(id,myString))
  def unapply(f: Foo) = Some((f.id,f.myBar.myString))
}

如果你想做def * = id?myInt?myString<> (Foo.apply _,Foo.unapply _)

你会在某种程度上得到类别的用法,但你可能会错过其他好的东西
像实际案例类一样平等和toString是免费的.
我宁愿保留案例类(并且其默认值应用于未应用程序),以便它们可以按照常规约定被视为代数数据类型.

这里的真正问题是这种情况,类有自己的未应用程序,所以你不能(据我所知)在同伴类中有一个类似的方法(同名和相同的参数).
您只需使用其他方法名称即可.毕竟,你想做的不是
无论如何,语义上相当于取消应用:

object Foo {
  def fromRow(id: Int,myString))
  def toRow(f: Foo) = Some((f.id,f.myBar.myString))
}

然后在你的表格中:

def * = id ~ myInt ~ myString <> (Foo.fromRow _,Foo.toRow _)

(编辑:李大同)

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

    推荐文章
      热点阅读