hangscer

Essential Slick 学习笔记(一)

2017/06/07

闲话💐

以前呢,Slick没有认真的去学习,都是需要在用它的时候再去看文档,片段式地学习。

现在UnderSocre.io把它的图书开源了,借此机会系统的学学(你这么热爱学习,能有女朋友吗😂),作作笔记。

不得不说,Slick确实比Quill难得多,设计层面颇为繁琐,而且还是异步执行。如果对scala异步以及回调不太熟悉的同学,可能对Slick上手有难度。

不能简单的把Slick以及Quill这样的框架归结为ORM框架,因为其中还融入了Monad、Monoid等函数式概念。官方说他们的框架是FRM(Functional Relational Mapping),却是恰如其分。

简单入门

sbt依赖配置(采用mysql数据库,Slick版本是3.2.0):

1
2
3
4
5
6
libraryDependencies ++= Seq(
"com.typesafe.slick" %% "slick" % "3.2.0",
"org.slf4j" % "slf4j-nop" % "1.6.4",
"com.typesafe.slick" %% "slick-hikaricp" % "3.2.0"
)
libraryDependencies += "mysql" % "mysql-connector-java" % "5.1.40"

application.conf配置为:

1
2
3
4
5
6
7
8
mysqltest = {
url = "jdbc:mysql://localhost:3306/nathan_db"
driver = "com.mysql.jdbc.Driver"
user = "root"
password = "***********"
connectionPool = disabled
keepAliveConnection = true
}

入门程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package nathan
import slick.jdbc.MySQLProfile.backend.Database
import slick.jdbc.MySQLProfile.api._
import scala.concurrent.ExecutionContext.Implicits.global
/**
* Created by nathan on 17/3/22.
*/
object Main extends App {
val db=Database.forConfig("mysqltest")
val suppliers=TableQuery[Suppliers]
val coffees=TableQuery[Coffees]
val setup=DBIO.seq(
(suppliers.schema++coffees.schema).create,
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"),
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)
)
)
db.run(setup)
Thread.sleep(1000)
}
class Suppliers(tag: Tag) extends Table[(Int,String,String,String,String,String)](tag,"Suppliers"){
def id=column[Int]("sup_id",O.PrimaryKey,O.AutoInc)
def name=column[String]("sup_name")
def street=column[String]("street")
def city=column[String]("city")
def state=column[String]("state")
def zip=column[String]("zip")
def * = (id,name,street,city,state,zip)
}
class Coffees(tag:Tag) extends Table[(String,Int,Double,Int,Int)](tag,"coffees"){
def name=column[String]("cof_name",O.PrimaryKey)
def supId=column[Int]("sup_id")
def price=column[Double]("price")
def sales=column[Int]("sales")
def total=column[Int]("total")
def * = (name,supId,price,sales,total)
def supplier=foreignKey("sup_fk",supId,TableQuery[Suppliers])(s=>s.id)
}

这里是查询:

1
db.run(suppliers.result).foreach(println)

更或者(for推导式风格,底层还是通过Monad转换为map、flatMap等函数):

1
2
3
4
5
val r=for{
s<-suppliers if s.id<200
}yield s.name
db.stream(r.result).foreach(println)
db.run(r.result).foreach(println)