SlideShare a Scribd company logo
1 of 38
SSlliicckk 22..11..00 
Satendra Kumar 
Software Consultant 
Knoldus Software LLP
TTooppiiccss CCoovveerreedd 
What is slick 
Table definition 
Queries and Joins 
Query extensions 
Nested Mapped entity 
Unit testing with H2 database 
Live Demo
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)
Table Definition 
class KnolTable(tag: Tag) extends Table[(String, String, Date, Int)](tag, "knol") { 
def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) 
def name: Column[String] = column[String]("name", O.NotNull) 
def email: Column[String] = column[String]("email", O.NotNull) 
def dob: Column[Date] = column[Date]("dob", O.NotNull) 
def * = (name, email, dob, id) 
} 
val knolTable = TableQuery[KnolTable]
Custom Row Types 
case class Knol(name: String, email: String, dob: java.sql.Date, id: Int = 0) 
class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { 
def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) 
def name: Column[String] = column[String]("name", O.NotNull) 
def email: Column[String] = column[String]("email", O.NotNull) 
def dob: Column[java.sql.Date] = column[java.sql.Date]("dob", O.NotNull) 
def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) 
}
Custom Column Types 
case class Knol(name: String, email: String, dob: java.util.Date, id: Int = 0) 
implicit val util2sqlDateMapper = MappedColumnType.base[java.util.Date, 
java.sql.Date]( 
{ utilDate => new java.sql.Date(utilDate.getTime()) }, 
{ sqlDate => new java.util.Date(sqlDate.getTime()) }) 
class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { 
def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) 
def name: Column[String] = column[String]("name", O.NotNull) 
def email: Column[String] = column[String]("email", O.NotNull) 
def dob: Column[java.util.Date] = column[java.util.Date]("dob", O.NotNull) 
def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) 
} 
val knolTable = TableQuery[KnolTable]
Foreign Keys 
case class KnolX(topic: String, date: Date, knolId: Int, id: Int = 0) 
class KnolXTable(tag: Tag) extends Table[KnolX](tag, "knolx") { 
def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) 
def topic: Column[String] = column[String]("topic", O.NotNull) 
def date: Column[Date] = column[Date]("date", O.NotNull) 
def knolId: Column[Int] = column[Int]("knol_id", O.NotNull) 
def * = (topic, date, knolId, id) <> (KnolX.tupled, KnolX.unapply) 
def fKey = foreignKey("knol_x_fk", knolId, knolTable)(_.id) 
} 
val knolSession = TableQuery[KnolXTable]
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
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))
Types in Slick 
class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { 
def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) 
def name: Column[String] = column[String]("name", O.NotNull) 
def email: Column[String] = column[String]("email", O.NotNull) 
def dob: Column[java.util.Date] = column[java.util.Date]("dob", O.NotNull) 
def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) 
} 
val knolTable = TableQuery[KnolTable] 
val query: Query[Column[String], String, Seq] = 
knolTable.map((knol: KnolTable) => knol.name: Column[String]) 
val knolList: Seq[String] = query.run(session)
Types in Slick 
class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { 
def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) 
def name: Column[String] = column[String]("name", O.NotNull) 
def email: Column[String] = column[String]("email", O.NotNull) 
def dob: Column[java.util.Date] = column[java.util.Date]("dob", O.NotNull) 
def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) 
} 
val knolTable = TableQuery[KnolTable] 
val query: Query[Column[String], String, Seq] = 
knolTable.map((knol: KnolTable) => knol.name: Column[String]) 
val knolList: Seq[String] = query.run(session)
Types in Slick 
class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { 
def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) 
def name: Column[String] = column[String]("name", O.NotNull) 
def email: Column[String] = column[String]("email", O.NotNull) 
def dob: Column[java.util.Date] = column[java.util.Date]("dob", O.NotNull) 
def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) 
} 
val knolTable = TableQuery[KnolTable] 
val query: Query[Column[String], String, Seq] = 
knolTable.map((knol: KnolTable) => knol.name: Column[String]) 
val knolList: Seq[String] = query.run(session)
Types in Slick 
class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { 
def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) 
def name: Column[String] = column[String]("name", O.NotNull) 
def email: Column[String] = column[String]("email", O.NotNull) 
def dob: Column[java.util.Date] = column[java.util.Date]("dob", O.NotNull) 
def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) 
} 
val knolTable = TableQuery[KnolTable] 
val query: Query[Column[String], String, Seq] = 
knolTable.map((knol: KnolTable) => knol.name: Column[String]) 
val knolList: Seq[String] = query.run(session)
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
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
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
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)
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.?))
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)
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.?))
Query Extension 
implicit class QueryExtension1[T1, E1](val q: Query[T1, E1, Seq]) { 
def page(no: Int, pageSize: Int = 2): Query[T1, E1, Seq] = 
q.drop((no - 1) * pageSize).take(pageSize) 
} 
knolTable.page(2).list
Query Extensions for Table 
implicit class QueryExtension2[T1, E1](val q: Query[KnolTable, Knol, Seq]) { 
def sortByName: Query[Column[String], String, Seq] = 
q.map(_.name).sortBy(_.asc) 
} 
knolTable.sortByName.run(session)
Query Extensions for Join 
implicit class QueryExtension3[T1, E1](val q: Query[T1, E1, Seq]) { 
def joinInner[T2, E2](s: Query[T2, E2, Seq])( 
condition: (T1, T2) => Column[Boolean]): Query[(T1, T2), (E1, E2), Seq] = 
q.innerJoin(s).on(condition) 
} 
val condition = (k: KnolTable, x: KnolXTable) => k.id === x.knolId 
knolTable.joinInner(knolXTable)(condition).list
Auto Joins 
implicit class QueryExtension4[T1, E1](val q: Query[T1, E1, Seq]) { 
def autoJoin[T2, E2](s: Query[T2, E2, Seq])( 
condition: (T1, T2) => Column[Boolean]): Query[(T1, T2), (E1, E2), Seq] = 
q.join(s).on(condition) 
} 
val condition = (k: KnolTable, x: KnolXTable) => k.id === x.knolId 
knolTable.autoJoin(knolXTable)(condition).list
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.
Nested Mapped entity 
case class Address(locationId: Int, location: String) 
case class Knol(name: String, email: String, address: Address, id: Int = 0) 
class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { 
def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) 
def name: Column[String] = column[String]("name", O.NotNull) 
def email: Column[String] = column[String]("email", O.NotNull) 
def locationId: Column[Int] = column[Int]("location_id") 
def location: Column[Int] = column[String]("location") 
def address = (locationId, location) <> (Address.tupled, Address.unapply) 
def * = (name, email, address, id) <> (Knol.tupled, Knol.unapply) 
}
import scala.slick.driver.H2Driver.simple._ 
trait KnolRepositoryComponent{ 
class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { 
def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) 
def name: Column[String] = column[String]("name", O.NotNull) 
def email: Column[String] = column[String]("email", O.NotNull) 
def dob: Column[java.util.Date] = column[java.util.Date]("dob", O.NotNull) 
def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) 
} 
val knolTable = TableQuery[KnolTable] 
def insert(knol: Knol) = { 
DB.getConnection.withSession { implicit session: Session => 
knolTable.insert(knol) } 
} 
} 
object DB{ 
def getConnection(): Database= 
Database.forURL("jdbc:h2:mem:test", driver = "org.h2.Driver") 
} 
What is wrong with design ?
import scala.slick.driver.H2Driver.simple._ 
trait KnolRepositoryComponent { 
class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { 
def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) 
def name: Column[String] = column[String]("name", O.NotNull) 
def email: Column[String] = column[String]("email", O.NotNull) 
def dob: Column[java.util.Date] = column[java.util.Date]("dob", O.NotNull) 
def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) 
} 
val knolTable = TableQuery[KnolTable] 
def insert(knol: Knol) = { 
DB.getConnection.withSession { implicit session: Session => knolTable.insert(knol) } 
} 
} 
object DB { 
def getConnection(): Database = 
Database.forURL("jdbc:h2:mem:test", driver = "org.h2.Driver") 
} 
This is database specific code
Slick Database Driver Hierarchy
Driver Level Abstraction 
import scala.slick.driver.JdbcProfile 
trait DBComponent { 
val driver: JdbcProfile 
import driver.simple._ 
def dbObject(): Database 
}
Driver Level Abstraction 
trait KnolRepositoryComponent { this: DBComponent => 
import driver.simple._ 
class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { 
def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) 
def name: Column[String] = column[String]("name", O.NotNull) 
def email: Column[String] = column[String]("email", O.NotNull) 
def dob: Column[Date] = column[java.util.Date]("dob", O.NotNull) 
def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) 
} 
val knolTable = TableQuery[KnolTable] 
def insert(knol: Knol): Int = 
dbObject.withSession { implicit session: Session => 
knolTable.returning(knolTable.map(_.id)).insert(knol) 
} 
def update(knol: Knol): Int = 
dbObject.withSession { implicit session: Session => knolTable.filter { _.id === 
knol.id }.update(knol) } 
def delete(id: Int): Int = 
dbObject.withSession { implicit session: Session => knolTable.filter { _.id === id }.delete } 
}
Driver Specific Implementation 
import scala.slick.driver.PostgresDriver 
import com.typesafe.config.ConfigFactory 
trait PostgresDBComponent extends DBComponent { 
val driver = PostgresDriver 
import driver.simple._ 
private val config = ConfigFactory.load() 
private val dbDriver = config.getString("db.driver") 
private val url = config.getString("db.url") 
private val host = config.getString("db.host") 
private val port = config.getInt("db.port") 
private val database = config.getString("db.database") 
private val userName = config.getString("db.username") 
private val password = config.getString("db.password") 
private val combindURL = url + host + ":" + port + "/" + database 
def dbObject(): Database = 
Database.forURL(combindURL, userName, password, null, dbDriver) 
}
For Production Usage 
trait KnolRepositoryComponent { this: DBComponent => 
import driver.simple._ 
class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { 
def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) 
def name: Column[String] = column[String]("name", O.NotNull) 
def email: Column[String] = column[String]("email", O.NotNull) 
def dob: Column[Date] = column[java.util.Date]("dob", O.NotNull) 
def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) 
} 
val knolTable = TableQuery[KnolTable] 
def insert(knol: Knol) = { 
dbObject.withSession { implicit session: Session => knolTable.insert(knol) } 
} 
} 
object KnolRepository extends KnolRepositoryComponent with PostgresDBComponent
Test Specific implementation 
import scala.slick.driver.H2Driver 
import com.typesafe.config.ConfigFactory 
import org.slf4j.LoggerFactory 
trait TestDBComponent extends DBComponent { 
val logger = LoggerFactory.getLogger(this.getClass()) 
val driver = H2Driver 
import driver.simple._ 
private val config = ConfigFactory.load() 
private val dbDriver = config.getString("db.driver") 
private val url = config.getString("db.url") 
def dbObject(): Database = { 
logger.debug(s"URL :[$url] driver: [$driver]") 
Database.forURL(url, driver = dbDriver) 
} 
}
Unit Test Using H2 database 
class KnolRepositoryTest extends FunSuite with KnolRepositoryComponent with TestDBComponent 
{ 
test("Get all knol info") { 
assert(getKnolList.length === 4) 
} 
test("Add new Knol info") { 
val knol = Knol("test", "test@knoldus.com", new Date("01/07/1986")) 
assert(insert(knol) === 5) 
} 
test("Update knol info") { 
val updatedKnol = Knol("Anand singh", "anand@knoldus.com", new Date("01/07/1986"), 1) 
assert(update(updatedKnol) === 1) 
} 
test("Delete Knol info") { 
assert(delete(1) === 1) 
} 
}
References 
1. Slick documentation 
http://slick.typesafe.com/doc/2.1.0/ 
2.Patterns for Slick database applications 
https://skillsmatter.com/skillscasts/4577-patterns-for-slick-database-applications
QQ && OOppttiioonn[[AA]]
TThhaannkkss

