PlayFrameWork2.5+Scala+Eclipse+PlaySlick+MySQLをWindows10で使ってみた

#はじめに
環境構築は[こちら](http://qiita.com/taka159/items/857c52e59c978e63a424)を参照

今回はここにMySQLを追加したものを準備

 - MySQL5.6


[(60分クッキング) Play Framework (Scala)+MySQLでREST APIサーバーを作る](http://qiita.com/AKB428/items/bbb085a06c37bd84d0be)

これを元に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](https://github.com/KeitaMoromizato/scala-study-play-mysql-api-server)

解説もわかりやすかったのでここを参考に写経してみる


##ルーティングの設定

```playScalaTest\conf\routes
GET /client  controllers.HomeController.client
```

##コントローラーの設定

```scala:playScalaTest\controllers\HomeController.scala
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テーブルを作成する

```sql:
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*を追加する

```:playScalaTest\build.sbt
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
```

##データベース設定
データベース設定を追記する

```:playScalaTest\conf\application.conf
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=[パスワード]"
```

##モデルの定義
```scala:playScalaTest\models\database\Client.scala
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の定義
```scala:playScalaTest\models\ClientDAO.scala
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の実装

```scala:playScalaTest\app\controllers\HomeController.scala
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
```

##実行結果
![image](https://qiita-image-store.s3.amazonaws.com/0/72166/16010af2-8eb5-5885-310c-6d958da17fa1.png)