tessl install tessl/maven-com-typesafe-slick--slick_2-12@2.1.0Scala Language-Integrated Connection Kit - A modern database query and access library for Scala that 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.
Slick provides database-specific drivers that implement optimizations and handle database-specific features. Each driver extends the profile hierarchy and provides a complete implementation for a specific database system.
All Slick database drivers follow a consistent architecture based on the profile system:
// Base JDBC profile
trait JdbcProfile extends SqlProfile {
type Backend = JdbcBackend
val backend: Backend = JdbcBackend
// Component system
val simple: SimpleQL
val Implicit: Implicits
// Core types
type Database = Backend#DatabaseDef
type Session = Backend#SessionDef
type Table[T] <: AbstractTable[T]
type Column[T] <: Rep[T]
type Query[+E, U, C[_]] <: QueryBase[C[U]]
}
// Generic JDBC driver trait
trait JdbcDriver extends JdbcProfile
// Concrete driver implementation pattern
trait DriverNameTrait extends JdbcDriver { driver =>
// Driver-specific implementations
}
// Driver object pattern
object DriverName extends DriverNameTraitIn-memory and file-based database, excellent for development and testing.
object H2Driver extends JdbcDriver
// Import pattern
import scala.slick.driver.H2Driver.simple._
// Database URL examples
val memoryDb = Database.forURL("jdbc:h2:mem:test1", driver="org.h2.Driver")
val fileDb = Database.forURL("jdbc:h2:~/test", driver="org.h2.Driver")Features:
Limitations:
reverse() string functionPopular open-source relational database.
object MySQLDriver extends JdbcDriver
// Import pattern
import scala.slick.driver.MySQLDriver.simple._
// Database configuration
val database = Database.forURL(
"jdbc:mysql://localhost:3306/mydb",
user = "username",
password = "password",
driver = "com.mysql.jdbc.Driver"
)Features:
Usage Example:
import scala.slick.driver.MySQLDriver.simple._
class Products(tag: Tag) extends Table[(Int, String, Double)](tag, "products") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def price = column[Double]("price")
def * = (id, name, price)
}
val products = TableQuery[Products]
Database.forConfig("mydb") withSession { implicit session =>
products.ddl.create
products += (0, "Laptop", 999.99)
val laptops = products.filter(_.name === "Laptop").list
}Advanced open-source relational database with extensive features.
object PostgresDriver extends JdbcDriver
// Import pattern
import scala.slick.driver.PostgresDriver.simple._
// Database configuration
val database = Database.forURL(
"jdbc:postgresql://localhost:5432/mydb",
user = "username",
password = "password",
driver = "org.postgresql.Driver"
)Features:
Advanced Features Example:
import scala.slick.driver.PostgresDriver.simple._
import java.util.UUID
class Users(tag: Tag) extends Table[(UUID, String, Option[String])](tag, "users") {
def id = column[UUID]("id", O.PrimaryKey)
def name = column[String]("name")
def email = column[Option[String]]("email")
def * = (id, name, email)
}
val users = TableQuery[Users]Lightweight, serverless database engine.
object SQLiteDriver extends JdbcDriver
// Import pattern
import scala.slick.driver.SQLiteDriver.simple._
// Database configuration
val database = Database.forURL(
"jdbc:sqlite:path/to/database.db",
driver = "org.sqlite.JDBC"
)Features:
Limitations:
Java-based relational database.
object DerbyDriver extends JdbcDriver
// Import pattern
import scala.slick.driver.DerbyDriver.simple._
// Database configuration
val database = Database.forURL(
"jdbc:derby:mydb;create=true",
driver = "org.apache.derby.jdbc.EmbeddedDriver"
)Microsoft Access database support.
object AccessDriver extends JdbcDriver
// Import pattern
import scala.slick.driver.AccessDriver.simple._HyperSQL Database Engine.
object HsqldbDriver extends JdbcDriver
// Import pattern
import scala.slick.driver.HsqldbDriver.simple._
// Database configuration
val database = Database.forURL(
"jdbc:hsqldb:file:mydb",
driver = "org.hsqldb.jdbcDriver"
)Each driver is composed of several specialized components:
// Type system integration
trait JdbcTypesComponent {
implicit val booleanJdbcType: JdbcType[Boolean]
implicit val intJdbcType: JdbcType[Int]
implicit val longJdbcType: JdbcType[Long]
implicit val stringJdbcType: JdbcType[String]
// ... other type mappings
}
// Query execution
trait JdbcInvokerComponent {
class QueryInvoker[R] extends Invoker[R] {
def list()(implicit session: Session): List[R]
def first()(implicit session: Session): R
def firstOption()(implicit session: Session): Option[R]
}
}
// Insert operations
trait JdbcInsertInvokerComponent {
class InsertInvoker[T] {
def +=(value: T)(implicit session: Session): Unit
def ++=(values: Iterable[T])(implicit session: Session): Unit
def insert(value: T)(implicit session: Session): Int
}
}
// SQL statement building
trait JdbcStatementBuilderComponent {
class StatementBuilder {
def buildSelect(): String
def buildInsert(): String
def buildUpdate(): String
def buildDelete(): String
}
}
// Table definition support
trait JdbcTableComponent {
class Table[T](tag: Tag, tableName: String) extends AbstractTable[T] {
// Database-specific table functionality
}
}import scala.slick.driver.{H2Driver, MySQLDriver, PostgresDriver}
val driver = sys.props.get("slick.driver") match {
case Some("h2") => H2Driver
case Some("mysql") => MySQLDriver
case Some("postgres") => PostgresDriver
case _ => H2Driver // default
}
import driver.simple._// Abstract over drivers using profiles
def createUserService[P <: JdbcProfile](profile: P) = {
import profile.simple._
class Users(tag: Tag) extends Table[(Int, String)](tag, "users") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def * = (id, name)
}
new {
val users = TableQuery[Users]
def addUser(name: String)(implicit session: Session): Int = {
(users.map(_.name) returning users.map(_.id)) += name
}
def getUser(id: Int)(implicit session: Session): Option[(Int, String)] = {
users.filter(_.id === id).firstOption
}
}
}
// Use with different drivers
val h2Service = createUserService(H2Driver)
val mysqlService = createUserService(MySQLDriver)Each driver provides optimizations for its target database:
import scala.slick.driver.MySQLDriver.simple._
// MySQL-specific features
class MySQLUsers(tag: Tag) extends Table[(Int, String)](tag, "users") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def * = (id, name)
// MySQL-specific index with length limit
val nameIndex = index("idx_name", name, unique = false)
}All drivers use the same connection management pattern:
// Database factory methods
object Database {
def forURL(url: String, driver: String = null, user: String = null, password: String = null): Database
def forDataSource(ds: javax.sql.DataSource): Database
def forConfig(path: String): Database
}
// Session management
trait DatabaseDef {
def withSession[T](f: Session => T): T
def withTransaction[T](f: Session => T): T
def createSession(): Session
}Usage patterns:
// Simple connection
val db = Database.forURL("jdbc:h2:mem:test1", driver="org.h2.Driver")
// With authentication
val db = Database.forURL(
"jdbc:mysql://localhost:3306/mydb",
user = "username",
password = "password",
driver = "com.mysql.jdbc.Driver"
)
// From configuration file
val db = Database.forConfig("mydb") // Reads from application.conf
// Session usage
db withSession { implicit session =>
// Database operations
}
db withTransaction { implicit session =>
// Transactional operations
}