More Related Content

What's hot

The Ring programming language version 1.5 book - Part 8 of 31
The Ring programming language version 1.5 book - Part 8 of 31The Ring programming language version 1.5 book - Part 8 of 31
The Ring programming language version 1.5 book - Part 8 of 31Mahmoud Samir Fayed
 
From java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFrom java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFabio Collini
 
The Ring programming language version 1.5.2 book - Part 32 of 181
The Ring programming language version 1.5.2 book - Part 32 of 181The Ring programming language version 1.5.2 book - Part 32 of 181
The Ring programming language version 1.5.2 book - Part 32 of 181Mahmoud Samir Fayed
 
[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)croquiscom
 
The Ring programming language version 1.5.2 book - Part 35 of 181
The Ring programming language version 1.5.2 book - Part 35 of 181The Ring programming language version 1.5.2 book - Part 35 of 181
The Ring programming language version 1.5.2 book - Part 35 of 181Mahmoud Samir Fayed
 
The Ring programming language version 1.5.1 book - Part 34 of 180
The Ring programming language version 1.5.1 book - Part 34 of 180The Ring programming language version 1.5.1 book - Part 34 of 180
The Ring programming language version 1.5.1 book - Part 34 of 180Mahmoud Samir Fayed
 
The Ring programming language version 1.2 book - Part 23 of 84
The Ring programming language version 1.2 book - Part 23 of 84The Ring programming language version 1.2 book - Part 23 of 84
The Ring programming language version 1.2 book - Part 23 of 84Mahmoud Samir Fayed
 
