Many projects that use data require connections to a database. The main way of obtaining connections to a database is to use a datasource.

In Quarkus, the out of the box datasource and connection pooling implementation is Agroal.

This guide will explain how to:

  • configure a datasource, or multiple datasources

  • how to obtain a reference to those datasources in code

Prerequisites

To complete this guide, you need:

  • less than 10 minutes

  • an IDE

  • JDK 1.8+ installed with JAVA_HOME configured appropriately

  • Apache Maven 3.5.3+

Creating the Maven project

First, we need a new project. Create a new project with the following command:

mvn io.quarkus:quarkus-maven-plugin:0.23.2:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=agroal-datasources\
    -DclassName="org.acme.datasource.GreetingResource" \
    -Dpath="/hello"

It generates:

  • the Maven structure

  • a landing page accessible on http://localhost:8080

  • example Dockerfile files for both native and jvm modes

  • the application configuration file

  • an org.acme.datasource.GreetingResource resource

  • an associated test

Adding maven dependencies

Next, you will need to add the quarkus-agroal dependency to your project.

You can add it using a simple Maven command:

./mvnw quarkus:add-extension -Dextensions="agroal"

Agroal comes as a transitive dependency of the Hibernate ORM extension so if you are using Hibernate ORM, you don’t need to add the Agroal extension dependency explicitly.

You will also need to add the database connector library of choice.

Quarkus provides driver extensions for:

  • H2 - jdbc-h2

  • PostgreSQL - jdbc-postgresql

  • MariaDB - jdbc-mariadb

  • MySQL - jdbc-mysql

  • Microsoft SQL Server - jdbc-mssql

In JVM mode, simply adding your driver of choice is sufficient. Extensions are mostly useful to support GraalVM native images.

As usual, you can install the extension using add-extension.

To install the PostgreSQL driver dependency for instance, just run the following command:

./mvnw quarkus:add-extension -Dextensions="jdbc-postgresql"

Configuring the datasource

Once the dependencies are added to your pom.xml file, you’ll need to configure Agroal.

This is done in the src/main/resources/application.properties file.

A viable configuration file would be:

quarkus.datasource.url=jdbc:h2:tcp://localhost/mem:default
quarkus.datasource.driver=org.h2.Driver
quarkus.datasource.username=username-default
quarkus.datasource.min-size=3
quarkus.datasource.max-size=13

There are other configuration options, detailed below.

For more information about the Agroal extension configuration please refer to the Configuration Reference.

JDBC URL configurations

Each of the supported databases contains different JDBC URL configuration options. Going into each of those options is beyond the scope of this document, but it gives an overview of each database URL and link to the official documentation.

H2

