PlayFramework2.3(scala)でDBアクセスをするときのめも
Play + ScalaでDBアクセスのめも
環境
DDLは↓
本来はEvolutionを利用して作るものだけど、今回は直接作成した・・・
CREATE TABLE `user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(255) NOT NULL, `mail` varchar(255) NOT NULL, `password` varchar(255) NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `mail_UNIQUE` (`mail`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
設定
SQLアクセスをするために、anormを使う
build.sbtの設定
必要なライブラリを追加
libraryDependencies ++= Seq( jdbc, anorm, cache, ws, "mysql" % "mysql-connector-java" % "5.1.34" )
application.confの設定
DB接続設定の追加 それぞれ以下の変数は自分の環境に適宜変更する
HOSTNAME, SCHEMANAME, USERNAME, PASSWORD
db.default.driver=com.mysql.jdbc.Driver db.default.url="jdbc:mysql://_HOSTNAME_/_SCHEMANAME_" db.default.user="_USERNAME_" db.default.password="_PASSWORD_"
実装
Scalaの場合、Javaと違ってモデルを扱うためのライブラリがないみたい
Slickというライブラリが時期バージョンでデフォルトになるとかならないとか・・・
初めはSlickを試していたけどうまく動いてくれなかったので断念して、 anormを利用してみたところ使い勝手が良かったのでanormを利用することにした
モデルは、Javaと同様にapp/models
以下に作成していく
anormではモデルを作成するパッケージなどに特に縛りはなく、 コントローラにSQLを書いたりしても問題ないが、アレだと思うので
app/models
以下に作成していく
実際のソース
https://github.com/yamashiro0110/Play-ScalaSample/blob/master/app/models/User.scala
ハマった点.1: ~
って何?
~
については、以下のページに解説があった
http://libro.tuyano.com/index3?id=1069003&page=5 ここでの「~」という記号は、Anorm特有の機能で、値をリスト化する働きをします。例えば、A~B~Cとすると、((A, B), C)というようにまとめられます。こうしてまとめたものを元にMydataオブジェクトを生成するのが、その後のmap部分です。
ハマった点.2:object User.data
が何なのかよくわからない
data
については、SQLの実行結果をオブジェクトにパースするためのものみたい
以下のコードだとSQL(SQL文).on(条件).as(パーサ.戻り値)
となっている
def findById(id: Long): Option[User] = { DB.withConnection { implicit c => val sql = "SELECT * FROM user WHERE id = {id}" SQL(sql) .on("id" -> id) .as(User.data.singleOpt) } }
戻り値をOption[User]
にしたのは、指定されたIDがテーブルに存在しない場合にエラーが発生したため
パーサ(data
)からOption[User]
を取得するためには、singleOpt
を呼び出せばいい
User
を取得したい場合は、single
でいける
User
モデルを呼び出している部分はapp/controllers/SampleController
になっている
変数usr
に、IDが1のUserを探して代入、存在しない場合はUser.notFound
を代入している
レスポンスはCall SampleController index!! ->
という文字列にusr.name
を追加して返しているだけ
def index = Action { val usr = User.findById(1).getOrElse(User.notFound) Ok("Call SampleController index!! -> " + usr.name) }
Play + JavaのEbeanがクソ便利だったので、 Play + Scalaにはなかったことを知ったとき(とSlickを断念したとき)はJavaに戻ろうかと考えたけど、 anormもなかなか使いやすかったので今後もPlay + Scalaを利用していきたいと思った
あと、今回のソースをGitHubに上げました^^;
参考にしたページm(__)m
Model(モデル)を使ってデータベースアクセスする[Scala編](1/7):Herokuで始める 初心者のためのPlay Framework入門