光滑和嵌套案例类别没有?

时间:2014-06-27 23:02:32

标签: scala playframework playframework-2.0 slick slick-2.0

我正在使用slick(和播放框架)在现有数据库之上构建应用程序。我无法改变数据库结构。

我的数据库有以下两个表:

会议:

  • id(PK)
  • 名称
  • chairman_id(FK to Person.id)
  • houseman_id(FK to Person.id)

人:

  • id(pk)
  • 如first_name
  • 姓氏

我想像我这样定义我的案例类:

case class Meeting (
  id: Int,
  name: String,
  chairman: Person,
  houseman: Person
) 

case class Person (
   id: Int,
   firstName: String,
   lastName: String
)

但是从这个非常简单的光滑文档中,看起来我必须将id保留在case类中而不是使用“Person”。那是对的吗?

对此最好的方法是什么?抱歉相对开放的问题,scala,光滑和游戏都很新。

谢谢,

1 个答案:

答案 0 :(得分:1)

你有外键,他们没有翻译成案例类,他们翻译成ids:

case class Meeting (
  id: Int,
  name: String,
  chairmanId: Int,
  housemanId: Int) 

 case class Person (
  id: Int,
  firstName: String,
  lastName: String)

架构将类似于:

 case class Meeting (
                   id: Int,
                   name: String,
                   chairmanId: Int,
                   housemanId: Int)

 case class Person (
                  id: Int,
                  firstName: String,
                  lastName: String)


class Meetings(tag: Tag) extends Table[Meeting](tag, "meeting") {
  def * = (id, name, chairmanId, housemanId) <>(Meeting.tupled, Meeting.unapply)

  def ? = (id.?, name, chairmanId, housemanId).shaped.<>({
    r => import r._
      _1.map(_ => Meeting.tupled((_1.get, _2, _3, _4)))
  }, (_: Any) => throw new Exception("Inserting into ? projection not supported."))

  val id: Column[Int] = column[Int]("id", O.AutoInc, O.PrimaryKey)
  val name: Column[String] = column[String]("name")
  val chairmanId: Column[Int] = column[Int]("chairmanId")
  val housemanId: Column[Int] = column[Int]("housemanId")

  lazy val meetingChairmanFk =
    foreignKey("meeting_chairman_fk", chairmanId, persons)(r => r.id, onUpdate = ForeignKeyAction.Restrict, onDelete = ForeignKeyAction.Cascade)


  lazy val meetingHousemanFk =
    foreignKey("meeting_houseman_fk", housemanId, persons)(r => r.id, onUpdate = ForeignKeyAction.Restrict, onDelete = ForeignKeyAction.Cascade)


}

lazy val meetings = new TableQuery(tag => new Meetings(tag))

class Persons(tag: Tag) extends Table[Person](tag, "person") {
  def * = (id, firstName, lastName) <>(Person.tupled, Person.unapply)

  def ? = (id.?, firstName, lastName).shaped.<>({
    r => import r._
      _1.map(_ => Person.tupled((_1.get, _2, _3)))
  }, (_: Any) => throw new Exception("Inserting into ? projection not supported."))

  val id: Column[Int] = column[Int]("id", O.AutoInc, O.PrimaryKey)
  val firstName: Column[String] = column[String]("firstname")
  val lastName: Column[String] = column[String]("lastname")


}

lazy val persons = new TableQuery(tag => new Persons(tag))

它可以像这样使用:

val thisMeeting = meetings.filter(_.name === "thisMeeting").join(persons).on((m, p) => m.housemanId === p.id || m.chairmanId === p.id).list()

或者用于理解(我个人觉得更清晰):

val thatMeething = (for {
  m <- meetings
  p <- persons if (p.id === m.chairmanId || p.id === m.housemanId) && m.name === "thatMeeting"
} yield m.id).run

请注意,第二个查询对应于隐式内部联接,也支持其他类型的联接,您可以找到它们here