play-slickを試した

play framework + Java + ebeanで色々やったので、今度はscalaでDB操作をしたかった。
調べるとSquerylとslickとで人気を二分しているらしい。今回はscalaの勉強であることとtypesafe stackに入っていることも考えてslickを試してみた。

play frameworkとslickを使うサンプルがすでにgithub上にあるが、どうもうまく統合できていないように感じたので調べたところplay-slickというプラグインがあるらしいので動かすところまでメモ。

環境

  • play framework 2.1.1
  • slick 2.10.0-RC5
  • play-slick 0.3.2

howto
いつもどおりplay new

play new mySlickSample

project/Build.scalaに追加

val appDependencies = Seq(
    //...他の依存ライブラリ
    "com.typesafe" % "slick_2.10.0-RC5" % "0.11.2",
    "com.typesafe.play" %% "play-slick" % "0.3.2" 
  )

application.confにDBの設定

 db.default.driver=org.h2.Driver
 db.default.url="jdbc:h2:mem:play"

play-slickを有効にする設定をapplication.confに追加。
このへんはebeanと同じですね。

# slick
# ~~~~~
# It is possible to specify individual objects like:
# slick.default="models.Users,models.Settings"
slick.default="models.*"

modelを作成

package models

import play.api.db.slick.Config.driver.simple._

case class User(
  id: Option[Long],//privary keyの場合はOption
  name: String)

object Users extends Table[User]("USERS") {

  def id = column[Long]("ID", O.PrimaryKey, O AutoInc) // This is the primary key column
  def name = column[String]("COF_NAME")
  def * = id.? ~ name <> (User.apply _, User.unapply _)

  //とりあえずfindAllだけ
  def findAll(filter: String = "%") = {
    //scalaのコレクションっぽく扱えるのが素敵
    for {
      u <- Users
      if (u.name like ("%" + filter))
    } yield u
  }
}

controllerも

package controllers

import models.Users
import play.api._
import play.api.Play.current
import play.api.db.slick.Config.driver.simple._
import play.api.mvc._

object Application extends Controller {

  def index = Action {
    //controllerでwithSessionを使うのが気持ち悪い気がするのだが、これでいいのだろうか?
    play.api.db.slick.DB.withSession { implicit session =>
      val users = Users.findAll().list
      Ok(views.html.index(users))
    }
  }
}

view

@(users: List[User])

@main("slick test") {
	<ul>
	@for(u <- users){
            <li>@u.toString()</li>
	}
	</ul>
}

あとappのdefault packageにGlobal.scalaとか作っておいて、

import play.api.Application
import play.api.GlobalSettings
import play.api.Play.current
import play.api.db.slick.Config.driver.simple._
import models.Users
import models.User

object Global extends GlobalSettings {

  override def onStart(app: Application) {

    play.api.db.slick.DB withSession {implicit session =>
      Users.insertAll(
        User(None, "jhon"),
        User(None, "bob"))
    }
  }
}

とやればテスト用データを入れておける。

localhost:9000にアクセスすれば表示できる。
f:id:ganr:20130609132711p:plain


次はtodoアプリを作ろう。

参考
Slick ガイド - tototoshiの日記
Slick

追記(2013/6/25)
今後play frameworkではAnormからslickに移行していくようだ。
play-slickがplay framework本体にプルリクされているようで
https://github.com/playframework/Play20/pull/1230
wktkが止まらないですね。