java experiments and programs
java experiments and programsjava experiments and programs
java experiments and programsKaruppaiyaa123
 
JDD 2016 - Pawel Byszewski - Kotlin, why?
JDD 2016 - Pawel Byszewski - Kotlin, why?JDD 2016 - Pawel Byszewski - Kotlin, why?
JDD 2016 - Pawel Byszewski - Kotlin, why?PROIDEA
 
The Ring programming language version 1.2 book - Part 22 of 84
The Ring programming language version 1.2 book - Part 22 of 84The Ring programming language version 1.2 book - Part 22 of 84
The Ring programming language version 1.2 book - Part 22 of 84Mahmoud Samir Fayed
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Jonas Bonér
 
The Ring programming language version 1.10 book - Part 43 of 212
The Ring programming language version 1.10 book - Part 43 of 212The Ring programming language version 1.10 book - Part 43 of 212
The Ring programming language version 1.10 book - Part 43 of 212Mahmoud Samir Fayed
 
The Ring programming language version 1.7 book - Part 34 of 196
The Ring programming language version 1.7 book - Part 34 of 196The Ring programming language version 1.7 book - Part 34 of 196
The Ring programming language version 1.7 book - Part 34 of 196Mahmoud Samir Fayed
 
Herding types with Scala macros
Herding types with Scala macrosHerding types with Scala macros
Herding types with Scala macrosMarina Sigaeva
 
The Ring programming language version 1.8 book - Part 43 of 202
The Ring programming language version 1.8 book - Part 43 of 202The Ring programming language version 1.8 book - Part 43 of 202
The Ring programming language version 1.8 book - Part 43 of 202Mahmoud Samir Fayed
 

What's hot (19)

The Ring programming language version 1.5 book - Part 8 of 31
The Ring programming language version 1.5 book - Part 8 of 31The Ring programming language version 1.5 book - Part 8 of 31
The Ring programming language version 1.5 book - Part 8 of 31
 
From java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+kFrom java to kotlin beyond alt+shift+cmd+k
From java to kotlin beyond alt+shift+cmd+k
 
The Ring programming language version 1.5.2 book - Part 32 of 181
The Ring programming language version 1.5.2 book - Part 32 of 181The Ring programming language version 1.5.2 book - Part 32 of 181
The Ring programming language version 1.5.2 book - Part 32 of 181
 
[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)[2019-07] GraphQL in depth (serverside)
[2019-07] GraphQL in depth (serverside)
 
The Ring programming language version 1.5.2 book - Part 35 of 181
The Ring programming language version 1.5.2 book - Part 35 of 181The Ring programming language version 1.5.2 book - Part 35 of 181
The Ring programming language version 1.5.2 book - Part 35 of 181
 
Benefits of Kotlin
Benefits of KotlinBenefits of Kotlin
Benefits of Kotlin
 
The Ring programming language version 1.5.1 book - Part 34 of 180
The Ring programming language version 1.5.1 book - Part 34 of 180The Ring programming language version 1.5.1 book - Part 34 of 180
The Ring programming language version 1.5.1 book - Part 34 of 180
 
The Ring programming language version 1.2 book - Part 23 of 84
The Ring programming language version 1.2 book - Part 23 of 84The Ring programming language version 1.2 book - Part 23 of 84
The Ring programming language version 1.2 book - Part 23 of 84
 
