Scala Play Framework 2.1 Slick 1.0蛋糕模式公共表字段

Scala Play Framework 2.1 Slick 1.0蛋糕模式公共表字段,scala,slick,Scala,Slick,我正在从事一个使用Slick 1.0和cake模式连接到postgresql数据库的项目。 就目前而言,一切似乎都很好,但我有更多的表要添加,我意识到所有表都包含许多公共列。我希望能够创建一个包含公共字段的trait,但我不知道如何让它起作用。(我是scala的新手,但我认为我的基础知识掌握得很好。) 下面是一个例子,希望能说明我想做什么: 1.scala: package models.db.slick import java.util.UUID import play

我正在从事一个使用Slick 1.0和cake模式连接到postgresql数据库的项目。
就目前而言,一切似乎都很好,但我有更多的表要添加,我意识到所有表都包含许多公共列。我希望能够创建一个包含公共字段的trait,但我不知道如何让它起作用。(我是scala的新手,但我认为我的基础知识掌握得很好。)

下面是一个例子,希望能说明我想做什么:

1.scala:

    package models.db.slick
    import java.util.UUID
    import play.api.db.slick.Profile
    case class One(common1:UUID, common2:String, unique1:String)
    trait OneComponent{this: Profile =>
      import profile.simple._
      object Ones extends Table[One]("One") with CommonColumns{
        def unique1 = column[String]("unique1")
        def * = common1 ~ common2 ~ unique1 <> (One.apply _, One.unapply _)
      }
    }
这不会编译,因为ColumnColumns特性不知道column[t]。我尝试指定一个表的自类型,但我不知道如何访问scala.slick.driver.BasicTableComponent特性中的表对象。我还尝试指定一个实现列函数的self类型,如:

    trait CommonColumns{ this => {def column[C](n: String, options:    
                                   scala.slick.lifted.ColumnOption[C]* )
                                   (implicit tm:scala.slick.lifted.TypeMapper[C]
                                    ): scala.slick.lifted.Column[C]}
    ...
    }
但这不起作用。我很可能在这一点上的语法错误,但我找不到一个好的例子如何做到这一点

你觉得怎么样?有什么好办法可以解决这个问题吗?

我想出来了! 至少我认为我做到了。如果有人发现这有什么问题,请告诉我

好的,我是这样做的:

我将CommonColumns特性更改为:

    trait CommonColumnsComponent{ this:Profile =>
      import profile.simple._
      trait CommonColumns{ this:Table[_] =>
        def common1 = column[UUID]("common1")
        def common2 = column[String]("common2")
      }
    }
然后我将一个组件更改为:

    trait OneComponent extends CommonColumnsComponent{this: Profile =>
      import profile.simple._
      object Ones extends Table[One]("One") with CommonColumns{
        def unique1 = column[String]("unique1")
        def * = common1 ~ common2 ~ unique1 <> (One.apply _, One.unapply _)
      }
    }
trait-OneComponent扩展了CommonColumnsComponent{this:Profile=>
导入profile.simple_
对象扩展表[One](“One”)的公共列{
def unique1=列[字符串](“unique1”)
def*=common1~common2~unique1(1.apply,1.unapply)
}
}

它成功了。

还没有测试,但似乎CommonColumns必须扩展表[t]或将其自身类型声明为表[t]。是的,这是我尝试过的,但我不知道如何实际指定它是表[t]类型。它表示找不到类型表。在“Ones”中,我得到了参考表[T],因为OneComponent是一个自我类型的概要文件。然后,当试图找到表[T]的定义位置时,它是trait scala.slick.driver.BasicTableComponent中的一个对象,我不知道如何在CommonColumns中使用它。我很确定这只是我缺乏scala方面的知识。我刚刚意识到我一直在说Table[T]是Trait中的一个对象,但实际上它是Trait中的一个抽象类。因此,如果我试图说CommonColumns是一种自我类型的slick.driver.BasicTableComponent.Table[T],我会得到一个信息,即BasicTableComponent是一种没有伴随对象的特性,我几乎就是这样做的
trait CommonColumns[T]{this:Table[T]…
…用CommonColumns[One]扩展表[One](“One”){…
。我不确定,但您的解决方案似乎会错过其他可以在两个类之间共享的有趣的抽象。因此,我认为您的意思是,我不应该将CommonColumns特性限制为我将其混合到的表的一部分。对吗?我确实看到了在技术上比是的,但我想不出任何我想要的情况。让…用CommonColumns[2]{…,扩展表[1](“1”)意味着什么?CommonColmns[X]的一个简单用例:一个接收common1或2并返回X的查询,使用[u]不能在CommonColumns中实现。对于
扩展表[1](“1”)对于CommonColumns[Two]{
,如果1和2之间存在正确的继承关系,那么它将起作用(很可能-我记不起本例中的差异限制)。啊,好的。那么,我可以让CommonColumns根据我发送的类型设置不同的公共字段。
    trait OneComponent extends CommonColumnsComponent{this: Profile =>
      import profile.simple._
      object Ones extends Table[One]("One") with CommonColumns{
        def unique1 = column[String]("unique1")
        def * = common1 ~ common2 ~ unique1 <> (One.apply _, One.unapply _)
      }
    }