Slick is a modern database query and access library for Scala. It allows you to work with stored data almost as if you were using Scala collections while at the same time giving you full control over when a database access happens and which data is transferred. You can write your database queries in Scala instead of SQL, thus profiting from the static checking, compile-time safety and compositionality of Scala. Slick features an extensible query compiler which can generate code for different backends.
2. TTooppiiccss CCoovveerreedd
What is slick
Table definition
Queries and Joins
Query extensions
Nested Mapped entity
Unit testing with H2 database
Live Demo
3. What is Slick
for{e ← Employees} yield e “select * from employee”
● Slick is a library written in scala for talking to database from scala programs.
● It is currently based on Jdbc.
● It is Successor of ScalaQuery.
● Developed By Typesafe and EPFL(École Polytechnique Fédérale de Lausanne)
8. Table Creation And Data Insertion
// ddl
(knolTable.ddl ++ knolXTable.ddl).create
// insert a record
knolTable.insert(Knol("saurabh", "saurabh@knoldus.com", new Date("01/07/1985")))
knolTable +=Knol("saurabh", "saurabh@knoldus.com", new Date("01/07/1985"))
// insert List of record
val list=List(Knol("saurabh", "saurabh@knoldus.com", new Date("01/07/1985")))
knolTable.insertAll(list:_*)
knolTable ++=list
9. Auto Generated Keys
val knolAutoInc = knolTable returning knolTable.map(_.id)
val kId =
knolAutoInc.insert(Knol("anand", "anand@knoldus.com", new Date("01/07/1986")))
knolXTable.insert(KnolX("play framework", new Date("03/05/2014"), kId))
knolXTable.insert(KnolX("Anorm", new Date("07/23/2014"), kId))
14. Update and Delete
//update name of knol which have id =2
val updatedObj = Knol("Anand Singh", "anand@knoldus.com", new Date("01/07/1986"))
knolTable.filter { knol => knol.id === 2 }.update(updatedObj)
* This is not good because we updating complete row instead on one column So :
knolTable.filter { knol => knol.id === 2 }.map(_.name).update("Anand Singh")
// delete record of id=2
knolTable.filter { knol => knol.id === 2 }.delete
15. Sorting , Filtering and Pagination
// ascending sorting
val sortedList = knolTable.sortBy(knol => knol.name.asc).list
// descending sorting
val reverseSortedList = knolTable.sortBy(knol => knol.name.desc).list
//filtering
val filteredList = knolTable.filter {
knol => knol.dob < (new Date("01/07/1988"))
}.map(_.name).list
// pagination
val page = knolTable.drop(2).take(1).list
16. Compiled Queries
Database queries typically depend on some parameters, e.g. an ID for which you want to
retrieve a matching database row. You can write a regular Scala function to create a
parameterized Query object each time you need to execute that query but this will
incur the cost of recompiling the query in Slick.
def getKnolCompiledQuery = {
Compiled(
(knolId: Column[Int]) =>
for { knol <- knolTable.filter(_.id === knolId) } yield (knol))
}
getKnolCompiledQuery(2).list
17. Inner join
/** implicit inner join */
val implicitInnerQuery = for {
knol: KnolTable <- knolTable
knolX: KnolXTable <- knolXTable if (knolX.knolId === knol.id)
} yield (knol, knolX)
/** explicit inner join */
val innerQuery = for {
(knol, knolX) <- knolTable innerJoin knolXTable on (_.id === _.knolId)
} yield (knol, knolX)
OR
val innerQuery = knolTable innerJoin knolXTable on (_.id === _.knolId)
18. Left Join
val leftJoinQuery = for {
(knol, knolX) <- knolTable leftJoin knolXTable on (_.id === _.knolId)
} yield (knol, knolX)
OR
val leftJoinQuery = knolTable leftJoin knolXTable on (_.id === _.knolId)
In left join, right-hand side have some additional null. So to avoid null
pointer exception use :
val leftJoin = for {
(knol, knolX) <- knolTable leftJoin knolXTable on (_.id === _.knolId)
} yield (knol, (knolX.topic.?, knolX.date.?, knolX.knolId.?, knolX.id.?))
19. Right Join
val rightJoin = for {
(knol, knolX) <- knolTable rightJoin knolXTable on (_.id === _.knolId)
} yield (knol, knolX)
OR
val rightJoin = knolTable rightJoin knolXTable on (_.id === _.knolId)
.
In right join, left-hand side have some additional null. So to avoid null pointer
exception use :
val rightJoin = for {
(knol, knolX) <- knolTable rightJoin knolXTable on (_.id === _.knolId)
} yield ((knol.name.?, knol.email.?, knol.dob.?,knol.id.?), knolX)
20. Full Outer Join
val fullOuterJoin = for {
(knol, knolX) <- knolTable outerJoin knolXTable on (_.id === _.knolId)
} yield (knol, knolX)
OR
val fullOuterJoin1 = knolTable outerJoin knolXTable on (_.id === _.knolId)
/** Full outer join have additional null both right and left side.*/
val fullOuterJoin = for {
(knol, knolX) <- knolTable outerJoin knolXTable on (_.id === _.knolId)
} yield (
(knol.name.?, knol.email.?, knol.dob.?, knol.id.?),
(knolX.topic.?, knolX.date.?, knolX.knolId.?, knolX.id.?))
25. Query extensions summary
• Mindshift required!
Think code, not monolithic query strings.
• Stay completely lazy!
Keep Query[...]s as long as you can.
• Re-use!
Write query functions or extensions methods for shorter, better and DRY code.