[Scala] ScalaQuery 筆記(一)

什麼是 ScalaQuery?

ScalaQuery 是一套 Scala 的資料庫 API / DSL 函式庫(也算是某種程度上的 ORM),透過 ScalaQuery 配合上適當的 JDBC Driver,你可以輕鬆地使用 Scala 內建的語法來操作資料庫,而不需要直接使用 SQL。

ScalaQuery 有以下的特點:

  • 沒有複雜的相依性

    • ScalaQuery 的相依性及少,你只需要 JDBC Driver 和 ScalaQuery 本身就可以了!
  • 使用簡易的 Scala API 來操作資料庫

    • 雖然低階的 JDBC API 相當強大,但卻也拌隨著囉唆的雜事,例如資料庫資源的管裡等等,而 JDBC API 在許多方面並不符合 Scala 的風格。ScalaQuery 則試圖減少這些雜事,讓你專注在程式最核心的工作上,同時也提供了較符合 Scala 風格的資料庫操作 API。
  • 編譯時期檢查及靜態型別

    • 直接使用 JDCB 以及 SQL 來操作資料庫時,常常會有資料庫表中的資型別與程式內的資料型別不符的問題,造成執行時期爆炸。相反的,在 ScalaQuery 中,所有的資料表和欄位都是靜態型別,因此可以在編譯時就找出此類的錯誤。
  • 和 Scala Collection 類似的抽象層

    • 與其他傳統的 ORM 的策略不同,ScalaQuery 是建構在關聯代數上,並且提供了類似於 Scala Collection 函式庫的 API,換句話說,你可以輕易地用 Scala 的 for expression 或 map、filter 等你熟悉的函式來組合出你想要的查詢。

使用 SBT 設定 ScalaQuery

GitHub 上的範例檔案

在開始之前,先提醒您,本節的完整程式範例,可以經由 GitHub 取得:

$ git clone git://github.com/brianhsu/scalaquery-tut.git
$ cd scalaquery-tut.git
$ git checkout origin/SetupBySBT -b SetupBySBTT

由於 ScalaQuery 已經被納入 ScalaTools 的 Maven 資源庫中,最新的版本是 0.9.1,所以如果你使用的建置系統支援 Maven 的話,可以直接使用以下的資料設置 ScalaQuery。

  • Maven Repository

    • url: http://scala-tools.org/repo-releases
  • ScalaQuery POM

    • groupId: org.scalaquery
    • artifactId: scalaquery
    • version: 0.9.1

SBT 是一套專門為了 Scala 打造的程式編譯及建置系統,有著非常強大和方便的功能,同時也是目前 Scala 生態圈中最受歡迎的建置系統之一,所以在接下來的範例中,我們會採用 SBT 做為我們的建置系統。

如果你還沒有安裝和使用過 SBT 的話,請務必先看一下 SBT 的說明文件並且安裝 SBT,相信我,這是值得的。;-)

當安裝完 SBT 後,請執行 sbt 來建立出我們的專案。

brianhsu@NBGentoo ~ $ mkdir scalaquery-tut
brianhsu@NBGentoo ~ $ cd scalaquery-tut/
brianhsu@NBGentoo ~/scalaquery-tut $ sbt
Project does not exist, create new project? (y/N/s) y
Name: ScalaQueryTut
Organization: scalaquery-tut
Version [1.0]: 
Scala version [2.8.1]: 
sbt version [0.7.5.RC0]: 
Getting Scala 2.7.7 ...

  << deleted >>

[info] Building project ScalaQueryTut 1.0 against Scala 2.8.1
[info]    using sbt.DefaultProject with sbt 0.7.5.RC0 and Scala 2.7.7
> 

如果你看到 > 符號的話,就代表 SBT 已經準備好,可以接受你輸入的命令了。

接著,請開啟你最後的編輯器,建立 scalaquery-tut/project/build/ScalaQueryTutProject.scala 這個檔案,並輸入以下的內容:

import sbt._

class UCProject(info: ProjectInfo) extends DefaultProject(info)
{
    val scalaQuery = "org.scalaquery" %% "scalaquery" % "0.9.1"
    val sqliteJDBC = "org.xerial" % "sqlite-jdbc" % "3.6.16"
}

在這個例子中,我們告訴 SBT 請他幫我們下載 ScalaQuery 以及 SQLite 的 JDBC Driver 函式庫,並且將這些函式庫設定在我們的 classpath 之中。

之後回到 SBT 的畫面,先輸入 reload 指令,讓 SBT 重新讀取我們的相依性設定,並且輸入 update 指令,讓 SBT 開始下載 ScalaQuery 和 SQLite Driver 函式庫。

> reload
[info] Building project ScalaQueryTut 1.0 against Scala 2.8.1
[info]    using UCProject with sbt 0.7.5.RC0 and Scala 2.7.7
> update
[info] 
[info] == update ==
[info] :: retrieving :: bone#scalaquerytut_2.8.1 [sync]
[info]  confs: [compile, runtime, test, provided, system, optional, sources, javadoc]
[info]  3 artifacts copied, 0 already retrieved (4017kB/49ms)
[info] == update ==
[success] Successful.
[info] 
[info] Total time: 2 s, completed 2011/3/28 上午 09:09:13
> 

如果沒意外的話,你應該可以看到 SBT 出現 Successful 的訊息,告訴你已經將相關的函式庫下載回來了。

接著,請在 SBT 畫面中下達 console 指令,這會產生一個包含了 ScalaQuery 以及 SQLite JDBC 函式庫的 classpath 的 Scala REPL,我們可以在這個 REPL 中測試我們的專案是否有正確的設定。

> console
[info] 
[info] == compile ==
[info]   Source analysis: 0 new/modified, 0 indirectly invalidated, 0 removed.
[info] Compiling main sources...
[info] Nothing to compile.
[info]   Post-analysis: 0 classes.
[info] == compile ==

  << deleted >>

Welcome to Scala version 2.8.1.final (OpenJDK Server VM, Java 1.6.0_20).
Type in expressions to have them evaluated.
Type :help for more information.

scala> 

現在你會看到熟悉的 REPL,那就先來簡單地測試一下 ScalaQuery 有沒有被納入我們新增的專案的 classpath 之中唄。

scala> import org.scalaquery.session.Database
import org.scalaquery.session.Database

scala> import org.scalaquery.session.Database.threadLocalSession
import org.scalaquery.session.Database.threadLocalSession

scala> val databbase = Database.forURL("jdbc:sqlite::memory:", driver = "org.sqlite.JDBC")      
databbase: org.scalaquery.session.Database = org.scalaquery.session.Database$$anon$2@1aac78d

scala> 

如同你所見的,我們可以在 Scala REPL 中使用 ScalaQuery 提供的一些 API,看來是沒有什麼大問題囉。下一次,就來看看我們所要使用的資料庫範例吧!

回響