Slick 對(duì)于 Scala 來說,有如 LINQ 至于 C#,或者類似于其它平臺(tái)上的 ORM 系統(tǒng),它使用應(yīng)用使用數(shù)據(jù)庫有如使用 Scala 內(nèi)置的集合類型(比如列表,集合等)一樣方便。當(dāng)然如有需要你還是可以直接使用 SQL 語句來查詢數(shù)據(jù)庫。
下面為使用 Slick 的代碼片段:
val limit = 10.0
// Your query could look like this:
( for( c <- coffees; if c.price < limit ) yield c.name ).list
// Or using more plain SQL String Interpolation:
sql"select COF_NAME from COFFEES where PRICE < $limit".as[String].list
// Both queries result in SQL equivalent to:
// select COF_NAME from COFFEES where PRICE < 10.0
使用 Slick 而不直接使用 SQL 語句,可以使用編譯器幫助發(fā)現(xiàn)一些類型錯(cuò)誤,同時(shí) Slick 可以為不同的后臺(tái)數(shù)據(jù)庫類型生成查詢。
它具有如下的一些特征:
所有查詢,表格和字段映射,以及類型都采用普通的 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]
數(shù)據(jù)訪問接口類型 Scala 的集合類型
// Query that only returns the "name" column
coffees.map(_.name)
// Query that does a "where price < 10.0"
coffees.filter(_.price < 10.0)
你使用的 IDE 可以幫助你寫代碼在編譯時(shí)而無需到運(yùn)行時(shí)就可以發(fā)現(xiàn)一些錯(cuò)誤
// The result of "select PRICE from COFFEES" is a Seq of Double
// because of the type safe column definitions
val coffeeNames: Seq[Double] = coffees.map(_.price).list
// Query builders are type safe:
coffees.filter(_.price < 10.0)
// Using a string in the filter would result in a compilation error
查詢接口為函數(shù),這些函數(shù)可以多次組合和重用。
// Create a query for coffee names with a price less than 10, sorted by name
coffees.filter(_.price < 10.0).sortBy(_.name).map(_.name)
// The generated SQL is equivalent to:
// select name from COFFEES where PRICE < 10.0 order by NAME
對(duì)于其它的一些數(shù)據(jù)庫類型 Slick 也提供了有限的支持。
Sclick 使用 Lifted Embedding 作為標(biāo)準(zhǔn)的數(shù)據(jù)庫查詢接口,此外 Direct Embedding 接口正在開發(fā)測(cè)試當(dāng)中。
Lifted Embedding 的名稱來自于,你不是使用標(biāo)準(zhǔn)的 Scala 數(shù)據(jù)類型來訪問查詢數(shù)據(jù)庫,而是使用 Rep 構(gòu)造器來提升(Lift)Scala 的基本數(shù)據(jù)類型,然后使用提升后的數(shù)據(jù)類型來訪問數(shù)據(jù)庫,比如標(biāo)準(zhǔn)的 Scala 集合的例子:
case class Coffee(name: String, price: Double)
val coffees: List[Coffee] = //...
val l = coffees.filter(_.price > 8.0).map(_.name)
// ^ ^ ^
// Double Double String
而對(duì)應(yīng)的提升之后的例子:
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]
所有的基本 Scala 類型,都提升為 Rep。即使是 8.0 字面量也被提升為 Rep[Double] 類型。
后面的例子,我們會(huì)采用 Chinook 數(shù)據(jù)庫作為例子。
Chinook 數(shù)據(jù)庫前身為著名的 Northwind 數(shù)據(jù)庫,它的數(shù)據(jù)模型如下:
更多建議: