decadence

個人のメモ帳

Slick in Play2.1

Slickを使ってみた

ドキュメントSlick ガイド - tototoshiの日記が参考になった

基本的な使い方は上記を参考に.以下の点について軽く

  • SlickをPlayで使う
  • 上記ガイドなどから見つけにくかったSlickに関する適当な事

環境
Scala 2.10.0
・Play 2.1.0-RC2
・Slick 1.0.0
Play複数環境でRC2揃えたら次の日にRC3が出ていまやstable


Lifted Embeddingしか使ってません
生のSQLも書けるらしいですね

HOWTO

default以外のdbを使う際のセッティング(ここではpiyo)
application.conf(postgresql使ってます)

db.piyo.driver=org.postgresql.Driver
db.piyo.url="jdbc:postgresql:dbname"
db.piyo.user=username
db.piyo.password=password

application.confのセッティングを読み込む
DB.getDataSourceの引数にpiyoを与える事でそのdbが利用可能
Tableを継承したクラス内で適当な関数をdb withSession {f:=>Any}とする事でDB操作が行える
複数カラムでユニークなキーを作る際にはindexを利用し,unique = trueと引数を加える
importのPostgresDriverの所をh2やmysqlに変えるだけ(sbtの依存設定やらも)で動くかららくちん

package models

import play.api.db.DB
import play.api.Play.current
import scala.slick.driver.PostgresDriver.simple._
import Database.threadLocalSession

case class Hoge(first: String, second: String, value: String)

object Hoges extends Table[Hoge]("hoge_table") {
  val dbname = "piyo"
  lazy val db = Database.forDataSource(DB.getDataSource(dbname))

  def first = column[String]("first", O DBType "char(2)", O NotNull)
  def second = column[String]("second", O DBType "char(8)", O NotNull)
  def value = column[String]("value", O DBType "varchar(128)", O Default("fuga"))

  def * = first ~ second ~ value <> (Hoge.apply _, Hoge.unapply _)
  def ins = first ~ second returning *
  def idx = index("hoges_id_key", (first, second), unique = true)

  // select * from hoge_table; => Seq[Hoge]
  def findAll = db withSession {
     Query(Hoges).list
  }

  // select * from hoge_table where first = "first"; => Seq[Hoge]
  def findHogeByFirst(first: String) = db withSession {
    (for(hoge <- Hoges if hoge.first === first) yield hoge).list
  }

  // select value from hoge_table where first = "first"; => Seq[String]
  def findValuesByFirst(first: String) = db withSession {
    (for(hoge <- Hoges if hoge.first === first) yield hoge.value).list
  }

  // insert into hoge_table (first, second, value) values ("first", "second", DEFAULT); => Hoge
  def create(first: String, second: String) = db withSession {
    Hoges.ins.insert(first, second)
  }

  // delete from hoge_table where first = "first"; => 後で見よ
  def deleteByFirst(first: String) = db withSession {
    Hoges.where(_.first === first).delete
  }

  // update hoge_table set second = "updateSecond", value = "updateValue" where first = "first"; => 後で見よ
  def updateValueByFirst(first: String, updateSecond: String, updateValue: String) = db withSession {
    val query = for(hoge <- Hoges if hoge.first === first) yield hoge.second ~ hoge.value
    query.update(updateSecond, updateValue)
  }
}

テーブルの作成はGlobal.scalaのonStartなどに書くと起動時に生成される
Global.scala

  override def onStart(app: Application) {
    lazy val piyoDB = Database.forDataSource(DB.getDataSource(Hoges.dbname))
    piyoDB.withSession{
      Hoges.ddl.create
    }
  }

後はHoge.findAllとか適当なクラスから呼び出して使ってる

anormと比べて以下の点で気に入ってる

  • evolution不要(多分)
  • Pkとは
  • 従来のScalaの記法に近い

動いたから使ってるって所もあるので,良くないやり方だったら指摘ください.
英語圏の方見てたらDataBaseLayerとかtrait作って使ってたりしてるけど...ううむ

  • -

Playでルーティング設定してws://~がlocalhostでは動くのにサーバあげたら動かない事で悩んでるから誰か相談...
京都から単身Scala Conference乗り込む事にした.寂しくない振りして頑張ろう.さびしいお
偶然にも翌日3/3~3/5に東北の学会行ける事になったから楽しみ増えた