Slick3.2 のTable Class コードを自動生成できる slick-codegen
だが、サンプルがあるようでなくて地味に時間がかかったのでコードメモ。
mysqlのversionを6以上にするとコンパイルが通らなかったり、依存系な罠が多かった。
なお、時間がTimeStampやDateとして出力されるのが微妙すぎたので、slick-joda-mapper
を使用し、
Option[DateTime]として出力している。また、AutoIncrementもautoIncLastAsOption = true によりOption化した。
application.conf
にDB設定を記述することで使用できる。
- http://tototoshi.hatenablog.com/entry/20130323/1364013170
- https://github.com/tototoshi/slick-joda-mapper
詳しくは https://github.com/EudyptesCapital/slick-table-code-generator
build.sbt
import sbt._
lazy val root = (project in file("."))
.settings(
inThisBuild(List(
scalaVersion := "2.12.4",
version := "1.0.0"
)),
name := "SlickTableCodeGenerator",
libraryDependencies ++= List(
"com.typesafe.slick" %% "slick" % "3.2.0",
"com.typesafe.slick" %% "slick-codegen" % "3.2.0",
"joda-time" % "joda-time" % "2.7",
"com.github.tototoshi" %% "slick-joda-mapper" % "2.3.0",
"org.scalatest" %% "scalatest" % "3.0.3" % Test,
"org.slf4j" % "slf4j-nop" % "1.6.4",
"mysql" % "mysql-connector-java" % "6.0.5",
"org.scala-lang" % "scala-reflect" % scalaVersion.value,
"org.joda" % "joda-convert" % "1.7",
"com.typesafe" % "config" % "1.3.1"
),
dependencyClasspath in Runtime += baseDirectory.value / "config"
)
SlickTableCodeGenerator.scala
object SlickTableCodeGenerator extends App {
val config = ConfigFactory.load
val tablesName = config.getString("db.name") + "Tables"
val db = Database.forURL(
config.getString("db.url"),
driver = config.getString("db.jdbc.driver"),
user = config.getString("db.user"),
password = config.getString("db.password")
)
val model: Model = Await.result(db.run(MySQLProfile.createModel()), Duration.Inf)
new CustomSourceCodeGenerator(model).writeToFile(
config.getString("db.slick.profile"),
config.getString("output.dir"),
config.getString("package.name"),
tablesName,
tablesName + ".scala"
)
}
class CustomSourceCodeGenerator(model: Model) extends SourceCodeGenerator(model) {
override def code = "import com.github.tototoshi.slick.MySQLJodaSupport._\n" + "import org.joda.time.DateTime\n" + super.code
override def Table = new Table(_) {
override def autoIncLastAsOption = true // AutoIncrement to Option
override def Column = new Column(_) {
override def rawType = model.tpe match {
case "java.sql.Timestamp" => "Option[DateTime]"
case "java.sql.Date" => "DateTime"
case _ => super.rawType
}
}
}
}
application.conf
db = {
name: "Database"
url: "jdbc:mysql://localhost/database?useSSL=false&nullNamePatternMatchesAll=true"
jdbc.driver: "com.mysql.cj.jdbc.Driver"
slick.profile: "slick.jdbc.MySQLProfile"
user="root"
password=""
}
package.name: "package"
output.dir: "./output"