Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.
-
Upload
yvonne-francy -
Category
Documents
-
view
221 -
download
2
Transcript of Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.
![Page 1: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/1.jpg)
Slick SQL Interactionin Scala
Jan Christopher Vogt, EPFLSlick Team
![Page 2: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/2.jpg)
(vs. ORM)
• Functional-Relational Mapper• natural fit (no impedance mismatch)• declarative• embraces relational• stateless• Slick is to ORM what Scala is to Java
![Page 3: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/3.jpg)
8 Reasons for using Slick
![Page 4: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/4.jpg)
1Scala collection-like
API
![Page 5: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/5.jpg)
Scala collection-like API
for ( d <- Devices; if d.price > 1000.0) yield d.acquisition
Devices .filter(_.price > 1000.0) .map(_.acquisition)
Deviceid: Longprice: Doubleacquisition: Date
![Page 6: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/6.jpg)
2Predictable SQL structure
![Page 7: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/7.jpg)
Predictable SQL structure
Devices .filter(_.price > 1000.0) .map(_.acquisition) .selectStatement
select x2."ACQUISITION" from "DEVICE" x2 where x2."PRICE" > 1000.0
![Page 8: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/8.jpg)
3Type-safety
![Page 9: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/9.jpg)
Compile-Time Safety
• Spelling mistake in column name?• Wrong column type?• Query doesn’t match the result type?
scalac sees it all!
![Page 10: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/10.jpg)
• Error messages can destroy the illusion
Caution: Error messages can be bad
![Page 11: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/11.jpg)
Enforce schema consistency
• Generate DDL from table classes• Slick 2.0: Generate table classes and mapped
classes from database
![Page 12: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/12.jpg)
4Small configuration
using Scala code
![Page 13: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/13.jpg)
Table description
class Devices(tag: Tag) extends Table[(Long, Double, Date)](tag,"DEVICE") { def id = column[Long] ("ID", O.PrimaryKey) def price = column[Double]("PRICE") def acquisition = column[Date] ("ACQUISITION") def * = (id, price, acquisition)
}def Devices = TableQuery[Devices]
can be auto-generated in Slick 2.0
![Page 14: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/14.jpg)
Connect
import scala.slick.driver.H2Driver.simple._
val db = Database.forURL( "jdbc:h2:mem:testdb", "org.h2.Driver")
db.withTransaction { implicit session =>
// <- run queries here
}
![Page 15: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/15.jpg)
5Explicit control over
execution and transfer
![Page 16: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/16.jpg)
Execution control
val query = for { d <- Devices if d.price > 1000.0 } yield d.acquisition
db.withTransaction { implicit session =>
val acquisitonDates = query.run
}
Deviceid: Longprice: Doubleacquisition: Date
(session)
no unexpected behavior,no loading strategy configuration,just write code
![Page 17: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/17.jpg)
6Loosely-coupled, flexible mapping
![Page 18: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/18.jpg)
Table description
class Devices(tag: Tag) extends Table[(Long, Double, Date)](tag,"DEVICE") { def id = column[Long] ("ID", O.PrimaryKey) def price = column[Double]("PRICE") def acquisition = column[Date] ("ACQUISITION") def * = (id, price, acquisition)
}val Devices = TableQuery[Devices]
![Page 19: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/19.jpg)
case class mapping
class Devices(tag: Tag) extends Table[Device](tag,"DEVICE") { def id = column[Long] ("ID", O.PrimaryKey) def price = column[Double]("PRICE") def acquisition = column[Date] ("ACQUISITION")
def * = (id, price, acquisition) <> (Device.tupled,Device.unapply)}val Devices = TableQuery[Devices]
case class Device(id: Long, price: Double, acquisition: Date)
![Page 20: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/20.jpg)
Custom mapping
class Devices(tag: Tag) extends Table[CustomType](tag,"DEVICE") { def id = column[Long] ("ID", O.PrimaryKey) def price = column[Double]("PRICE") def acquisition = column[Date] ("ACQUISITION")
def * = (id, price, acquisition) <> (construct,extract)}val Devices = TableQuery[Devices]
def construct : ((Long,Double,Date)) => CustomTypedef extract: CustomType => Option[(Long,Double,Date)]
![Page 21: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/21.jpg)
7Plain SQL support
![Page 22: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/22.jpg)
Plain SQL supportimport scala.slick.jdbc.{GetResult, StaticQuery}import StaticQuery.interpolation
implicit val getDeviceResult = GetResult(r => Device(r.<<, r.<<, r.<<))
val price = 1000.0
val expensiveDevices: List[Device] = sql"select * from DEVICE where PRICE > $price" .as[Device].list
![Page 23: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/23.jpg)
8composable /
re-usable queries
![Page 24: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/24.jpg)
Composable, re-usable queriesdef deviceLocations (companies: Query[Companies,Company]) : Query[Column[String],String] = { companies.computers.devices.sites.map(_.location)}
val apples = Companies.filter(_.name iLike "%apple%")val locations : Seq[String] = { deviceLocations(apples) .filter(_.inAmerica: Column[String]=>Column[Boolean]) .run}
re-use queries
re-use user-defined operators
re-use joins
execute exactly one, precise query
![Page 25: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/25.jpg)
Live Demo
![Page 26: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/26.jpg)
Slick app design
![Page 27: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/27.jpg)
Mental paradigm shift
Non-composable executor APIs (DAOs) DevicesDAO .inPriceRange( 500.0, 2000.0 ) : List[Device]
Composable query libraries devices .inPriceRange( 500.0, 2000.0 ) : Query[_,Device]
executes
composes
![Page 28: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/28.jpg)
Non-composableExecutor API / DAO
def byId( id:Long ) : Device
def withComputers : Map[…,Seq[Computer]]
…
ComposableQuery Library
def byId( Column[Long] ) : Query[…,Computers]
def withComputers : Query[…,(…,Computers)]
def iLike( Column[String] ) : Column[Boolean]
…
Table classes
CompaniesComputersDevicesSites…
Controller Database SessionView
Suggested Slick app architecture
![Page 29: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/29.jpg)
Relationships / Associations
• Via composable queries using foreign keys!
companies.withComputers : Query[…,(Company,Computer)]
• Not object references within query results• Not executor APIs
![Page 30: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/30.jpg)
Auto joins(only in play-slick sample app)implicit def autojoin1 = joinCondition[Sites,Devices] (_.id === _.siteId)implicit def autojoin2 = joinCondition[Devices,Computers] (_.computerId === _.id)
sites.autoJoin(devices).further(computers) : Query[_,(Site,Computer)]sites.autoJoin(devices).autoJoinVia(computers)(_._2) : Query[_,((Site,Device),Computer)]
Site
id: Longname: String
Device
id: Longprice: Doubleacquisition: DatesiteId: Long
1n
Computer
Id: LongName: StringcompanyId: Int
1 n
![Page 31: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/31.jpg)
Other features
![Page 32: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/32.jpg)
Other features
• inserts += ++=, updates query.update(…)• user defined column types, e.g. type-safe ids• user defined database functions• …
![Page 33: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/33.jpg)
Outlook
![Page 34: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/34.jpg)
2.0 is around the corner
• code-generation based type providers• hlists and custom shapes (no 22-col limit,
easy integration with shapeless, etc.)• distributed queries (over multiple dbs)• improved pre-compiled queries
![Page 35: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/35.jpg)
Current experiments
• improved macro-based api (simpler types)• macro-based type providers• schema manipulation api• migration/version management tool• extended for-comprehensions (order, group)
Thanks to @amirsh @clhodapp @nafg
![Page 36: Slick SQL Interaction in Scala Jan Christopher Vogt, EPFL Slick Team.](https://reader034.fdocuments.in/reader034/viewer/2022051614/5518be9e550346b31f8b5494/html5/thumbnails/36.jpg)
slick.typesafe.com
@cvogt@StefanZeiger
http://slick.typesafe.com/talks/https://github.com/cvogt/play-slick/
Thank you