java experiments and programs
java experiments and programsjava experiments and programs
java experiments and programs
 
JDD 2016 - Pawel Byszewski - Kotlin, why?
JDD 2016 - Pawel Byszewski - Kotlin, why?JDD 2016 - Pawel Byszewski - Kotlin, why?
JDD 2016 - Pawel Byszewski - Kotlin, why?
 
The Ring programming language version 1.2 book - Part 22 of 84
The Ring programming language version 1.2 book - Part 22 of 84The Ring programming language version 1.2 book - Part 22 of 84
The Ring programming language version 1.2 book - Part 22 of 84
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
Python speleology
Python speleologyPython speleology
Python speleology
 
mobl
moblmobl
mobl
 
The Ring programming language version 1.10 book - Part 43 of 212
The Ring programming language version 1.10 book - Part 43 of 212The Ring programming language version 1.10 book - Part 43 of 212
The Ring programming language version 1.10 book - Part 43 of 212
 
Pytables
PytablesPytables
Pytables
 
The Ring programming language version 1.7 book - Part 34 of 196
The Ring programming language version 1.7 book - Part 34 of 196The Ring programming language version 1.7 book - Part 34 of 196
The Ring programming language version 1.7 book - Part 34 of 196
 
Herding types with Scala macros
Herding types with Scala macrosHerding types with Scala macros
Herding types with Scala macros
 
The Ring programming language version 1.8 book - Part 43 of 202
The Ring programming language version 1.8 book - Part 43 of 202The Ring programming language version 1.8 book - Part 43 of 202
The Ring programming language version 1.8 book - Part 43 of 202
 

Similar to WorkingWithSlick2.1.0

Kotlin for Android Developers
Kotlin for Android DevelopersKotlin for Android Developers
Kotlin for Android DevelopersHassan Abid
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systemsleague
 
Postgresql 9.3 overview
Postgresql 9.3 overviewPostgresql 9.3 overview
Postgresql 9.3 overviewAveic
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?Tomasz Wrobel
 
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...PROIDEA
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patternsleague
 
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
JDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation streamJDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation stream
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation streamRuslan Shevchenko
 
Privet Kotlin (Windy City DevFest)
Privet Kotlin (Windy City DevFest)Privet Kotlin (Windy City DevFest)
Privet Kotlin (Windy City DevFest)Cody Engel
 
Model-Driven Software Development - Pretty-Printing, Editor Services, Term Re...
Model-Driven Software Development - Pretty-Printing, Editor Services, Term Re...Model-Driven Software Development - Pretty-Printing, Editor Services, Term Re...
Model-Driven Software Development - Pretty-Printing, Editor Services, Term Re...Eelco Visser
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7decoupled
 
Swift 함수 커링 사용하기
Swift 함수 커링 사용하기Swift 함수 커링 사용하기
Swift 함수 커링 사용하기진성 오
 
The Ring programming language version 1.5.3 book - Part 44 of 184
The Ring programming language version 1.5.3 book - Part 44 of 184The Ring programming language version 1.5.3 book - Part 44 of 184
The Ring programming language version 1.5.3 book - Part 44 of 184Mahmoud Samir Fayed
 
The Ring programming language version 1.5.3 book - Part 54 of 184
The Ring programming language version 1.5.3 book - Part 54 of 184The Ring programming language version 1.5.3 book - Part 54 of 184
The Ring programming language version 1.5.3 book - Part 54 of 184Mahmoud Samir Fayed
 
The Ring programming language version 1.5.4 book - Part 34 of 185
The Ring programming language version 1.5.4 book - Part 34 of 185The Ring programming language version 1.5.4 book - Part 34 of 185
The Ring programming language version 1.5.4 book - Part 34 of 185Mahmoud Samir Fayed
 
Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti...
Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti...Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti...
Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti...scalaconfjp
 
The Ring programming language version 1.5.4 book - Part 40 of 185
The Ring programming language version 1.5.4 book - Part 40 of 185The Ring programming language version 1.5.4 book - Part 40 of 185
The Ring programming language version 1.5.4 book - Part 40 of 185Mahmoud Samir Fayed
 

Similar to WorkingWithSlick2.1.0 (20)

Kotlin for Android Developers
Kotlin for Android DevelopersKotlin for Android Developers
Kotlin for Android Developers
 
Modular Module Systems
Modular Module SystemsModular Module Systems
Modular Module Systems
 
Postgresql 9.3 overview
Postgresql 9.3 overviewPostgresql 9.3 overview
Postgresql 9.3 overview
 
