Scala
PlayFramework

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

More than 1 year has passed since last update.


さぁーて、今週のPlayは?

前回PlayでAPIもどきを作成できたので、今度はテンプレートを使ってhtmlを返し&DB接続をしてみます。


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

application.comfに接続情報を。

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


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を追加します。


build.sbt

libraryDependencies ++= Seq(

...(省略)
"mysql" % "mysql-connector-java" % "5.1.34"
)


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

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

まずはroutes


conf/routes

GET     /companies         controllers.CompaniesController.index


CompaniesControllerはこんな感じ


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を引数にするコンストラクタも作ってみました。

(こんな設計で大丈夫かなあ?)


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はこんな感じで。スタイルがしょぼいのは気にしないでください。


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