#はじめに
環境構築はこちらを参照
今回はここにMySQLを追加したものを準備
- MySQL5.6
(60分クッキング) Play Framework (Scala)+MySQLでREST APIサーバーを作る
これを元にPlayFrameWorkを使ってみる。
##早速問題が発生
build.sbtにanormを追加して、activator eclipseコマンドから
必要ファイルのダウンロードをする
C:\framework\play\playScalaTest>activator eclipse
ACTIVATOR_HOME=C:\framework\activator-1.3.10-minimal
ファイル BIN_DIRECTORY\..\conf\sbtconfig.txt が見つかりません。
[info] Loading project definition from C:\framework\play\playScalaTest\project
Anorm has been moved to an external module.
See https://playframework.com/documentation/2.4.x/Migration24 for details.
Project loading failed: (r)etry, (q)uit, (l)ast, or (i)gnore?
https://playframework.com/documentation/2.4.x/Migration24
https://playframework.com/documentation/2.4.x/Anorm
PlayFrameWork2.4からanormはplayのコアから切り出されているため、
そのままでは使えないみたい
せっかくなので方向転換してPlaySlickを使ってみる
#参考情報
Scala on PlayでAPIサーバーの構築 with MySQL
解説もわかりやすかったのでここを参考に写経してみる
##ルーティングの設定
GET /client controllers.HomeController.client
##コントローラーの設定
package controllers
import javax.inject._
import play.api._
import play.api.mvc._
// importを追加
import play.api.libs.json.Json
/**
* This controller creates an `Action` to handle HTTP requests to the
* application's home page.
*/
@Singleton
class HomeController @Inject() extends Controller {
/**
* Create an Action to render an HTML page with a welcome message.
* 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 {
Ok(views.html.index("Your new application is ready."))
}
// Actionを追加
def client = Action {
val json = Json.obj("client" -> "Hello!");
Ok(Json.toJson(json));
}
}
##MySQLを設定
clientテーブルを作成する
CREATE TABLE `client` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` text NOT NULL,
`address` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
適当なデータの登録をしておく
##モジュールの追加
MySQL-ConnectorとPlay-Slickを追加する
name := """playScalaTest"""
version := "1.0-SNAPSHOT"
lazy val root = (project in file(".")).enablePlugins(PlayScala)
scalaVersion := "2.11.7"
libraryDependencies ++= Seq(
jdbc,
cache,
ws,
"org.scalatestplus.play" %% "scalatestplus-play" % "1.5.1" % Test,
"mysql" % "mysql-connector-java" % "5.1.39",
"com.typesafe.play" %% "play-slick" % "2.0.0"
)
resolvers += "scalaz-bintray" at "http://dl.bintray.com/scalaz/releases"
コマンドプロンプトからEclipseに追加
C:\framework\play\playScalaTest>activator eclipse
ACTIVATOR_HOME=C:\framework\activator-1.3.10-minimal
ファイル BIN_DIRECTORY\..\conf\sbtconfig.txt が見つかりません。
[info] Loading project definition from C:\framework\play\playScalaTest\project
[info] Set current project to playScalaTest (in build file:/C:/framework/play/playScalaTest/)
[info] About to create Eclipse project files for your project(s).
[info] Updating {file:/C:/framework/play/playScalaTest/}root...
[info] Resolving jline#jline;2.12.1 ...
[info] downloading https://repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.39/mysql-connector-java-5.1.39.jar ...
[info] [SUCCESSFUL ] mysql#mysql-connector-java;5.1.39!mysql-connector-java.jar (1789ms)
[info] Done updating.
[info] Successfully created Eclipse project files for project(s):
[info] playScalaTest
##データベース設定
データベース設定を追記する
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/test?user=[ユーザー名]&password=[パスワード]"
##モデルの定義
package models.database
import play.api.libs.json.Json
case class Client (
id: Option[Long],
name: String,
address: String
)
object Client {
implicit val clientWrites = Json.writes[Client]
implicit val clientReads = Json.reads[Client]
}
##DAOの定義
package models
import javax.inject.Singleton
import javax.inject.Inject
import play.api.db.slick.DatabaseConfigProvider
import slick.driver.JdbcProfile
import scala.concurrent.impl.Future
import scala.concurrent.Future
import models.database.Client
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.libs.json
@Singleton
class ClientDAO @Inject()(val dbConfigProvider: DatabaseConfigProvider) {
val dbConfig = dbConfigProvider.get[JdbcProfile]
import dbConfig.driver.api._
private class ClientTable(tag: Tag) extends Table[Client](tag, "client") {
def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def address = column[String]("address")
def * = (id.?, name, address) <> ((Client.apply _).tupled, Client.unapply)
}
private val clients = TableQuery[ClientTable]
def all(): Future[List[Client]] = dbConfig.db.run(clients.result).map(_.toList)
}
##APIの実装
package controllers
import javax.inject._
import play.api._
import play.api.mvc._
import play.api.libs.json.Json
import models.database.Client
import models.ClientDAO
// Futureを扱うにはこの2つのimportが必要
import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
/**
* This controller creates an `Action` to handle HTTP requests to the
* application's home page.
*/
@Singleton
class HomeController @Inject() (dao: ClientDAO) extends Controller {
/**
* Create an Action to render an HTML page with a welcome message.
* 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 {
Ok(views.html.index("Your new application is ready."))
}
// APIの処理を書き直し
def client = Action.async {
dao.all().map(clients => Ok(Json.toJson(Json.toJson(clients))))
}
}
##Eclipseのコンパイル
コマンドプロンプトで実行
c:\framework\play\playScalaTest>activator eclipse compile
ACTIVATOR_HOME=C:\framework\activator-1.3.10-minimal
ファイル BIN_DIRECTORY\..\conf\sbtconfig.txt が見つかりません。
[info] Loading project definition from C:\framework\play\playScalaTest\project
[info] Set current project to playScalaTest (in build file:/C:/framework/play/playScalaTest/)
[info] About to create Eclipse project files for your project(s).
[info] Successfully created Eclipse project files for project(s):
[info] playScalaTest
[info] Compiling 7 Scala sources and 1 Java source to C:\framework\play\playScalaTest\target\scala-2.11\classes...
[success] Total time: 9 s, completed 2016/06/29 21:26:45