Slick 3.0.0 documentation - 01 Introduction

Permalink to Introduction — Slick 3.0.0 documentation

導入 

What is Slick 

Slick (“Scala Language-Integrated Connection Kit”)はTypesafe社によってリレーショナルデータベースを簡単に扱うための、ScalaのFRM (Functional Relational Mapping)ライブラリである。まるでScalaのコレクションを扱うかのような操作でデータベースにアクセスし、データを操作出来る。SQLを直接扱うことも可能である。PlayAkkaを基にしたリアクティブアプリケーションに完璧にフィットするよう、データベースへの処理は非同期に実行される。

val limit = 10.0
// クエリはこのように書く事が出来る
( for( c <- coffees; if c.price < limit ) yield c.name ).result
// こちらのSQLと等しい: select COF_NAME from COFFEES where PRICE < 10.0

SQLを直接書くのに比べ、Scalaを通してSQLを発行すると、コンパイル時により良いクエリを型安全に提供する事が出来る。Slickは独自のクエリコンパイラを用いて、データベースに対するクエリを発行する。

すぐにSlickを試したいのなら、Typesafe Activatorを利用して、Hello Slick templateを試してみると良い。こちらを読むと、Slickがコードを生成したり出来る、サポートされたデータベースの概要が分かる。

Functional Relational Mapping 

関数型言語を用いるプログラマは長い間、リレーショナルデータベースを用いる際に、Object-RelationalとObject-Mathのミスマッチに悩まされてきた。Slickの持つ新たなFRMのパラダイムは、Scalaを通して、疎結合で最小限の設定のみで、リレーショナルデータベースへ接続する複雑さを抽象化する事を可能にした。

我々はリレーショナルモデルと闘おうとはしていない。ただ、関数型のパラダイムを通してリレーショナルモデルを包み込んだのだ。オブジェクトモデルとデータベースモデルのギャップに対してのブリッジを作ることで、Scala側へデータベースモデルを持ち込み、結果としてエンジニアはSQLを書く必要がなくなったのである。

class Coffees(tag: Tag) extends Table[(String, Double)](tag, "COFFEES") {
  def name = column[String]("COF_NAME", O.PrimaryKey)
  def price = column[Double]("PRICE")
  def * = (name, price)
}
val coffees = TableQuery[Coffees]

Slickはデータベースに関する事柄を直接Scala側へと統合させる。そして、メモリ上のデータを操作するのと同じように、従来のScalaのクラスやコレクションを扱うかのように、クエリを発行して外部のデータを操作するのである。

// nameカラムのみを取り出すクエリ (select NAME from COFFEES)
coffees.map(_.name)
...
// 10.0未満のpriceで絞り込んだクエリ (select * from COFFEES where PRICE < 10.0)
coffees.filter(_.price < 10.0)

これは、いつデータベースにアクセスしただとか、どのデータが変更されたかなどといったアクションを全てコントロール出来る。SlickのFRMに含まれる、言語に統合されたクエリモデルは、MicrosoftのLINQやEricssonのMnesiaの早期のコンセプトに影響を受けている。

関数型言語に対するSlickのFRMなアプローチには、以下のようなメリットが含まれている。

ORMとは異なりFRMは、より効率的にデータベースへ接続を行う。これは、データベースとの接続を最適化する機能を備えているためであり、さらにFRMを用いる事であなたは柔軟にその機能を利用出来る。より高速化されたアプリを作るためには、FRMはORMに比べ役に立つ。

FRMは型安全にデータベースのクエリを作成する事が出来る。今まで型のないただの文字列だけでエラーを探してきたデベロッパーにとっても、今や自動的にコンパイラがエラーを見つけてきてくれるのだ。

priceカラムのタイポがある場合には、コンパイラはこんな感じであなたにエラーを知らせてくれる。

GettingStartedOverview.scala:89: value prices is not a member of com.typesafe.slick.docs.GettingStartedOverview.Coffees
        coffees.map(_.prices).result
                      ^

他にも、こんな型エラーを知らせてくれる。

GettingStartedOverview.scala:89: type mismatch;
 found   : slick.driver.H2Driver.StreamingDriverAction[Seq[String],String,slick.dbio.Effect.Read]
    (which expands to)  slick.profile.FixedSqlStreamingAction[Seq[String],String,slick.dbio.Effect.Read]
 required: slick.dbio.DBIOAction[Seq[Double],slick.dbio.NoStream,Nothing]
        coffees.map(_.name).result
                            ^

FRMはクエリを作成するための合成可能なモデルをサポートしている。これはクエリを作る際に用いるいくつかのピースを合成するのに、非常に自然なモデルになっている。さらにこのようなモデルは、コード内で再利用もしやすい。

// priceが10未満で、name順にソートしたcoffeeの名前のみ取り出すクエリを作る
coffees.filter(_.price < 10.0).sortBy(_.name).map(_.name)
// select name from COFFEES where PRICE < 10.0 order by NAME

Reactive Applications 

非同期を中心にデザインされたアプリケーションや、Reactive Manifestoに従って作られたアプリケーションにとって、Slickは非常に使いやすいようになっている。一般的に用いられている処理をブロックするシンプルなデータベースAPIとは異なり、Slickは以下の事をあなたに提供してくれる。

Plain SQL Support 

SlickのScalaベースなクエリAPIは、Scalaコレクションを扱うかのように、データベースクエリを記述することが出来る。はじめようは、このAPIに焦点を当てたマニュアルになっている。

もし、あなたが独自のSQL文を通常のSlickのクエリと同様に非同期に実行したいと言うのならば、Plain SQL APIを利用する事が出来る。

val limit = 10.0
sql"select COF_NAME from COFFEES where PRICE < $limit".as[String]
// 変数はSQLインジェクションが無いように自動的に束縛される
// select COF_NAME from COFFEES where PRICE < ?

License 

Slick is released under a BSD-Style free and open source software license. See the chapter on the commercial Slick Extensions add-on package for details on licensing the Slick drivers for the big commercial database systems.

Next Steps 

Fork me on GitHub