hello-slick-3.0やってみた


## slickのチュートリアル
[ここ](https://www.typesafe.com/activator/template/hello-slick-3.0)からダウンロード

## とりあえずbuild
IntelliJでいじりたかったから```project/plugins.sbt```に記述を追加

```scala:plugins.sbt
addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.6.0")
```

その後，```sbt gen-idea```でbuild終わり

## チュートリアル
[Slick の Documentationを翻訳した](http://qiita.com/krrrr38/items/488ffc49a01cca8425f8)のリンクにあったSlick3.0.0の翻訳されたドキュメントを見て進めた．

### 構成

![スクリーンショット 2015-08-26 15.36.24.png](https://qiita-image-store.s3.amazonaws.com/0/84299/89518fe2-cf2f-ccbc-f6d4-c1b8b4e8350d.png "スクリーンショット 2015-08-26 15.36.24.png")

### Database Configration

```scala:application.conf
h2mem1 = {
	//urlで指定したとこにdbのファイルができる
  url = "jdbc:h2:file:~/Documents/workspace/scalatra/hello-slick-3.0/data"
  driver = org.h2.Driver
  connectionPool = disabled
  keepAliveConnection = true
}
```

DBオブジェクトを利用するときは

```scala:main/scala/CaseClassMapping.scala
val db = Database.forConfig("h2mem1")
  try {
    Await.result(db.run(DBIO.seq(
      // create the schema
      users.schema.create,

      // insert two User instances
      users += User("John Doe"),
      users += User("Fred Smith"),

      // print the users (select * from USERS)
      users.result.map(println)
    )), Duration.Inf)
  } finally db.close
```

こんな感じで利用

### Schema
スキーマを定義する．

```scala:main/scala/Tables.scala
import slick.driver.H2Driver.api._
import slick.lifted.{ProvenShape, ForeignKeyQuery}

// SUPPLIERテーブルの定義
class Suppliers(tag: Tag)
  extends Table[(Int, String, String, String, String, String)](tag, "SUPPLIERS") {

  // PK
  def id: Rep[Int] = column[Int]("SUP_ID", O.PrimaryKey)
  def name: Rep[String] = column[String]("SUP_NAME")
  def street: Rep[String] = column[String]("STREET")
  def city: Rep[String] = column[String]("CITY")
  def state: Rep[String] = column[String]("STATE")
  def zip: Rep[String] = column[String]("ZIP")
  
  // 全てのテーブルで，* 射影をテーブルの型パラメータに合うよう定義
  def * : ProvenShape[(Int, String, String, String, String, String)] =
    (id, name, street, city, state, zip)
}

// COFFEESテーブルの定義
class Coffees(tag: Tag)
  extends Table[(String, Int, Double, Int, Int)](tag, "COFFEES") {

  def name: Rep[String] = column[String]("COF_NAME", O.PrimaryKey)
  def supID: Rep[Int] = column[Int]("SUP_ID")
  def price: Rep[Double] = column[Double]("PRICE")
  def sales: Rep[Int] = column[Int]("SALES")
  def total: Rep[Int] = column[Int]("TOTAL")
  
  def * : ProvenShape[(String, Int, Double, Int, Int)] =
    (name, supID, price, sales, total)
  
  // joinなどを発行する際に用いられる外部キー
  def supplier: ForeignKeyQuery[Suppliers, (Int, String, String, String, String, String)] = 
    foreignKey("SUP_FK", supID, TableQuery[Suppliers])(_.id)
}
```

名前は一般的にSQL側では大文字とアンダースコアで，Scala側ではキャメルケースで記述される．

###DBの操作

```main/scala/HelloSlick.scala
import scala.concurrent.{Future, Await}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration
import slick.backend.DatabasePublisher
import slick.driver.H2Driver.api._

// The main application
object HelloSlick extends App {
  val db = Database.forConfig("h2mem1")
  try {

    // SUPPLIERSテーブルに対するクエリインタフェース
    val suppliers: TableQuery[Suppliers] = TableQuery[Suppliers]

    // COFFEESテーブルに対するクエリインタフェース
    val coffees: TableQuery[Coffees] = TableQuery[Coffees]

    val setupAction: DBIO[Unit] = DBIO.seq(
      //主キーや外部キーを含むテーブルを作成
      (suppliers.schema ++ coffees.schema).create,

      // Insert some suppliers
      // insert into SUPPLIERS(SUP_ID, SUP_NAME, STREET, CITY, STATE, ZIP) values (?,?,?,?,?,?)
      suppliers += (101, "Acme, Inc.", "99 Market Street", "Groundsville", "CA", "95199"),
      suppliers += ( 49, "Superior Coffee", "1 Party Place", "Mendocino", "CA", "95460"),
      suppliers += (150, "The High Ground", "100 Coffee Lane", "Meadows", "CA", "93966")


    )

    val setupFuture: Future[Unit] = db.run(setupAction)
    val f = setupFuture.flatMap { _ =>

      // Insert some coffees (using JDBC's batch insert feature)
      val insertAction: DBIO[Option[Int]] = coffees ++= Seq (
        ("Colombian",         101, 7.99, 0, 0),
        ("French_Roast",       49, 8.99, 0, 0),
        ("Espresso",          150, 9.99, 0, 0),
        ("Colombian_Decaf",   101, 8.99, 0, 0),
        ("French_Roast_Decaf", 49, 9.99, 0, 0)
      )
     ・
     ・
     val setupFuture = db.run(setup)
```

長くなるから割愛したが，本来のhello-slickにはこのほかにもupdate文や，delete文などのsampleが記述してある．

もう一度urlを載っけると，[hello-slick-3.0](https://www.typesafe.com/activator/template/hello-slick-3.0)です．

### 確認
本当にDBに登録されたのか確認してみる．

h2データベースを起動

自分の場合は```/Applications/h2```にh2を置いている．

```cd /Applications/h2/bin```
```java -jar h2*.jar```

でh2DBの起動

[MacでH2使う](http://qiita.com/kijitoraneko/items/eb525f673c54abbb505e)の記事を参考に，起動した後のurlをipアドレスではなく，localhostと変更したら無事動いた．

起動後，色々聞かれるから入力

|聞かれること|記述(載っけてるコードの場合)|
|:---:|:---:|
|ドライバクラス|org.h2.Driver|
|JDBC URL|jdbc:h2:file:~/Documents/workspace/scalatra/hello-slick-3.0/data|
|ユーザ名|空欄でok|
|パスワード|空欄でok|

無事ログインできるはず．


![スクリーンショット 2015-08-26 18.43.17.png](https://qiita-image-store.s3.amazonaws.com/0/84299/946a6439-2fa6-6f08-207f-c6d725e79e2d.png "スクリーンショット 2015-08-26 18.43.17.png")

無事中身が入ってることを確認できた．