はじめて(一週間ぶり2回目)の Play Framework でデータベース接続してみる

## さぁーて、今週のPlayは？

[前回](http://qiita.com/asano-y/items/252abecbd79c1b1b7277)PlayでAPIもどきを作成できたので、今度はテンプレートを使ってhtmlを返し＆DB接続をしてみます。

## 待てあわてるな、これは準備だ

application.comfに接続情報を。
ローカルで動いているMySQLのplaydbという名前のデータベースに接続する場合です。

```text:conf/application.conf
# (省略)

libraryDependencies += jdbc
play.db {
  config = "db"
  default = "default"
  prototype {
  }
}
db {
  default.driver=com.mysql.jdbc.Driver
  default.url="jdbc:mysql://localhost/playdb"
  default.username = user123
  default.password = "password123"
}
```

データはこのように入れてみました。

```
+----+----------------------+--------------------------------------+---------------------------+
| id | company_name         | company_copy                         | addr                      |
+----+----------------------+--------------------------------------+---------------------------+
|  1 | 独立行政法人サンプル | 私たちはサンプルのためのサンプルです | 〒000-0123 銀河の果てまで |
|  2 | なんとか株式会社     | なんとかせんといかん会社             | 〒000-2222 東京都XXX      |
|  3 | テスト企業 01        | 企業1です！                          | 〒000-1111 東京都ほげほげ |
+----+----------------------+--------------------------------------+---------------------------+
```

build.sbtのlibraryDependenciesにmysql-connector-javaを追加します。

```text:build.sbt
libraryDependencies ++= Seq(
  ...(省略)
  "mysql" % "mysql-connector-java" % "5.1.34"
)
```


## よろしい、ならばコーディングだ

MySQLのDBからデータを取ってきて表示するページを作ってみます。

まずはroutes

```text:conf/routes
GET     /companies         controllers.CompaniesController.index
```

CompaniesControllerはこんな感じ

```scala:app/controllers/CompaniesController.scala
package controllers

import javax.inject._
import play.api._
import play.api.mvc._
import play.api.db._
import models.Company

@Singleton
class CompaniesController @Inject() (db1: Database) extends Controller {

  def index = Action {
    var str = ""
    var coms = List[Company]()
    val conn = db1.getConnection
    try {
      val stmt = conn.createStatement
      val rs = stmt.executeQuery("select * from companies order by id ASC limit 3")
      while (rs.next()) {
        coms = coms :+ new Company(rs)
      }
    } finally {
      conn.close
    }
    Ok(views.html.companies(coms))
  }

}
```

何気なく出てきたCompanyはこんな感じ。
stmt.executeQuery はResultSet型を返してくるので、ResultSetを引数にするコンストラクタも作ってみました。
(こんな設計で大丈夫かなあ？)

```scala:models/Company.scala
package models

import java.sql.ResultSet

case class Company(_id: Int, _company_name: String, _company_copy: String, _addr: String) {
  var id = _id
  var company_name = _company_name
  var company_copy = _company_copy
  var addr = _addr

  def this() = {
    this(0, "", "", "")
  }
  def this(rs: ResultSet) = {
    this(rs.getInt("id"), rs.getString("company_name"), rs.getString("company_copy"), rs.getString("addr"))
  }

  def getId: Int = {
    return this.id
  }
  def getName: String = {
    return this.company_name
  }
  def getCopy: String = {
    return this.company_copy
  }
  def getAddr: String = {
    return this.addr
  }
}
```

viewはこんな感じで。スタイルがしょぼいのは気にしないでください。

```html:views/companies.scala.html
@(coms: List[Company])
<!DOCTYPE html>
<html lang="ja">
<head>
    <title>Companies</title>
    <link rel="shortcut icon" type="image/png" href="@routes.Assets.versioned("images/favicon.png")">
    <style>
    div.com{
      margin: 4px 12px;
      padding: 4px 8px;
      border: 2px solid rgb(127,191,191);
      border-radius: 2px;
    }
    p.name{
      border-left: 2px solid rgb(63,63,127);
      padding-left: 8px;
      font-size:110%;
    }
    p.addr{
      font-size: 90%;
    }
    </style>
</head>
<body>
  <header></header>
  <main>
    <h1>企業一覧</h1>
    @for(com <- coms){
        <div class="com">
        <p class="name">@com.getName</p>
        <p class="copy">@com.getCopy</p>
        <p class="addr">@com.getAddr</p>
        </div>
    }
  </main>
  <footer></footer>
</body>
</html>
```


## これでいいのだ

![vivaldi2.png](https://qiita-image-store.s3.amazonaws.com/0/118352/18148c51-654d-ce0d-6cdd-d370d8775f79.png)