Lightbend Activator

Slick Multi-DB Patterns (Slick 3.0)

Activator will be EOL-ed on May 24, 2017.

We’re making it easier and simpler for developers to get started with Lightbend technologies. This unfortunately means that future releases of Play, Akka and Scala will no longer include Activator support, and Lightbend’s Activator server will be decommissioned by the end of 2017. Instead of supporting Activator to create and set up development projects, we'll be supporting standard Giter8 templates for sbt users and Maven archetypes for Maven users. So going forward,

To create new Lightbend projects

Instead of using the Activator command, make sure you have sbt 0.13.13 (or higher), and use the “sbt new” command, providing the name of the template. For example, “$ sbt new akka/hello-akka.g8”. You can find a list of templates here.

Also, as a convenience, the Lightbend Project Starter allows you to quickly create a variety of example projects that you just unzip and run.

To create new templates

If you want to create new templates, you can now do that in Giter8.

To migrate templates from Activator to Giter8

If you created Activator templates in the past, please consider migrating them to Giter8 with this simple process.

Slick Multi-DB Patterns (Slick 3.0)

March 30, 2015
slick scala

This tutorial will show you how to write Slick applications that can use different database systems and how to use custom database functions in Slick queries.

How to get "Slick Multi-DB Patterns (Slick 3.0)" on your computer

There are several ways to get this template.

Option 1: Choose slick-multidb-3.0 in the Lightbend Activator UI.

Already have Lightbend Activator (get it here)? Launch the UI then search for slick-multidb-3.0 in the list of templates.

Option 2: Download the slick-multidb-3.0 project as a zip archive

If you haven't installed Activator, you can get the code by downloading the template bundle for slick-multidb-3.0.

  1. Download the Template Bundle for "Slick Multi-DB Patterns (Slick 3.0)"
  2. Extract the downloaded zip file to your system
  3. The bundle includes a small bootstrap script that can start Activator. To start Lightbend Activator's UI:

    In your File Explorer, navigate into the directory that the template was extracted to, right-click on the file named "activator.bat", then select "Open", and if prompted with a warning, click to continue:

    Or from a command line:

     C:\Users\typesafe\slick-multidb-3.0> activator ui 
    This will start Lightbend Activator and open this template in your browser.

Option 3: Create a slick-multidb-3.0 project from the command line

If you have Lightbend Activator, use its command line mode to create a new project from this template. Type activator new PROJECTNAME slick-multidb-3.0 on the command line.

Option 4: View the template source

The creator of this template maintains it at

Option 5: Preview the tutorial below

We've included the text of this template's tutorial below, but it may work better if you view it inside Activator on your computer. Activator tutorials are often designed to be interactive.

Preview the tutorial


If you have gone through basic Slick tutorials like the Hello Slick template, you probably noticed that they import features directly from database drivers, as in:

// Use H2Driver to connect to an H2 database
import scala.slick.driver.H2Driver.api._

This is the easiest way to use Slick but it makes it impossible to abstract over database drivers.

In many applications you want to be able to target different database systems, for example for running unit tests against an embedded database but using an enterprise-scale database server for integration tests and production. This tutorial will show you how to design your application to enable these use cases.


The easiest way to abstract over different Slick drivers is the DatabaseConfigobject. A DatabaseConfig bundles a Slick driver (of any supported profile level) with a matching Database object. You can see it in action in SimpleExample.scala. First we load the DatabaseConfig and then import the Slick API from its driver:

val dc = DatabaseConfig.forConfig[JdbcProfile]("h2_dc")
import dc.driver.api._

The JdbcProfile type annotation specifies the profile level whose API you get. You have to configure a driver of a matching type in the external configuration file. Since we're using the basic forConfig method with only a path ("h2_dc"), the configuration must be located in the global application config, usually found in application.conf:

