鍍金池/ 教程/ Scala/ 基本查詢
概述
基本查詢
查詢(二)
查詢(三)
直接使用 SQL 語句
數(shù)據(jù)庫連接和事務處理
數(shù)據(jù)庫 Schema
查詢(一)
準備開發(fā)環(huán)境

基本查詢

我們準備好了開發(fā)環(huán)境,下面就來看看 Slick 的基本查詢方法,我們打算查詢 Chinook 中的 Album 表,我們先看看之前自動生成的代碼中表 Album 的定義:

/** Entity class storing rows of table Album
   *  @param albumid Database column AlbumId PrimaryKey
   *  @param title Database column Title
   *  @param artistid Database column ArtistId  */
case class AlbumRow(albumid: Int, title: String, artistid: Int)
    /** GetResult implicit for fetching AlbumRow objects using plain SQL queries */
    implicit def GetResultAlbumRow(implicit e0: GR[Int], e1: GR[String]): GR[AlbumRow] = GR{
    prs => import prs._
    AlbumRow.tupled((<<[Int], <<[String], <<[Int]))
}
/** Table description of table Album. Objects of this class serve as prototypes for rows in queries. */
class Album(tag: Tag) extends Table[AlbumRow](tag, "Album") {
    ...
    /** Database column AlbumId PrimaryKey */
    val albumid: Column[Int] = column[Int]("AlbumId", O.PrimaryKey)
    /** Database column Title  */
    val title: Column[String] = column[String]("Title")
    /** Database column ArtistId  */
    val artistid: Column[Int] = column[Int]("ArtistId")

    /** Foreign key referencing Artist (database name FK_AlbumArtistId) */
    lazy val artistFk = foreignKey("FK_AlbumArtistId", artistid, Artist)
        (r => r.artistid, onUpdate=ForeignKeyAction.NoAction, onDelete=ForeignKeyAction.NoAction)
}
    /** Collection-like TableQuery object for table Album */
    lazy val Album = new TableQuery(tag => new Album(tag))

可以看到對于數(shù)據(jù)庫中每個表,我們定義了一個 case class 代表表的一行,如 AlbumRow,一個 Table 類,比如 Album,還定義了一個 lazy 變量 Album,可以直接使用這個變量以集合類對象的方式來查詢數(shù)據(jù)表。下面我們看看查詢的基本用法:

我們在和 Tables.scala 的同一個目錄下(本例為 com/guidebee/slick/example)創(chuàng)建一個 Example.scala 文件:

package com.guidebee.slick.example

import scala.slick.driver.MySQLDriver.simple._
import com.guidebee.slick.example.Tables._
// The main application
object Example extends App {

    Database.forURL("jdbc:mysql://127.0.0.1/Chinook",
        driver = "com.mysql.jdbc.Driver",
        user="user",
        password="password").withSession {
            implicit session =>
            // <- write queries here
            Album foreach { case AlbumRow(albumId,title,artistId) =>
            println(" " + albumId + ":" + title + ":" + artistId)
            }
        }

}

注意:修改正確的用戶名和密碼。

其中代碼

    Database.forURL("jdbc:mysql://127.0.0.1/Chinook",
        driver = "com.mysql.jdbc.Driver",
        user="user",
        password="password").withSession {
          implicit session =>
          // <- write queries here

           }
        }

用來連接數(shù)據(jù)庫,并且創(chuàng)建一個 Session 對象,所有數(shù)據(jù)庫相關查詢都可以在這個代碼塊中實現(xiàn),這里我們打印出 Album 中所有記錄:

http://wiki.jikexueyuan.com/project/slick-guide/images/20140716001.png" alt="圖片" />

Album 為一集合對象,因此我們可以使用 Scala 集合對象支持的方法,來過濾,比較,比如:

val q1= for (a <- Album;if a.albumid<10)
     yield (a.albumid,a.title,a.artistid)
q1 foreach println

顯示前 9 條記錄: (1,For Those About To Rock We Salute You,1) (2,Balls to the Wall,2) (3,Restless and Wild,2) (4,Let There Be Rock,1) (5,Big Ones,3) (6,Jagged Little Pill,4) (7,Facelift,5) (8,Warner 25 Anos,6) (9,Plays Metallica By Four Cellos,7)

val q1= for (a <- Album;if a.albumid<10)
    yield a.albumid.asColumnOf[String] ++ LiteralColumn(":") ++ a.title
q1 foreach println

1:For Those About To Rock We Salute You 2:Balls to the Wall 3:Restless and Wild 4:Let There Be Rock 5:Big Ones 6:Jagged Little Pill 7:Facelift 8:Warner 25 Anos 9:Plays Metallica By Four Cellos

我們再來看看多個表 Join 的情況:先看看直接使用 SQL 語句

select album.AlbumId,album.Title,artist.Name from album
INNER JOIN artist 
ON album.ArtistId=artist.ArtistId
WHERE album.AlbumId<10

http://wiki.jikexueyuan.com/project/slick-guide/images/20140716002.png" alt="圖片" />

那么使用 Scala 語句如何實現(xiàn)呢,也就是多個集合對象 Join 的情況:

val q3 = for {
    a <- Album if a.albumid < 10
    t <- Artist if a.artistid===t.artistid 
}  yield (a.albumid,a.title,t.name)
q3 foreach println

注意,比較運算符為===,我們也可以直接使用外鍵來查詢,在 Tables.scala,類 Album 中定義了一個外鍵 artistFk

val q2 = for {
    a <- Album if a.albumid < 10
    t <- a.artistFk
} yield (a.albumid,a.title,t.name)
q2 foreach println

兩種方法都輸出如下結(jié)果:

(1,For Those About To Rock We Salute You,Some(AC/DC))
(2,Balls to the Wall,Some(Accept))
(3,Restless and Wild,Some(Accept))
(4,Let There Be Rock,Some(AC/DC))
(5,Big Ones,Some(Aerosmith))
(6,Jagged Little Pill,Some(Alanis Morissette))
(7,Facelift,Some(Alice In Chains))
(8,Warner 25 Anos,Some(Ant?nio Carlos Jobim))
(9,Plays Metallica By Four Cellos,Some(Apocalyptica))