はじめに

Play2.4のPlaySlickではSlick3.1をサポートするようになりました。

今年の四月末にリリースしたSlick3.0はSlick2.xから仕様が大きく変更されており、3.1は10月に公開されたアップデートのようです。Playのドキュメントでは “This guide assumes you already know both Play 2.4 and Slick 3.1.” などと丸投げされていたのでSlickのマニュアルやサンプルコードをいったりきたりしながら、PlaySlickを使ってDB操作ができるまでをやってみました。

プロジェクトの作成

activatorなりでサクッとプロジェクトを作成し、 build.sbtlibraryDependencies を変更します。

もともと入ってるものもありますが、追加したのは "com.typesafe.play" %% "play-slick" % "1.1.0""com.h2database" % "h2" % "1.4.190", の二つです。PlaySlickにはJDBC driverは含まれないために、明示的に入れています。

h2databaseのほうはオープンソースのDBMSの1つで、とりあえずMySQLとかを用意しなくても良いように入れておきます。

続いて conf/application.conf に接続する設定を追加します。これはH2に繋ぐようの設定なので、もしMySQLとかに繋ぐような場合はまたちょっと違います。(今回そっちは扱いません)

素のSlickとPlaySlickの違い

さて、通常のSlickであればこの先DBに操作をする場合には、なんとかして slick.jdbc.JdbcBackend.Database 型のオブジェクトを生成して、こいつに対していろいろと実行したりすることになります。

生成方法もまあいろいろあってconfファイルから読み込ませたり、直接URLを流し込んで作ったり別にそこまで難しいものではないです。ただ、DB接続するクラスが幾つもあると、まさか毎回生成するわけにもいかずその辺の使い回しに苦労することになるかもしれません。また、接続はSlickが管理してくれるので勝手にcloseしていいものでもありません。

そこでPlaySlickでは、DBに接続するために設定ファイルさえ書けばあとはどうにかしてくれます。さっきapplication.confに書いたものがそれです。あれを使ってdbConfigを生成しつつ、 HasDatabaseConfig をミックスインしてやることで、サクッと簡単に Database 型が用意されて自由に使えるようになります。

こうすればこのクラス(例で言えば Sample )のフィールドに db が用意されて、これを使ってDB操作を行うことができます。ここから先は素のSlickであっても共通です。

スキーマ定義

スキーマ定義は以下のように行います。

この例でもそうしていますが、同じようなcase classを作っておいて、それを利用するのが楽っぽいです。 (Mapped Tables

こうしておくことで、通常はItemオブジェクトを自然に使いつつSlickで使うときには*が適宜タプルとcase classの相互変換を活用して必要な形式に変換してくれます。

このテーブルにアクセスするためには前述のdbの他にTableQueryというのも必要になるので、合わせて用意します。

取得

作成したTableQueryの .result を呼び出してdb.runに渡せば結果が帰ってきます。結果は非同期で返ってくるのでFutureで受け取ります。limitやoffset、それにsortなどの設定も可能です。

取得したいレコードを絞り込みたいのであればfilterで絞り込みが可能です。この場合、内部で自動的にきちんとWHERE句等としてクエリを投げてくれるので、Scalaの感覚そのままにDBにアクセスすることができました。

この場合一件だけなので .headOption を使ってSeqでなく単体で取得するようにしています。

このとき注意したいのは、filterにおいて同値をチェックするには === を使用するという点です。ちょっとややこしいのですが、 == が置き換えられないのでやむを得ないらしいです。ちなみに不一致も =!= になっています。

挿入

挿入もとってもお手軽で、無造作に足すだけで構いません。楽チンですね。複数まとめて足したければ配列として結合してやれば問題ありません。

場合によってはデータを連続してまとめて挿入したりしたいケースもあると思います。そんな時は DBIO を使うことによって複数のDB操作をまとめてリクエストすることも可能です

更新と削除

アップデートはfilterなどで対象を絞り込んでから .update でその値に更新することができます。レコード単位でまとめても、あるいはfilterで複数が該当する条件にして特定のフィールドを更新することもできます。

同じように絞りこんで .delete を呼べばそのレコードを削除することができます。

最後に

このようにslick3.1ではScalaっぽい書き方で自然にDB操作を行うことができます。また、AUTOINCREMENTを設定できたり、使いどころは限られますがテーブル作成のためのクエリを生成して実行する方法もあります。

また、Playとの組み合わせとしても非同期レスポンス(Action.async)では同じくFutureを使うため自然に組み合わせることができます。

新しいライブラリはどうしても手が出しづらいところがありますが、Slickは便利なのでぜひ使ってみてください。

参考になりそうな関連ページ

公式ドキュメント

サンプルコード

最後に宣伝

ナイル株式会社は、2016年1月に開催される日本最大級のScalaのカンファレンス、ScalaMatsuri 2016のスポンサーとなっています。

合わせて日本語セッションも応募しているので、興味を持っていただけましたらぜひとも投票をよろしくお願いします。