Slick 對(duì)于 Scala 來(lái)說(shuō),有如 LINQ 至于 C#,或者類(lèi)似于其它平臺(tái)上的 ORM 系統(tǒng),它使用應(yīng)用使用數(shù)據(jù)庫(kù)有如使用 Scala 內(nèi)置的集合類(lèi)型(比如列表,集合等)一樣方便。當(dāng)然如有需要你還是可以直接使用 SQL 語(yǔ)句來(lái)查詢(xún)數(shù)據(jù)庫(kù)。
下面為使用 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 語(yǔ)句,可以使用編譯器幫助發(fā)現(xiàn)一些類(lèi)型錯(cuò)誤,同時(shí) Slick 可以為不同的后臺(tái)數(shù)據(jù)庫(kù)類(lèi)型生成查詢(xún)。
它具有如下的一些特征:
所有查詢(xún),表格和字段映射,以及類(lèi)型都采用普通的 Scala 語(yǔ)法。
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ù)訪問(wèn)接口類(lèi)型 Scala 的集合類(lèi)型
// Query that only returns the "name" column
coffees.map(_.name)
// Query that does a "where price < 10.0"
coffees.filter(_.price < 10.0)
你使用的 IDE 可以幫助你寫(xiě)代碼在編譯時(shí)而無(wú)需到運(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
查詢(xún)接口為函數(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ù)庫(kù)類(lèi)型 Slick 也提供了有限的支持。
Sclick 使用 Lifted Embedding 作為標(biāo)準(zhǔn)的數(shù)據(jù)庫(kù)查詢(xún)接口,此外 Direct Embedding 接口正在開(kāi)發(fā)測(cè)試當(dāng)中。
Lifted Embedding 的名稱(chēng)來(lái)自于,你不是使用標(biāo)準(zhǔn)的 Scala 數(shù)據(jù)類(lèi)型來(lái)訪問(wèn)查詢(xún)數(shù)據(jù)庫(kù),而是使用 Rep 構(gòu)造器來(lái)提升(Lift)Scala 的基本數(shù)據(jù)類(lèi)型,然后使用提升后的數(shù)據(jù)類(lèi)型來(lái)訪問(wèn)數(shù)據(jù)庫(kù),比如標(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 類(lèi)型,都提升為 Rep。即使是 8.0 字面量也被提升為 Rep[Double] 類(lèi)型。
后面的例子,我們會(huì)采用 Chinook 數(shù)據(jù)庫(kù)作為例子。
Chinook 數(shù)據(jù)庫(kù)前身為著名的 Northwind 數(shù)據(jù)庫(kù),它的數(shù)據(jù)模型如下:
更多建議: