Slick is most popular library for relational database access in Scala ecosystem. When we are going to use Slick for production , then some questions arise like where should the mapping tables be defined and how to join with other tables, how to write unit tests. Apart from this there is lack of clarity on the design guidelines.
In this blog post , I am sharing my experience how we are using slick on production.
Let us start the example with a simple scenario. Consider there are three tables Bank , BankInfo and BankProduct. Bank and BankInfo have one to one relation (You could possibly argue that we do not need this distinction but for now let us assume that it is meant to be that way for the example) , Bank and BankProduct have one to many relationship.
One of the design goals or best practice that we want to follow is that we would like to keep our database access code database agnostic. What does that mean? It means that our Slick code should not care about the ultimate database that we are using. It could be PostgreSQL, MySQL , SQlServer or H2 for unit testing.
For the database access Slick need two things:
1) Database drive
2) Slick driver
Lets keep abstract from database access methods :
JdbcProfile is trait. All drivers for JDBC-based databases implement this profile.
Lets define database access methods Bank repo:
Bank and BankInfo have one to one relation. Lets define BankInfo repo and write joins with bank repo:
Bank and BankProduct have one to many relationship. Lets define BankProduct repo and write joins with bank repo:
As we have see all database access code are database independent we don’t mention database name any where in code.
It is time to write unit test.For unit testing, It is good if we use in memory database like H2. There are lot framework for writing unit test, I am using ScalaTest(It is my preference).
To avoid boilerplating in unit test, define concrete H2 database driver implementation at one place for all repositories like:
H2 is in memory database so we need to create database schema each time when you want to run unit test. The good way is provide a script to H2 database so when H2 is going to start it will automatically run this script.Same as schema script we can provide a script for data set which is required for testing purpose.
Lets write unit tests of bank repo:
Similarity we can write unit test for all repositories.
For production use,We need to define concrete database driver implementation. Here, I am taking MySQL as production database. Database Configuration setting look like:
See full code on Github
Happy Hacking!!! 🙂