(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?(How) can we benefit from adopting scala?
(How) can we benefit from adopting scala?
 
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
JDD2015: Functional programing and Event Sourcing - a pair made in heaven - e...
 
Scala Functional Patterns
Scala Functional PatternsScala Functional Patterns
Scala Functional Patterns
 
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
JDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation streamJDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation stream
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
 
Scala best practices
Scala best practicesScala best practices
Scala best practices
 
Privet Kotlin (Windy City DevFest)
Privet Kotlin (Windy City DevFest)Privet Kotlin (Windy City DevFest)
Privet Kotlin (Windy City DevFest)
 
2014-11-01 01 Денис Нелюбин. О сортах кофе
2014-11-01 01 Денис Нелюбин. О сортах кофе2014-11-01 01 Денис Нелюбин. О сортах кофе
2014-11-01 01 Денис Нелюбин. О сортах кофе
 
Model-Driven Software Development - Pretty-Printing, Editor Services, Term Re...
Model-Driven Software Development - Pretty-Printing, Editor Services, Term Re...Model-Driven Software Development - Pretty-Printing, Editor Services, Term Re...
Model-Driven Software Development - Pretty-Printing, Editor Services, Term Re...
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7
 
A tour of Python
A tour of PythonA tour of Python
A tour of Python
 
Swift 함수 커링 사용하기
Swift 함수 커링 사용하기Swift 함수 커링 사용하기
Swift 함수 커링 사용하기
 
The Ring programming language version 1.5.3 book - Part 44 of 184
The Ring programming language version 1.5.3 book - Part 44 of 184The Ring programming language version 1.5.3 book - Part 44 of 184
The Ring programming language version 1.5.3 book - Part 44 of 184
 
The Ring programming language version 1.5.3 book - Part 54 of 184
The Ring programming language version 1.5.3 book - Part 54 of 184The Ring programming language version 1.5.3 book - Part 54 of 184
The Ring programming language version 1.5.3 book - Part 54 of 184
 
Kotlin, why?
Kotlin, why?Kotlin, why?
Kotlin, why?
 
The Ring programming language version 1.5.4 book - Part 34 of 185
The Ring programming language version 1.5.4 book - Part 34 of 185The Ring programming language version 1.5.4 book - Part 34 of 185
The Ring programming language version 1.5.4 book - Part 34 of 185
 
Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti...
Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti...Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti...
Functional Object-Oriented Imperative Scala / 関数型オブジェクト指向命令型 Scala by Sébasti...
 
The Ring programming language version 1.5.4 book - Part 40 of 185
The Ring programming language version 1.5.4 book - Part 40 of 185The Ring programming language version 1.5.4 book - Part 40 of 185
The Ring programming language version 1.5.4 book - Part 40 of 185
 

More from Knoldus Inc.

GraphQL with .NET Core Microservices.pdf
GraphQL with .NET Core Microservices.pdfGraphQL with .NET Core Microservices.pdf
GraphQL with .NET Core Microservices.pdfKnoldus Inc.
 
NuGet Packages Presentation (DoT NeT).pptx
NuGet Packages Presentation (DoT NeT).pptxNuGet Packages Presentation (DoT NeT).pptx
NuGet Packages Presentation (DoT NeT).pptxKnoldus Inc.
 
Data Quality in Test Automation Navigating the Path to Reliable Testing
Data Quality in Test Automation Navigating the Path to Reliable TestingData Quality in Test Automation Navigating the Path to Reliable Testing
Data Quality in Test Automation Navigating the Path to Reliable TestingKnoldus Inc.
 
K8sGPTThe AI​ way to diagnose Kubernetes
K8sGPTThe AI​ way to diagnose KubernetesK8sGPTThe AI​ way to diagnose Kubernetes
K8sGPTThe AI​ way to diagnose KubernetesKnoldus Inc.
 
Introduction to Circle Ci Presentation.pptx
Introduction to Circle Ci Presentation.pptxIntroduction to Circle Ci Presentation.pptx
Introduction to Circle Ci Presentation.pptxKnoldus Inc.
 
Robusta -Tool Presentation (DevOps).pptx
Robusta -Tool Presentation (DevOps).pptxRobusta -Tool Presentation (DevOps).pptx
Robusta -Tool Presentation (DevOps).pptxKnoldus Inc.
 
Optimizing Kubernetes using GOLDILOCKS.pptx
Optimizing Kubernetes using GOLDILOCKS.pptxOptimizing Kubernetes using GOLDILOCKS.pptx
Optimizing Kubernetes using GOLDILOCKS.pptxKnoldus Inc.
 
Azure Function App Exception Handling.pptx
Azure Function App Exception Handling.pptxAzure Function App Exception Handling.pptx
Azure Function App Exception Handling.pptxKnoldus Inc.
 
CQRS Design Pattern Presentation (Java).pptx
CQRS Design Pattern Presentation (Java).pptxCQRS Design Pattern Presentation (Java).pptx
CQRS Design Pattern Presentation (Java).pptxKnoldus Inc.
 
ETL Observability: Azure to Snowflake Presentation
ETL Observability: Azure to Snowflake PresentationETL Observability: Azure to Snowflake Presentation
ETL Observability: Azure to Snowflake PresentationKnoldus Inc.
 
Scripting with K6 - Beyond the Basics Presentation
Scripting with K6 - Beyond the Basics PresentationScripting with K6 - Beyond the Basics Presentation
Scripting with K6 - Beyond the Basics PresentationKnoldus Inc.
 
Getting started with dotnet core Web APIs
Getting started with dotnet core Web APIsGetting started with dotnet core Web APIs
Getting started with dotnet core Web APIsKnoldus Inc.
 
Introduction To Rust part II Presentation
Introduction To Rust part II PresentationIntroduction To Rust part II Presentation
Introduction To Rust part II PresentationKnoldus Inc.
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Configuring Workflows & Validators in JIRA
Configuring Workflows & Validators in JIRAConfiguring Workflows & Validators in JIRA
Configuring Workflows & Validators in JIRAKnoldus Inc.
 
Advanced Python (with dependency injection and hydra configuration packages)
Advanced Python (with dependency injection and hydra configuration packages)Advanced Python (with dependency injection and hydra configuration packages)
Advanced Python (with dependency injection and hydra configuration packages)Knoldus Inc.
 
Azure Databricks (For Data Analytics).pptx
Azure Databricks (For Data Analytics).pptxAzure Databricks (For Data Analytics).pptx
Azure Databricks (For Data Analytics).pptxKnoldus Inc.
 
The Power of Dependency Injection with Dagger 2 and Kotlin
The Power of Dependency Injection with Dagger 2 and KotlinThe Power of Dependency Injection with Dagger 2 and Kotlin
The Power of Dependency Injection with Dagger 2 and KotlinKnoldus Inc.
 
Data Engineering with Databricks Presentation
Data Engineering with Databricks PresentationData Engineering with Databricks Presentation
Data Engineering with Databricks PresentationKnoldus Inc.
 
Databricks for MLOps Presentation (AI/ML)
Databricks for MLOps Presentation (AI/ML)Databricks for MLOps Presentation (AI/ML)
Databricks for MLOps Presentation (AI/ML)Knoldus Inc.
 

More from Knoldus Inc. (20)

GraphQL with .NET Core Microservices.pdf
GraphQL with .NET Core Microservices.pdfGraphQL with .NET Core Microservices.pdf
GraphQL with .NET Core Microservices.pdf
 
NuGet Packages Presentation (DoT NeT).pptx
NuGet Packages Presentation (DoT NeT).pptxNuGet Packages Presentation (DoT NeT).pptx
NuGet Packages Presentation (DoT NeT).pptx
 
Data Quality in Test Automation Navigating the Path to Reliable Testing
Data Quality in Test Automation Navigating the Path to Reliable TestingData Quality in Test Automation Navigating the Path to Reliable Testing
Data Quality in Test Automation Navigating the Path to Reliable Testing
 
K8sGPTThe AI​ way to diagnose Kubernetes
K8sGPTThe AI​ way to diagnose KubernetesK8sGPTThe AI​ way to diagnose Kubernetes
K8sGPTThe AI​ way to diagnose Kubernetes
 
Introduction to Circle Ci Presentation.pptx
Introduction to Circle Ci Presentation.pptxIntroduction to Circle Ci Presentation.pptx
Introduction to Circle Ci Presentation.pptx
 
Robusta -Tool Presentation (DevOps).pptx
Robusta -Tool Presentation (DevOps).pptxRobusta -Tool Presentation (DevOps).pptx
Robusta -Tool Presentation (DevOps).pptx
 
Optimizing Kubernetes using GOLDILOCKS.pptx
Optimizing Kubernetes using GOLDILOCKS.pptxOptimizing Kubernetes using GOLDILOCKS.pptx
Optimizing Kubernetes using GOLDILOCKS.pptx
 
Azure Function App Exception Handling.pptx
Azure Function App Exception Handling.pptxAzure Function App Exception Handling.pptx
Azure Function App Exception Handling.pptx
 
CQRS Design Pattern Presentation (Java).pptx
CQRS Design Pattern Presentation (Java).pptxCQRS Design Pattern Presentation (Java).pptx
CQRS Design Pattern Presentation (Java).pptx
 
ETL Observability: Azure to Snowflake Presentation
ETL Observability: Azure to Snowflake PresentationETL Observability: Azure to Snowflake Presentation
ETL Observability: Azure to Snowflake Presentation
 
Scripting with K6 - Beyond the Basics Presentation
Scripting with K6 - Beyond the Basics PresentationScripting with K6 - Beyond the Basics Presentation
Scripting with K6 - Beyond the Basics Presentation
 
Getting started with dotnet core Web APIs
Getting started with dotnet core Web APIsGetting started with dotnet core Web APIs
Getting started with dotnet core Web APIs
 
Introduction To Rust part II Presentation
Introduction To Rust part II PresentationIntroduction To Rust part II Presentation
Introduction To Rust part II Presentation
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Configuring Workflows & Validators in JIRA
Configuring Workflows & Validators in JIRAConfiguring Workflows & Validators in JIRA
Configuring Workflows & Validators in JIRA
 
Advanced Python (with dependency injection and hydra configuration packages)
Advanced Python (with dependency injection and hydra configuration packages)Advanced Python (with dependency injection and hydra configuration packages)
Advanced Python (with dependency injection and hydra configuration packages)
 
Azure Databricks (For Data Analytics).pptx
Azure Databricks (For Data Analytics).pptxAzure Databricks (For Data Analytics).pptx
Azure Databricks (For Data Analytics).pptx
 
The Power of Dependency Injection with Dagger 2 and Kotlin
The Power of Dependency Injection with Dagger 2 and KotlinThe Power of Dependency Injection with Dagger 2 and Kotlin
The Power of Dependency Injection with Dagger 2 and Kotlin
 
Data Engineering with Databricks Presentation
Data Engineering with Databricks PresentationData Engineering with Databricks Presentation
Data Engineering with Databricks Presentation
 
Databricks for MLOps Presentation (AI/ML)
Databricks for MLOps Presentation (AI/ML)Databricks for MLOps Presentation (AI/ML)
Databricks for MLOps Presentation (AI/ML)
 

Recently uploaded

chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyFrank van der Linden
 
XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsMehedi Hasan Shohan
 
What are the features of Vehicle Tracking System?
What are the features of Vehicle Tracking System?What are the features of Vehicle Tracking System?
What are the features of Vehicle Tracking System?Watsoo Telematics
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
buds n tech IT solutions
buds n  tech IT                solutionsbuds n  tech IT                solutions
buds n tech IT solutionsmonugehlot87
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...aditisharan08
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
cybersecurity notes for mca students for learning
cybersecurity notes for mca students for learningcybersecurity notes for mca students for learning
cybersecurity notes for mca students for learningVitsRangannavar
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝soniya singh
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfPower Karaoke
 

Recently uploaded (20)

chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The Ugly
 
XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software Solutions
 
What are the features of Vehicle Tracking System?
What are the features of Vehicle Tracking System?What are the features of Vehicle Tracking System?
What are the features of Vehicle Tracking System?
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
buds n tech IT solutions
buds n  tech IT                solutionsbuds n  tech IT                solutions
buds n tech IT solutions
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
cybersecurity notes for mca students for learning
cybersecurity notes for mca students for learningcybersecurity notes for mca students for learning
cybersecurity notes for mca students for learning
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
Call Girls in Naraina Delhi 💯Call Us 🔝8264348440🔝
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdf
 

WorkingWithSlick2.1.0

  • 1. SSlliicckk 22..11..00 Satendra Kumar Software Consultant Knoldus Software LLP
  • 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)
  • 4. Table Definition class KnolTable(tag: Tag) extends Table[(String, String, Date, Int)](tag, "knol") { def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) def name: Column[String] = column[String]("name", O.NotNull) def email: Column[String] = column[String]("email", O.NotNull) def dob: Column[Date] = column[Date]("dob", O.NotNull) def * = (name, email, dob, id) } val knolTable = TableQuery[KnolTable]
  • 5. Custom Row Types case class Knol(name: String, email: String, dob: java.sql.Date, id: Int = 0) class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) def name: Column[String] = column[String]("name", O.NotNull) def email: Column[String] = column[String]("email", O.NotNull) def dob: Column[java.sql.Date] = column[java.sql.Date]("dob", O.NotNull) def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) }
  • 6. Custom Column Types case class Knol(name: String, email: String, dob: java.util.Date, id: Int = 0) implicit val util2sqlDateMapper = MappedColumnType.base[java.util.Date, java.sql.Date]( { utilDate => new java.sql.Date(utilDate.getTime()) }, { sqlDate => new java.util.Date(sqlDate.getTime()) }) class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) def name: Column[String] = column[String]("name", O.NotNull) def email: Column[String] = column[String]("email", O.NotNull) def dob: Column[java.util.Date] = column[java.util.Date]("dob", O.NotNull) def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) } val knolTable = TableQuery[KnolTable]
  • 7. Foreign Keys case class KnolX(topic: String, date: Date, knolId: Int, id: Int = 0) class KnolXTable(tag: Tag) extends Table[KnolX](tag, "knolx") { def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) def topic: Column[String] = column[String]("topic", O.NotNull) def date: Column[Date] = column[Date]("date", O.NotNull) def knolId: Column[Int] = column[Int]("knol_id", O.NotNull) def * = (topic, date, knolId, id) <> (KnolX.tupled, KnolX.unapply) def fKey = foreignKey("knol_x_fk", knolId, knolTable)(_.id) } val knolSession = TableQuery[KnolXTable]
  • 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))
  • 10. Types in Slick class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) def name: Column[String] = column[String]("name", O.NotNull) def email: Column[String] = column[String]("email", O.NotNull) def dob: Column[java.util.Date] = column[java.util.Date]("dob", O.NotNull) def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) } val knolTable = TableQuery[KnolTable] val query: Query[Column[String], String, Seq] = knolTable.map((knol: KnolTable) => knol.name: Column[String]) val knolList: Seq[String] = query.run(session)
  • 11. Types in Slick class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) def name: Column[String] = column[String]("name", O.NotNull) def email: Column[String] = column[String]("email", O.NotNull) def dob: Column[java.util.Date] = column[java.util.Date]("dob", O.NotNull) def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) } val knolTable = TableQuery[KnolTable] val query: Query[Column[String], String, Seq] = knolTable.map((knol: KnolTable) => knol.name: Column[String]) val knolList: Seq[String] = query.run(session)
  • 12. Types in Slick class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) def name: Column[String] = column[String]("name", O.NotNull) def email: Column[String] = column[String]("email", O.NotNull) def dob: Column[java.util.Date] = column[java.util.Date]("dob", O.NotNull) def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) } val knolTable = TableQuery[KnolTable] val query: Query[Column[String], String, Seq] = knolTable.map((knol: KnolTable) => knol.name: Column[String]) val knolList: Seq[String] = query.run(session)
  • 13. Types in Slick class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) def name: Column[String] = column[String]("name", O.NotNull) def email: Column[String] = column[String]("email", O.NotNull) def dob: Column[java.util.Date] = column[java.util.Date]("dob", O.NotNull) def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) } val knolTable = TableQuery[KnolTable] val query: Query[Column[String], String, Seq] = knolTable.map((knol: KnolTable) => knol.name: Column[String]) val knolList: Seq[String] = query.run(session)
  • 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.?))
  • 21. Query Extension implicit class QueryExtension1[T1, E1](val q: Query[T1, E1, Seq]) { def page(no: Int, pageSize: Int = 2): Query[T1, E1, Seq] = q.drop((no - 1) * pageSize).take(pageSize) } knolTable.page(2).list
  • 22. Query Extensions for Table implicit class QueryExtension2[T1, E1](val q: Query[KnolTable, Knol, Seq]) { def sortByName: Query[Column[String], String, Seq] = q.map(_.name).sortBy(_.asc) } knolTable.sortByName.run(session)
  • 23. Query Extensions for Join implicit class QueryExtension3[T1, E1](val q: Query[T1, E1, Seq]) { def joinInner[T2, E2](s: Query[T2, E2, Seq])( condition: (T1, T2) => Column[Boolean]): Query[(T1, T2), (E1, E2), Seq] = q.innerJoin(s).on(condition) } val condition = (k: KnolTable, x: KnolXTable) => k.id === x.knolId knolTable.joinInner(knolXTable)(condition).list
  • 24. Auto Joins implicit class QueryExtension4[T1, E1](val q: Query[T1, E1, Seq]) { def autoJoin[T2, E2](s: Query[T2, E2, Seq])( condition: (T1, T2) => Column[Boolean]): Query[(T1, T2), (E1, E2), Seq] = q.join(s).on(condition) } val condition = (k: KnolTable, x: KnolXTable) => k.id === x.knolId knolTable.autoJoin(knolXTable)(condition).list
  • 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.
  • 26. Nested Mapped entity case class Address(locationId: Int, location: String) case class Knol(name: String, email: String, address: Address, id: Int = 0) class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) def name: Column[String] = column[String]("name", O.NotNull) def email: Column[String] = column[String]("email", O.NotNull) def locationId: Column[Int] = column[Int]("location_id") def location: Column[Int] = column[String]("location") def address = (locationId, location) <> (Address.tupled, Address.unapply) def * = (name, email, address, id) <> (Knol.tupled, Knol.unapply) }
  • 27. import scala.slick.driver.H2Driver.simple._ trait KnolRepositoryComponent{ class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) def name: Column[String] = column[String]("name", O.NotNull) def email: Column[String] = column[String]("email", O.NotNull) def dob: Column[java.util.Date] = column[java.util.Date]("dob", O.NotNull) def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) } val knolTable = TableQuery[KnolTable] def insert(knol: Knol) = { DB.getConnection.withSession { implicit session: Session => knolTable.insert(knol) } } } object DB{ def getConnection(): Database= Database.forURL("jdbc:h2:mem:test", driver = "org.h2.Driver") } What is wrong with design ?
  • 28. import scala.slick.driver.H2Driver.simple._ trait KnolRepositoryComponent { class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) def name: Column[String] = column[String]("name", O.NotNull) def email: Column[String] = column[String]("email", O.NotNull) def dob: Column[java.util.Date] = column[java.util.Date]("dob", O.NotNull) def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) } val knolTable = TableQuery[KnolTable] def insert(knol: Knol) = { DB.getConnection.withSession { implicit session: Session => knolTable.insert(knol) } } } object DB { def getConnection(): Database = Database.forURL("jdbc:h2:mem:test", driver = "org.h2.Driver") } This is database specific code
  • 30. Driver Level Abstraction import scala.slick.driver.JdbcProfile trait DBComponent { val driver: JdbcProfile import driver.simple._ def dbObject(): Database }
  • 31. Driver Level Abstraction trait KnolRepositoryComponent { this: DBComponent => import driver.simple._ class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) def name: Column[String] = column[String]("name", O.NotNull) def email: Column[String] = column[String]("email", O.NotNull) def dob: Column[Date] = column[java.util.Date]("dob", O.NotNull) def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) } val knolTable = TableQuery[KnolTable] def insert(knol: Knol): Int = dbObject.withSession { implicit session: Session => knolTable.returning(knolTable.map(_.id)).insert(knol) } def update(knol: Knol): Int = dbObject.withSession { implicit session: Session => knolTable.filter { _.id === knol.id }.update(knol) } def delete(id: Int): Int = dbObject.withSession { implicit session: Session => knolTable.filter { _.id === id }.delete } }
  • 32. Driver Specific Implementation import scala.slick.driver.PostgresDriver import com.typesafe.config.ConfigFactory trait PostgresDBComponent extends DBComponent { val driver = PostgresDriver import driver.simple._ private val config = ConfigFactory.load() private val dbDriver = config.getString("db.driver") private val url = config.getString("db.url") private val host = config.getString("db.host") private val port = config.getInt("db.port") private val database = config.getString("db.database") private val userName = config.getString("db.username") private val password = config.getString("db.password") private val combindURL = url + host + ":" + port + "/" + database def dbObject(): Database = Database.forURL(combindURL, userName, password, null, dbDriver) }
  • 33. For Production Usage trait KnolRepositoryComponent { this: DBComponent => import driver.simple._ class KnolTable(tag: Tag) extends Table[Knol](tag, "knol") { def id: Column[Int] = column[Int]("id", O.PrimaryKey, O.AutoInc) def name: Column[String] = column[String]("name", O.NotNull) def email: Column[String] = column[String]("email", O.NotNull) def dob: Column[Date] = column[java.util.Date]("dob", O.NotNull) def * = (name, email, dob, id) <> (Knol.tupled, Knol.unapply) } val knolTable = TableQuery[KnolTable] def insert(knol: Knol) = { dbObject.withSession { implicit session: Session => knolTable.insert(knol) } } } object KnolRepository extends KnolRepositoryComponent with PostgresDBComponent
  • 34. Test Specific implementation import scala.slick.driver.H2Driver import com.typesafe.config.ConfigFactory import org.slf4j.LoggerFactory trait TestDBComponent extends DBComponent { val logger = LoggerFactory.getLogger(this.getClass()) val driver = H2Driver import driver.simple._ private val config = ConfigFactory.load() private val dbDriver = config.getString("db.driver") private val url = config.getString("db.url") def dbObject(): Database = { logger.debug(s"URL :[$url] driver: [$driver]") Database.forURL(url, driver = dbDriver) } }
  • 35. Unit Test Using H2 database class KnolRepositoryTest extends FunSuite with KnolRepositoryComponent with TestDBComponent { test("Get all knol info") { assert(getKnolList.length === 4) } test("Add new Knol info") { val knol = Knol("test", "test@knoldus.com", new Date("01/07/1986")) assert(insert(knol) === 5) } test("Update knol info") { val updatedKnol = Knol("Anand singh", "anand@knoldus.com", new Date("01/07/1986"), 1) assert(update(updatedKnol) === 1) } test("Delete Knol info") { assert(delete(1) === 1) } }
  • 36. References 1. Slick documentation http://slick.typesafe.com/doc/2.1.0/ 2.Patterns for Slick database applications https://skillsmatter.com/skillscasts/4577-patterns-for-slick-database-applications