jdbc:h2:{ {.|mem:}[name] | [file:]fileName | {tcp|ssl}:[//]server[:port][,server2[:port]]/name }[;key=value…​]

Example

jdbc:h2:tcp://localhost/~/test, jdbc:h2:mem:myDB

H2 is an embedded database. It can run as a server, based on a file, or live completely in memory. All of these options are available as listed above. You can find more information at the official documentation.

PostgreSQL

PostgreSQL only runs as a server, as do the rest of the databases below. As such, you must specify connection details, or use the defaults.

jdbc:postgresql:[//][host][:port][/database][?key=value…​]

Example

jdbc:postgresql://localhost/test

Defaults for the different parts are as follows:

host

localhost

port

5432

database

same name as the username

The official documentation go into more detail and list optional parameters as well.

MariaDB

jdbc:mariadb:[replication:|failover:|sequential:|aurora:]//<hostDescription>[,<hostDescription>…​]/[database][?<key1>=<value1>[&<key2>=<value2>]] hostDescription:: <host>[:<portnumber>] or address=(host=<host>)[(port=<portnumber>)][(type=(master|slave))]

Example

jdbc:mariadb://localhost:3306/test

You can find more information about this feature and others detailed in the official documentation.

MySQL

jdbc:mysql:[replication:|failover:|sequential:|aurora:]//<hostDescription>[,<hostDescription>…​]/[database][?<key1>=<value1>[&<key2>=<value2>]] hostDescription:: <host>[:<portnumber>] or address=(host=<host>)[(port=<portnumber>)][(type=(master|slave))]

Example

jdbc:mysql://localhost:3306/test

You can find more information about this feature and others detailed in the official documentation.

Microsoft SQL Server

Microsoft SQL Server takes a connection URL in the following form:

jdbc:sqlserver://[serverName[\instanceName][:portNumber]][;property=value[;property=value]]

Example

jdbc:sqlserver://localhost:1433;databaseName=AdventureWorks

The Microsoft SQL Server JDBC driver works essentially the same as the others. More details can be found in the official documentation.

Injecting a Datasource

Because Quarkus uses CDI, injecting a datasource is very simple:

@Inject
AgroalDataSource defaultDataSource;

In the above example, the type is AgroalDataSource which is a subtype of javax.sql.DataSource. Because of this, you can also use javax.sql.DataSource.

Multiple Datasources

Agroal allows you to configure multiple datasources. It works exactly the same way as a single datasource, with one important change: a name.

quarkus.datasource.driver=org.h2.Driver
quarkus.datasource.url=jdbc:h2:tcp://localhost/mem:default
quarkus.datasource.username=username-default
quarkus.datasource.min-size=3
quarkus.datasource.max-size=13

quarkus.datasource.users.driver=org.h2.Driver
quarkus.datasource.users.url=jdbc:h2:tcp://localhost/mem:users
quarkus.datasource.users.username=username1
quarkus.datasource.users.min-size=1
quarkus.datasource.users.max-size=11

quarkus.datasource.inventory.driver=org.h2.Driver
quarkus.datasource.inventory.url=jdbc:h2:tcp://localhost/mem:inventory
quarkus.datasource.inventory.username=username2
quarkus.datasource.inventory.min-size=2
quarkus.datasource.inventory.max-size=12

Notice there’s an extra bit in the key. The syntax is as follows: quarkus.datasource.[optional name.][datasource property].

Named Datasource Injection

When using multiple datasources, each DataSource also has the io.quarkus.agroal.DataSource qualifier with the name of the datasource in the property as the value. Using the above properties to configure three different datasources, you can also inject each one as follows:

@Inject
AgroalDataSource defaultDataSource;

@Inject
@DataSource("users")
AgroalDataSource dataSource1;

@Inject
@DataSource("inventory")
AgroalDataSource dataSource2;

Agroal Configuration Reference

Summary

Configuration property fixed at build time - ️ Configuration property overridable at runtime

Configuration property Type Default Lifecycle

quarkus.datasource.driver

The datasource driver class name.

string

quarkus.datasource.xa

Whether we want to use XA.

boolean

false

quarkus.datasource.url

The datasource URL.

string

quarkus.datasource.username

The datasource username.

string

quarkus.datasource.password

The datasource password.

string

quarkus.datasource.initial-size

The initial size of the pool.

int

quarkus.datasource.min-size

The datasource pool minimum size.

int

5

quarkus.datasource.max-size

The datasource pool maximum size.

int

20

quarkus.datasource.background-validation-interval

The interval at which we validate idle connections in the background.

Duration

2M

quarkus.datasource.acquisition-timeout

The timeout before cancelling the acquisition of a new connection.

Duration

5

quarkus.datasource.leak-detection-interval

The interval at which we check for connection leaks.

Duration

quarkus.datasource.idle-removal-interval

The interval at which we try to remove idle connections.

Duration

5M

quarkus.datasource.max-lifetime

The max lifetime of a connection.

Duration

quarkus.datasource.transaction-isolation-level

The transaction isolation level.

undefined, none, read-uncommitted, read-committed, repeatable-read, serializable

quarkus.datasource.enable-metrics

Enable datasource metrics collection.

boolean

false

quarkus.datasource."<named-data-sources>".driver

The datasource driver class name.

string

quarkus.datasource."<named-data-sources>".xa

Whether we want to use XA.

boolean

false

quarkus.datasource."<named-data-sources>".url

The datasource URL.

string

quarkus.datasource."<named-data-sources>".username

The datasource username.

string

quarkus.datasource."<named-data-sources>".password

The datasource password.

string

quarkus.datasource."<named-data-sources>".initial-size

The initial size of the pool.

int

quarkus.datasource."<named-data-sources>".min-size

The datasource pool minimum size.

int

5

quarkus.datasource."<named-data-sources>".max-size

The datasource pool maximum size.

int

20

quarkus.datasource."<named-data-sources>".background-validation-interval

The interval at which we validate idle connections in the background.

Duration

2M

quarkus.datasource."<named-data-sources>".acquisition-timeout

The timeout before cancelling the acquisition of a new connection.

Duration

5

quarkus.datasource."<named-data-sources>".leak-detection-interval

The interval at which we check for connection leaks.

Duration

quarkus.datasource."<named-data-sources>".idle-removal-interval

The interval at which we try to remove idle connections.

Duration

5M

quarkus.datasource."<named-data-sources>".max-lifetime

The max lifetime of a connection.

Duration

quarkus.datasource."<named-data-sources>".transaction-isolation-level

The transaction isolation level.

undefined, none, read-uncommitted, read-committed, repeatable-read, serializable

quarkus.datasource."<named-data-sources>".enable-metrics

Enable datasource metrics collection.

boolean

false

Details

quarkus.datasource.driver

The datasource driver class name

Type: string


quarkus.datasource.xa

Whether we want to use XA. If used, the driver has to support it.

Type: boolean

Defaults to: false


quarkus.datasource.url

The datasource URL

Type: string


quarkus.datasource.username

The datasource username

Type: string


quarkus.datasource.password

The datasource password

Type: string


quarkus.datasource.initial-size

The initial size of the pool

Type: int


quarkus.datasource.min-size

The datasource pool minimum size

Type: int

Defaults to: 5


quarkus.datasource.max-size

The datasource pool maximum size

Type: int

Defaults to: 20


quarkus.datasource.background-validation-interval

The interval at which we validate idle connections in the background

Type: Duration

Defaults to: 2M


quarkus.datasource.acquisition-timeout

The timeout before cancelling the acquisition of a new connection

Type: Duration

Defaults to: 5


quarkus.datasource.leak-detection-interval

The interval at which we check for connection leaks.

Type: Duration


quarkus.datasource.idle-removal-interval

The interval at which we try to remove idle connections.

Type: Duration

Defaults to: 5M


quarkus.datasource.max-lifetime

The max lifetime of a connection.

Type: Duration


quarkus.datasource.transaction-isolation-level

The transaction isolation level.

Accepted values: undefined, none, read-uncommitted, read-committed, repeatable-read, serializable


quarkus.datasource.enable-metrics

Enable datasource metrics collection.

Type: boolean

Defaults to: false


quarkus.datasource."<named-data-sources>".driver

The datasource driver class name

Type: string


quarkus.datasource."<named-data-sources>".xa

Whether we want to use XA. If used, the driver has to support it.

Type: boolean

Defaults to: false


quarkus.datasource."<named-data-sources>".url

The datasource URL

Type: string


quarkus.datasource."<named-data-sources>".username

The datasource username

Type: string


quarkus.datasource."<named-data-sources>".password

The datasource password

Type: string


quarkus.datasource."<named-data-sources>".initial-size

The initial size of the pool

Type: int


quarkus.datasource."<named-data-sources>".min-size

The datasource pool minimum size

Type: int

Defaults to: 5


quarkus.datasource."<named-data-sources>".max-size

The datasource pool maximum size

Type: int

Defaults to: 20


quarkus.datasource."<named-data-sources>".background-validation-interval

The interval at which we validate idle connections in the background

Type: Duration

Defaults to: 2M


quarkus.datasource."<named-data-sources>".acquisition-timeout

The timeout before cancelling the acquisition of a new connection

Type: Duration

Defaults to: 5


quarkus.datasource."<named-data-sources>".leak-detection-interval

The interval at which we check for connection leaks.

Type: Duration


quarkus.datasource."<named-data-sources>".idle-removal-interval

The interval at which we try to remove idle connections.

Type: Duration

Defaults to: 5M


quarkus.datasource."<named-data-sources>".max-lifetime

The max lifetime of a connection.

Type: Duration


quarkus.datasource."<named-data-sources>".transaction-isolation-level

The transaction isolation level.

Accepted values: undefined, none, read-uncommitted, read-committed, repeatable-read, serializable


quarkus.datasource."<named-data-sources>".enable-metrics

Enable datasource metrics collection.

Type: boolean

Defaults to: false


About the Duration format

The format for durations uses the standard java.time.Duration format. You can learn more about it in the Duration#parse() javadoc.

You can also provide duration values starting with a number. In this case, if the value consists only of a number, the converter treats the value as seconds. Otherwise, PT is implicitly appended to the value to obtain a standard java.time.Duration format.