1. 基于 play-slick 来编写 Models 层
1.1 安装相关依赖
在 build.sbt 中添加如下依赖,
libraryDependencies ++= Seq(
// play-slick "com.typesafe.play" %% "play-slick" % "4.0.2",
"com.typesafe.play" %% "play-slick-evolutions" % "4.0.2",
"mysql" % "mysql-connector-java" % "8.0.17", // mysql连接器)
1.2 配置 slick
配置 conf/application.conf 文件,如下(mysql 数据库需要预先搭建好):
# Connect to playdb as playdbuser
slick.dbs.default.driver = "slick.driver.MySQLDriver$"
slick.dbs.default.db.driver = "com.mysql.jdbc.Driver"
slick.dbs.default.db.url = "jdbc:mysql://localhost:3306/NetworkDeviceManager?useUnicode=true&characterEncoding=utf8&useSSL=false"
slick.dbs.default.db.user = "root"
slick.dbs.default.db.password = "root"
1.3 编写 Model 类
新建 app/models/Models.scala 如下
package models
import java.sql.Timestamp
case class MachineType(
id: Int,
name: String,
description: Option[String],
created_at: Timestamp,
updated_at: Timestamp
)
case class NetworkEntity(
id: Int,
name: String,
description: Option[String],
comment: Option[String],
machine_type_id: Int,
created_at: Timestamp,
updated_at: Timestamp
)
case class NetworkLink(
id: Int,
from_entity_id: Int,
to_entity_id: Int,
description: Option[String],
comment: Option[String],
setted_ip: Option[String],
setted_subnet_mask: Option[String],
setted_gateway: Option[String],
from_physical_interface: Option[String],
to_physical_interface: Option[String],
created_at: Timestamp,
updated_at: Timestamp
)
1.4 编写 dao service 对 model 进行操作
以 app/services/dao/MachineType.scala 为例,
package services.dao
import javax.inject.Inject
import play.api.db.slick.DatabaseConfigProvider
import play.api.db.slick.HasDatabaseConfigProvider
import scala.concurrent.{ExecutionContext, Future}
import slick.jdbc.JdbcProfile
import java.sql.Timestamp
import models.MachineType
class MachineTypeService @Inject()(
protected val dbConfigProvider: DatabaseConfigProvider
)(implicit executionContext: ExecutionContext)
extends HasDatabaseConfigProvider[JdbcProfile] {
import profile.api._
private val machine_types = TableQuery[MachineTypeTable]
def all(): Future[Seq[MachineType]] = db.run(machine_types.result)
// def insert(machine_type: MachineType): Future[Unit] = db.run(machine_types += machine_type).map { _ => () }
private class MachineTypeTable(tag: Tag)
extends Table[MachineType](tag, "machine_type") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def description = column[Option[String]]("description")
def created_at = column[Timestamp]("created_at")
def updated_at = column[Timestamp]("updated_at")
def * =
(id, name, description, created_at, updated_at) <> (MachineType.tupled, MachineType.unapply)
}
}
1.5 在 controller 中使用
以 app/controllers/HomeControllers.scala 为例
package controllers
import javax.inject._
import play.api._
import play.api.mvc._
import scala.concurrent.ExecutionContext
import services.dao.{
MachineTypeService,
NetworkLinkService,
NetworkEntityService
}
/*** This controller creates an `Action` to handle HTTP requests to the* application's home page.*/
@Singleton
class HomeController @Inject()(
machineTypeService: MachineTypeService,
netWorkLinkService: NetworkLinkService,
netWorkEntityService: NetworkEntityService,
cc: ControllerComponents
)(implicit executionContext: ExecutionContext)
extends AbstractController(cc) {
/*** Create an Action to render an HTML page.** The configuration in the `routes` file means that this method* will be called when the application receives a `GET` request with* a path of `/`.*/
def index() = Action.async { implicit request: Request[AnyContent] =>
netWorkLinkService
.all()
.zip(netWorkEntityService.all())
.zip(machineTypeService.all())
.map {
case ((network_links, network_entitys), machine_types) => {
Ok(views.html.topology())
}
}
}
}
2. 使用 flyway-play 进行数据库迁移管理
配置 build.sbt 如下
enablePlugins(FlywayPlugin)
libraryDependencies ++= Seq(
// flyway-play
"org.flywaydb" %% "flyway-play" % "5.3.3",
)
配置 project/plugin.sbt
addSbtPlugin("io.github.davidmweber"%"flyway-sbt"%"6.0.0")
配置 conf/application.conf 文件
play.modules.enabled += "org.flywaydb.play.PlayModule"
db.default = ${slick.dbs.default.db}
db.default.migration.showInsertQuery=true
db.default.migration.initOnMigrate=true
# db.default.migration.auto=true # prod
添加 对应的迁移脚本, 比如 conf/db/migration/default/V0.0.1__Create_three_basic_tables.sql
最后运行服务,可在 http://127.0.0.1:9000/@flyway/default 管理数据库迁移
NOTE:flyway-play 使用中存在一个还未解决的问题,sql 脚本中包含中文时,会出现乱码 。暂时还未排查原因