在 Play 2.4 和更新版本中,slick 插件不再创造进化。为此,我在开发模式中添加了一个页面,该页面始终显示浏览器中所有演变的最新版本。这种方法与模块系统中所有即将发生的变化兼容,因为它不使用任何模块。使用依赖注入,它完全使用您在 application.conf 文件中配置的 Slick 数据库驱动程序
我在 config/routes 中添加了以下行:
GET /evolutions.sql controllers.SchemaEvolutionsController.evolutions
然后我创建了一个控制器(app/controllers/SchemaEvolutionsController.scala)
package controllers
import com.google.inject.Inject
import dao.CatDao
import models.HasSchemaDescription
import models.HasSchemaDescription.SqlSchemaDescription
import play.api.Environment
import play.api.mvc.{Action, Controller}
import play.api.Mode
class SchemaEvolutionsController @Inject() (environment: Environment, catDao : CatDao) extends Controller {
def allSchemas : Seq[HasSchemaDescription] = List(catDao) // List all schemas here
def descriptionsForAllSchemas : Seq[SqlSchemaDescription] = allSchemas.map(_.schemaDescription)
def evolutions = Action {
environment.mode match {
case Mode.Prod => NotFound
case _ => Ok(views.txt.evolutions(descriptionsForAllSchemas)).withHeaders(CONTENT_TYPE -> "text/plain")
}
}
}
对于这个控制器当然有对应的视图(views/evolutions.scala.txt)
@import models.HasSchemaDescription.SqlSchemaDescription
@(schemaDescriptions : Seq[SqlSchemaDescription])
# Get the newest version of this evolutions script on the address
# http://localhost:9000@(controllers.routes.SchemaEvolutionsController.evolutions)
# when the server runs in development mode
# --- !Ups
@for(
schemaDescription <- schemaDescriptions;
statement <- schemaDescription.createStatements) {
@(statement.replaceAll(";",";;"));
}
# --- !Downs
@for(
schemaDescription <- schemaDescriptions;
statement <- schemaDescription.dropStatements) {
@(statement.replaceAll(";",";;"));
}
对于 DAO 对象,我添加了一个通用特征来获取架构描述 (app/models/HasSchemaDescription):
package models
import models.HasSchemaDescription.SqlSchemaDescription
trait HasSchemaDescription {
def schemaDescription: SqlSchemaDescription
}
object HasSchemaDescription {
type SqlSchemaDescription = slick.profile.SqlProfile#SchemaDescription
}
现在对于每个 DAO 对象,我必须实现 trait 并将 DAO 添加到 SchemaEvolutionsController。
例如用于服务 cat 对象的 DAO:
class CatDao @Inject()(protected val dbConfigProvider: DatabaseConfigProvider)
extends HasDatabaseConfigProvider[JdbcProfile] with HasSchemaDescription {
import driver.api._
private val Cats = TableQuery[CatsTable]
def schemaDescription : SqlSchemaDescription = Cats.schema
def findById(id : Int) : Future[Option[Cat]] = db.run(Cats.filter(_.id === id).result.headOption)
private class CatsTable(tag: Tag) extends Table[Cat](tag, "CAT") {
def id = column[Int]("ID", O.PrimaryKey, O.AutoInc)
def name = column[String]("NAME")
def color = column[String]("COLOR")
def age = column[Option[Int]]("AGE")
def * = (id, name, color, age) <> (Cat.tupled, Cat.unapply _)
}
}
通过此示例,您在http://localhost:9000/evolutions.sql 上得到以下结果
# Get the newest version of this evolutions script on the address
# http://localhost:9000/evolutions.sql
# when the server runs in development mode
# --- !Ups
create table `CAT` (`ID` INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,`NAME` TEXT NOT NULL,`COLOR` TEXT NOT NULL,`AGE` INTEGER);
# --- !Downs
drop table `CAT`;