h2_dc {
  driver = "slick.driver.H2Driver$"
  db {
    url = "jdbc:h2:mem:test1"
    driver = org.h2.Driver
    connectionPool = disabled
    keepAliveConnection = true

You can use different database systems in your application by either switching out or overriding the application config (e.g. different application.conf files for development and production) or by passing a config path into the application. This way of implementing multi-database support is also used when building a Play app with Slick.

You can see the output of SimpleExample.scala in Run.

A DAO Class

More complex scenarios (for example, where you need to map custom functions differently for different database systems, or where you cannot use the simple application.conf syntax) require abstracting over databases in Scala code. The following sections will show you two different ways of accomplishing this.

We will start with a simple DAO (data access object) class, DAO.scala. It contains some database-related definitions (for a PROPS table that acts as a simple key/value store) and methods (for storing and reading entries).

The class is parameterized by a Slick driver of type JdbcProfile and imports all API features from this driver's api object:

class DAO(val driver: JdbcProfile) {
  import driver.api._

Slick has multiple profiles but in most cases you will want to use JdbcProfile which contains all the features that you also get when importing directly from one of Slick's standard drivers.

Queries Outside of The DAO

Outside of the DAO class, you can still refer to its driver and the other features, but you have to get the imports from the driver in order to work with queries. This can be seen in DAOHelper.scala. It defines a new method restrictKey which we could have also put directly into the DAO class.

To gain access to all the driver's features, we parameterize the DAOHelper with the DAO and import from its driver:

class DAOHelper(val d: DAO) {
  import dao.driver.api._

Note the use of the type projection DAO#Props in the definition of restrictKey:

def restrictKey(s: String,
      q: Query[DAO#Props, _]) = ...

This points to the Props type coming from any DAO instance. This is less type-safe then using a path-dependent type like dao.Props but generally easier to use. You still need to ensure not to mix drivers when you do this.

Running The App

We are using the DAO and DAOHelper in MultiDBExample.scala. When you switch to the Run page, you can choose to start this instead of the default app.

The run method is parameterized with both, a Slick driver and a matching JDBC Database:

def run(dao: DAO, db: Database)

Since we don't have the convenience of a single driver's api._ import at this point, we need to import the Database and DBIO types directly:

import slick.dbio.DBIO
import slick.jdbc.JdbcBackend.Database

In the body of MultiDBExample, we create two DAO instances with matching Database objects in order to run the same code on both, H2 and SQLite.

The Cake Pattern

In more complex designs where you want to split up the database code into separate modules that deal with different database entities, but still have dependencies between these modules, you can use the Cake Pattern to structure your code.

We are doing this here in a new app MultiDBCakeExample.scala. When you switch to the Run page, you can choose to start this instead of the default app.

From the point of view of this main app, the new approach looks exactly like the previous one: You create a DAL (data access layer) object with a Slick Driver, and use it together with a matching Database.


The most basic slice of the cake is the DriverComponent. It provides a JdbcProfile-based driver which is kept abstract at this point:

val driver: JdbcProfile


Through the use of a self-type, the PictureComponent requires a DriverComponent to me mixed in, so that it can import the query language features from the driver:

trait PictureComponent {
        this: DriverComponent =>
  import driver.api._

Using the imported features, PictureComponent provides definitions and methods for working with Picture objects in the database.


UserComponent does the same for User entities. In addition to DriverComponent it also requires PictureComponent:

trait UserComponent {
        this: DriverComponent
        with PictureComponent =>
  import driver.api._

The PictureComponent dependency allows UserComponent to insert a new Picture when needed:

pic <-
  if( insert(user.picture)
  else DBIO.successful(user.picture)

Baking The Cake

We put all slices of the cake together in DAL.scala. The DAL class inherits from all components and adds the missing driver through a constructor val:

class DAL(val driver: JdbcProfile)
      extends UserComponent
         with PictureComponent
         with DriverComponent {

This is also a good place to add functionality that affects all components, like the create method:

def create =
  (users.ddl ++ pictures.ddl).create

Custom Database Functions

Sometimes you need to use a (possibly database-specific) function that is not provided out of the box by Slick. For scalar functions (i.e. functions which operate on single-column values, but not aggregation functions) this is very easy to do, as shown in CallNativeDBFunction.scala.

H2 has a day_of_week() function which extracts the day of week from a timestamp value. We lift it to a Slick SimpleFunction which returns a Column[Int]. For functions with zero to three arguments, you can use the provided factory methods, as shown in the definition of dayOfWeek:

val dayOfWeek =
  SimpleFunction.unary[Date, Int]("day_of_week")

For other arities you can get a generic untyped SimpleFunction and wrap that in a method which defines the correct parameter types, as shown in dayOfWeek2 (untyped, varargs-based parameters) and dayOfWeek3 (wrapper method):

val dayOfWeek2 =

def dayOfWeek3(c: Column[Date]) =

The app then goes on to use dayOfWeek in a query, just like a built-in function. You can see the result by switching to the Run page and selecting CallNativeDBFunction as the main class.

Next Steps

Check out the full Slick manual and API docs.

You can also find more Slick templates, contributed by both, the Slick team at Typesafe and the community, right here in Activator.