我正在使用带有Play Framework 2.1 的Slick ,但遇到了一些麻烦。
给定以下实体...
package models
import scala.slick.driver.PostgresDriver.simple._
case class Account(id: Option[Long], email: String, password: String)
object Accounts extends Table[Account]("account") {
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
def email = column[String]("email")
def password = column[String]("password")
def * = id.? ~ email ~ password <> (Account, Account.unapply _)
}
...我必须为特定的数据库驱动程序导入一个包,但我想在生产中使用H2进行测试和PostgreSQL。我应该如何进行?
我可以通过覆盖单元测试中的驱动程序设置来解决此问题:
package test
import org.specs2.mutable._
import play.api.test._
import play.api.test.Helpers._
import scala.slick.driver.H2Driver.simple._
import Database.threadLocalSession
import models.{Accounts, Account}
class AccountSpec extends Specification {
"An Account" should {
"be creatable" in {
Database.forURL("jdbc:h2:mem:test1", driver = "org.h2.Driver") withSession {
Accounts.ddl.create
Accounts.insert(Account(None, "user@gmail.com", "Password"))
val account = for (account <- Accounts) yield account
account.first.id.get mustEqual 1
}
}
}
}
我不喜欢这个解决方案,我想知道是否有一种优雅的方式来编写与 DB 无关的代码,因此使用了两种不同的数据库引擎——一个用于测试,另一个用于生产?
我也不想使用进化,更喜欢让 Slick 为我创建数据库表:
import play.api.Application
import play.api.GlobalSettings
import play.api.Play.current
import play.api.db.DB
import scala.slick.driver.PostgresDriver.simple._
import Database.threadLocalSession
import models.Accounts
object Global extends GlobalSettings {
override def onStart(app: Application) {
lazy val database = Database.forDataSource(DB.getDataSource())
database withSession {
Accounts.ddl.create
}
}
}
我第一次启动应用程序时,一切正常……当然,第二次启动应用程序时它崩溃了,因为表已经存在于 PostgreSQL 数据库中。
也就是说,我的最后两个问题是:
- 如何确定数据库表是否已经存在?
- 如何使上述
onStart
方法与 DB 无关,以便我可以使用 测试我的应用程序FakeApplication
?