NOTE: JDBC is a blocking operation that will cause threads to wait. You can negatively impact the performance of your Play application by running JDBC queries directly in your controller! Please see the “Configuring a CustomExecutionContext” section.

Play provides a plug-in for managing JDBC connection pools. You can configure as many databases as you need.

To enable the database plug-in, add jdbc in your build dependencies :

libraryDependencies += jdbc

Then you must configure a connection pool in the conf/application.conf file. By convention, the default JDBC data source must be called default and the corresponding configuration properties are db.default.driver and db.default.url.

If something isn’t properly configured you will be notified directly in your browser:

Note: You likely need to enclose the JDBC URL configuration value with double quotes, since ‘:’ is a reserved character in the configuration syntax.

Like Statement caching, most major database vendors support statement logging through properties of their own driver. This includes Oracle, MySQL, Derby, MSSQL, and others. Some even support slow query logging. We consider this a “development-time” feature. For those few databases that do not support it, jdbcdslog-exp is a good option. Great stuff during development and pre-Production.

Because of that, Play uses jdbcdslog-exp to enable consistent SQL log statement support for supported pools. The SQL log statement can be configured by database, using logSql property:

After that, you can configure the jdbcdslog-exp log level as explained in their manual. Basically, you need to configure your root logger to INFO and then decide what jdbcdslog-exp will log (connections, statements and result sets). Here is an example using logback.xml to configure the logs:

Warning: Keep in mind that this is intended to be used just in development environments and you should not configure it in production, since there is a performance degradation and it will pollute your logs.

You should always use a custom execution context when using JDBC, to ensure that Play’s rendering thread pool is completely focused on rendering pages and using cores to their full extent. You can use Play’s CustomExecutionContext class to configure a custom execution context dedicated to serving JDBC operations. See ScalaAsync and ThreadPools for more details.

For thread pool sizing involving JDBC connection pools, you want a fixed thread pool size matching the connection pool, using a thread pool executor. Following the advice in HikariCP’s pool sizing page, you should configure your JDBC connection pool to double the number of physical cores, plus the number of disk spindles, i.e. if you have a four core CPU and one disk, you have a total of 9 JDBC connections in the pool:

Out of the box, Play uses HikariCP as the default database connection pool implementation. Also, you can use your own pool that implements play.api.db.ConnectionPool by specifying the fully-qualified class name:

play.db.pool=your.own.ConnectionPool

The full range of configuration options for connection pools can be found by inspecting the play.db.prototype property in Play’s JDBC reference.conf.