TypesafeのScala用データベースクエリおよびアクセスライブラリであるSlickが大幅に改善され,バージョン3.0としてリリースされた。“Reactive Slick”という名称の,データベースクエリの構成と実行をリアクティブな手法で行うAPIも新たに導入されている。Reactiveという名は,“非ブロック型のバックプレッシャを備えた非同期ストリーム処理の標準型を提供しようという試み”としてReactive Streams APIをサポートすること,リアクティブ宣言(Reactive Manifesto)に従ったアプリケーションの構築をサポートすること,という意味だ。
Slickを使ったデータベースクエリは,Scalaのコレクションを操作するように記述することが可能だ。同じボキャブラリと,同じような操作がサポートされている(構文が複雑になると,この錯覚は成り立たなくなるが)。副次的なメリットとして,クエリは単なる文字列ではないため,コンパイラによるタイプチェックが行われる。2つのテーブルの単純な結合とwhere句ならば,
val q2 = for {
c <- coffees if c.price < 9.0
s <- suppliers if s.id === c.supID
} yield (c.name, s.name)
これと等価なSQLコードは次のようになる。
select c.COF_NAME, s.SUP_NAME from COFFEES c, SUPPLIERS s where c.PRICE < 9.0 and s.SUP_ID = c.SUP_ID;
クエリAPIに大きな変更はないが,クエリが実際の結果ではなく,DBIOActionを返すようになっている (旧APIは非推奨となり,3.1で廃止される予定)。このようなアクションを組み合わせてデータベースに転送し,順次実行することも可能だ。そのようなSlick 3スタイルのクエリの例を以下に示す。
val q = for (c <- coffees) yield c.name
val a = q.result
val f: Future[Seq[String]] = db.run(a)
f.onSuccess { case s => println(s"Result: $s") }
これまでのAPIであれば,
val q = for (c <- coffees) yield c.name
val result = db.withSession {
implicit session =>
val s = q.list // <- takes session implicitly
println(s"Result: $s")
}
新しいアプローチの最大のメリットは,データベースクエリの実行によって,呼び出したスレッドがブロックされないという,完全な非同期性にある。さらに,データベースからの処理結果をストリーム化できるようになった。Reactive Streamsをサポートする,例えばFrameworkなどと組み合わせることによって,要求を処理するスレッドを,可能な限り早く解放できるようになる。
InfoQは,Slickの技術リーダであるStefan Zeiger氏に,新リリースの詳細と今後の計画について聞いた。
InfoQ: 新APIでは主としてクエリの実行方法が変わっているようですが,クエリの構築方法については,何らかの変更があったのでしょうか?
クエリの記述方法については,基本的な部分では変わっていませんが,2つの大きな新機能があります。外部結合の型付けが正しくなって,Optionが片側に(完全外部結合の場合は両方に)返されるようになったことがそのひとつです。これにより,マップされたデータタイプや2つ以上のテーブルとの外部結合の記述が簡単になります。これまではすべてのクエリで,分かりにくく複雑なマッピングを自分で書かなくてはなりませんでした。もうひとつの大きな機能はtsql interpolatorで,組込みSQL文の静的検証と型推論が可能になります。手作業で記述したSQLのエラーを見つけるために,実行時まで待つ必要はありません。Scalaコンパイラがコンパイル時に,データベースにチェックを実行させてくれるのです。
InfoQ: PlayやAkkaのJava APIのような,Java 8の新しいStreamsやラムダを使用するJava APIを開発する予定はありますか?
そうですね,近いうちに実現して,Java開発者向けのフルスタックソリューションを完成させたいと思っています。
InfoQ: ストリーミングや新しいIO-APIは,すべてのデータベースで動作するのでしょうか,あるいは制限があるのですか?
DBIO APIはJDBC上に実装されていますから,既存のすべてのドライバで動作します。既存の非同期ドライバを利用して,データベースのネイティブサポートを改善することについても調査しています。
InfoQ: Slick 3.1あるいは4.0の計画はありますか?
Slick 3.1に向けて現在開発中の機能で大きなものは,クエリコンパイラのバックエンドを改良して,よりシンプルなSQLコードを生成可能にすることです。これによって生成されるコードが,すべてのユーザに対して読みやすいものになるだけでなく,パフォーマンス上のメリットも期待できます。特にMySQLの結合では,現在Slickが生成するコードでは,インデックスを利用できないことが多いのです。当社の有償製品であるReactive Platformには,Slick専用のモニタ機能を追加する予定です。
変更点の完全な一覧については,リリースアナウンスを参照してほしい。 アップグレードガイドもチェックが必要だ。Slick 3の詳細については,このStefan Zeiger氏のScalaDaysでの講演を見るとよいだろう。