3 分でできる Play2 で Skinny ORM を使う手順 #play_ja
これは Play framework 2.x Scala Advent Calendar 2013 の 8 日目です。
http://www.adventar.org/calendars/114
ご存知の方もいるかと思いますが、私は Skinny Framework というフレームワークをつくっています。これのコンポーネントは基本的に Skinny Framework 以外でも使えるようにつくられていて、その一つである Skinny ORM がある程度使える ORM として育ってきました。まだドキュメントはそれほど充実していませんが、こちらをご覧ください。
http://skinny-framework.org/documentation/orm.html
この Skinny ORM は ScalikeJDBC という DB ライブラリをより ORM 的に使えるようにするために、ScalikeJDBC を土台につくられています。ScalikeJDBC と Play2 の連携は以前から実装されていて、実績もあります。
Skinny ORM を Play ユーザの皆さんにもぜひ使っていただきたいので、今回は導入までの手順を紹介します。
Play アプリをつくる
この時点では Play 2.2.1 が最新です。私のように最近 play コマンド使ってないなーという方は brew upgrade play しておきましょう。
play new play-with-skinny-orm cd play-with-skinny-orm
build.sbt を書き換える
build.sbt をこのように書き換えてください。
name := "play-with-skinny-orm" version := "1.0-SNAPSHOT" libraryDependencies ++= Seq( "org.skinny-framework" %% "skinny-orm" % "0.9.29", "org.scalikejdbc" %% "scalikejdbc-play-plugin" % "1.7.1", "com.h2database" % "h2" % "1.3.174" ) play.Project.playScalaSettings
conf/play.plugins
Play に ScalikeJDBC ベースのコネクションマネージメントを伝えるために、ScalikeJDBC の Play プラグインを追加します。
10000:scalikejdbc.PlayPlugin
conf/application.conf
Play の DB 設定を更新します。今回の説明の都合上、H2 をファイルベースの DB に変えてください。
db.default.driver=org.h2.Driver db.default.url="jdbc:h2:file:play" db.default.user=sa db.default.password=""
conf/db/migration/V1__Create_companies.sql
DB マイグレーション用ファイルをつくってください。V1__ のアンダースコアは二つなので気をつけてください。Flyway のファイルです。今回は手動でマイグレーションを実行します。
create table company ( id bigserial not null primary key, name varchar(64) not null, url varchar(128), created_at timestamp not null, updated_at timestamp, deleted_at timestamp );
app/models/Company.scala
Skinny ORM では SkinnyCRUDMapper という trait を継承すると基本的な CRUD 操作はすぐに使えるようになります。
package models import scalikejdbc._, SQLInterpolation._ import skinny.orm._, feature._ import org.joda.time.DateTime case class Company( id: Long, name: String, url: Option[String] = None, createdAt: DateTime, updatedAt: Option[DateTime] = None, deletedAt: Option[DateTime] = None) object Company extends SkinnyCRUDMapper[Company] with TimestampsFeature[Company] with SoftDeleteWithTimestampFeature[Company] { override val defaultAlias = createAlias("c") override def extract(rs: WrappedResultSet, c: ResultName[Company]): Company = new Company( id = rs.long(c.id), name = rs.string(c.name), url = rs.stringOpt(c.url), createdAt = rs.dateTime(c.createdAt), updatedAt = rs.dateTimeOpt(c.updatedAt) ) }
app/controllers/Application.scala
説明を簡略化するためにただ toString しています。
package controllers import play.api._ import play.api.mvc._ import models.Company object Application extends Controller { def index = Action { Ok(Company.findAll().toString) } }
手動で DB マイグレーション
今回はさらっと試すだけなので play console でマイグレートしてしまいましょう。
skinny.DBSettings.initialize() skinny.dbmigration.DBMigration.migrate()
例外がでなければ成功です。こんな感じで model が使えるようになりました。console から試してみてください。
skinny.DBSettings.initialize() import models._ Company.count() Company.createWithAttributes('name -> "Typesafe") Company.findAll()
console で実行した結果を貼付けておきますね。
$ sbt console [info] Starting scala interpreter... [info] Welcome to Scala version 2.10.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_25). Type in expressions to have them evaluated. Type :help for more information. scala> skinny.DBSettings.initialize() scala> import models._ import models._ scala> Company.count() res1: Long = 0 scala> Company.createWithAttributes('name -> "Typesafe") res2: Long = 1 scala> Company.findAll() res3: List[models.Company] = List(Company(1,Typesafe,None,2013-12-08T20:03:36.771+09:00,None,None))
play run
最後に play run で Play アプリにちゃんと組み込まれたか確認します。
play run
ブラウザから http://localhost:9000/ にアクセスして正常に表示されれば OK です。
最終的にはこのようなファイル構成となりました。
. ├── README ├── app │ ├── controllers │ │ └── Application.scala │ ├── models │ │ └── Company.scala │ └── views │ ├── index.scala.html │ └── main.scala.html ├── build.sbt ├── conf │ ├── application.conf │ ├── db │ │ └── migration │ │ └── V1__Create_companies.sql │ ├── play.plugins │ └── routes ├── logs │ └── application.log ├── play.h2.db ├── project │ ├── build.properties │ └── plugins.sbt ├── public │ ├── images │ │ └── favicon.png │ ├── javascripts │ │ └── jquery-1.9.0.min.js │ └── stylesheets │ └── main.css └── test ├── ApplicationSpec.scala └── IntegrationSpec.scala 14 directories, 19 files
明日は unokazuhiko さんです。その次の日からまた空いてますけどね・・・