Slick 2.0.0 documentation - 01 導入(Introduction) Permalink to Introduction — Slick 2.0.0 documentation

導入 

Slickとは 

SlickはTypesafe社によって開発が行われている、Scalaのためのモダンなデータベースラッパーである。データベースにアクセスしながらScalaのコレクションを扱うかのようにデータを操作する事が出来る。また、SQLを直接書く事も可能である。

val limit = 10.0
// クエリはこのように書く事が出来る
( for( c <- Coffees; if c.price < limit ) yield c.name ).list
// SQLを直接書いた例
sql"select name from coffees where price < $limit".as[String].list

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

すぐにSlickを試したいのなら、Typesafe ActivatorにあるHello Slickテンプレートを使うと良い。

Slickの特徴 

Scala 

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]
// name というカラムを返すクエリ
coffees.map(_.name)
// 価格が 10.0 未満という条件を用いたクエリ
coffees.filter(_.price < 10.0)

Type Safe 

// `select PRICE from COFFEES` の結果はSeq[Double]になる
// これは型安全な処理が行なわれるためである
val coffeeNames: Seq[Double] = coffees.map(_.price).list
// クエリを作るのも型安全に行なわれる
coffees.filter(_.price < 10.0)
// もし条件の中で異なる型が比較されていたのなら、コンパイルエラーになる

Composable 

// 10.0 未満の価格で、名前順にソートしたコーヒーの名前を取り出すクエリを作る
coffees.filter(_.price < 10.0).sortBy(_.name).map(_.name)
// ここで作られるSQLは次のものと等価になる
// select name from COFFEES where PRICE < 10.0 order by NAME

Compatibility 

SlickはScalaのバージョン2.10が必要になる。(もし2.9以下で使いたいならScalaQueryを使うと良い)

サポートするデータベース 

他のSQLデータベースもSlickなら簡単にアクセスする事が出来る。独自のSQLベースのバックエンドを持つデータベースも、プラグインを作成する事でSlickを利用することが出来ます。そのようなプラグインの作成は大きな貢献となる。 NoSQLのような他のバックエンドを持つようなデータベースに関しては現在開発中であるため、まだ利用する事はできません。

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.

Query APIs 

Lifted Embedding は型安全なクエリや更新が行えるSlickの基本的なAPIである。Getting Startedでは Lifted Embedding を用いた例を紹介する。

SQL文を直接発行したい場合には、Plain SQL API を利用することが出来る。

Direct Embeddingはまだ実験的なものではあるが、Lifted Embeddingに替わりとして利用出来る。

Lifted Embedding 

Lifted Embeddingという名前は基本的なScalaの型を用いるのではなく、 Rep型へと持ち上げ(lifted)されたものを用いるという事に基づいている。これはScalaのコレクションを操作する例と比べると明らかだろう。

case class Coffee(name: String, price: Double)
val coffees: List[Coffee] = //...
...
val l = coffees.filter(_.price > 8.0).map(_.name)
//                       ^       ^          ^
//                       Double  Double     String

… Lifted Embeddingを用いる際には次のように書ける

class Coffees(tag: Tag) extends Table[(String, Double)](tag, "COFFEES") {
  def name = column[String]("COF_NAME")
  def price = column[Double]("PRICE")
  def * = (name, price)
}
val coffees = TableQuery[Coffees]
...
val q = coffees.filter(_.price > 8.0).map(_.name)
//                       ^       ^          ^
//               Rep[Double]  Rep[Double]  Rep[String]

全ての型はRepへと持ち上げられる。カラムの型であるCoffeesも同様にRep[(String, Double)]へと持ち上げられる。数値リテラルである8.0も自動的にRep[Double]へと持ち上げられる。これは条件式>の左辺がRep[Double]であることから、右辺には暗黙的な変換が行われるためである。生のScalaの型や値を用いることは、SQLへの変換を行う上で充分な情報を提供しない。これらの変換はそのために行なわれるのである。

Fork me on GitHub