如何使用Scala为关系数据库链接表建模?

时间:2012-07-16 20:56:00

标签: scala scalaquery

我需要在Scala中进行很多对象的映射,并将其保存到关系数据库中。

这是一个简化问题的假例子:

假设我们想要为演讲室和学生建模。一个演讲室可能有很多学生,但这些学生也可以去不同的房间。从关系数据库模型的角度来看,您将创建3个表,一个用于ROOM,一个用于STUDENT,一个用于链接学生和房间,ROOM_STUDENT。

假设表格如下:

ROOM
-----
id
subject

STUDENT
-------
id
name

ROOM_STUDENT
-------------
room_id
student_id

如果我想使用Scala访问(并且可能创建)这样的数据库,那么如何使用ScalaQuery或SLICK来实现这一目标,或者是否有更好的Scala解决方案?我应该以某种方式使用case类,或者以某种方式使用普通的旧SQL吗?

我基本上希望这里有两个提示,1。在Scala中展示学生和房间的好方法,2。针对此问题的关系数据库持久性的一些想法。

1 个答案:

答案 0 :(得分:3)

我个人更喜欢Lift's Mapper library,并偶尔在Lift Web应用程序的上下文中使用它。以下是一个完整的工作示例,您可以从sbt运行,例如以下build.sbt

libraryDependencies ++= Seq(
  "net.liftweb" %% "lift-mapper" % "2.4" % "compile->default",
  "com.h2database" % "h2" % "1.2.127"
)

首先是模特:

import net.liftweb.common._, net.liftweb.mapper._

object Student extends Student with LongKeyedMetaMapper[Student]
class Student extends LongKeyedMapper[Student] with IdPK with ManyToMany {
  def getSingleton = Student
  object name extends MappedString(this, 40)
  object rooms extends MappedManyToMany(
    StudentRoom, StudentRoom.student, StudentRoom.room, Room
  )
}

object Room extends Room with LongKeyedMetaMapper[Room]
class Room extends LongKeyedMapper[Room] with IdPK with ManyToMany {
  def getSingleton = Room
  object subject extends MappedString(this, 40)
  object students extends MappedManyToMany(
    StudentRoom, StudentRoom.room, StudentRoom.student, Student
  )
}

object StudentRoom extends StudentRoom with LongKeyedMetaMapper[StudentRoom] {
  override def dbIndexes = Index(student, room) :: super.dbIndexes
}

class StudentRoom extends LongKeyedMapper[StudentRoom] with IdPK {
  def getSingleton = StudentRoom
  object student extends MappedLongForeignKey(this, Student)
  object room extends MappedLongForeignKey(this, Room)
}

一些数据库设置:

DB.defineConnectionManager(
  DefaultConnectionIdentifier,
  new StandardDBVendor("org.h2.Driver", "jdbc:h2:mem:example", Empty, Empty)
)

Schemifier.schemify(true, Schemifier.infoF _, Student, Room, StudentRoom)

还有一些数据:

val m = Student.create.name("Mary"); m.save
val j = Student.create.name("John"); j.save
val physics = Room.create.subject("Physics"); physics.save
StudentRoom.create.student(m).room(physics).save
StudentRoom.create.student(j).room(physics).save

我们准备好了:

scala> Room.findAll(By(Room.subject, "Physics")).flatMap(_.students)
res7: List[Student] = List(Student={name=Mary,id=2}, Student={name=John,id=3})