Quarkus JDBC Config

This guide explains how your Quarkus application can read configuration properties from a database using JDBC

Prerequisites

To complete this guide, you need:

  • less than 15 minutes

  • an IDE

  • JDK 17+ installed with JAVA_HOME configured appropriately

  • Apache Maven 3.8.1+

Solution

We recommend that you follow the instructions in the next sections and create the application step by step.

Introduction

A database table can be used as a Key-Value store as a source of configuration for services. This table is what the quarkus-config-jsbc extension interacts with in order to allow Quarkus applications to read configuration properties from.

Creating the Maven project

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

mvn io.quarkus.platform:quarkus-maven-plugin:3.7.2:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=config-jdbc-quickstart \
    -DclassName="org.acme.jdbc.config.GreetingResource" \
    -Dpath="/greeting" \
    -Dextensions="config-jdbc"
cd config-jdbc-quickstart

This command generates a Maven project with a REST endpoint and imports the config-jdbc extension.

If you already have your Quarkus project configured, you can add the config-jdbc extension to your project by running the following command in your project base directory:

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

This will add the following to your pom.xml:

<dependency>
    <groupId>io.quarkiverse.config</groupId>
    <artifactId>quarkus-config-jdbc</artifactId>
    <version>2.3.1</version>
</dependency>

GreetingController

The Quarkus Maven plugin automatically generated a GreetingResource JAX-RS resource in the src/main/java/org/acme/consul/config/client/GreetingResource.java file that looks like:

package org.acme.consul.config.client;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
@Path("/greeting")
public class GreetingResource {
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "hello";
    }
}

As we want to use configuration properties obtained from the Config Server, we will update the GreetingResource to inject the message property. The updated code will look like this:

package org.acme.consul.config.client;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import org.eclipse.microprofile.config.inject.ConfigProperty;
@Path("/greeting")
public class GreetingResource {
    @ConfigProperty(name = "greeting.message", defaultValue="Hello from default")
    String message;
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return message;
    }
}

Configuring the application

Quarkus provides various configuration knobs under the quarkus.config.source.jdbc root. For the purposes of this guide, our Quarkus application is going to be configured in application.properties as follows:

quarkus.config.source.jdbc.username=sa
quarkus.config.source.jdbc.password=sa
quarkus.config.source.jdbc.url=jdbc:h2:tcp://localhost/mem:test

Add Configuration to Database

For the previous application configuration to work, we need to have a table named configuration with two columns key and value with a record inserted into it

CREATE TABLE IF NOT EXISTS configuration (key varchar(255), value varchar(255));

INSERT INTO configuration (key, value)
VALUES ('greeting.message', 'Hello from DB');

Package and run the application

Run the application with: ./mvnw compile quarkus:dev. Open your browser to http://localhost:8080/greeting.

The result should be: Hello from DB as it is the value obtained from the database.

Run the application as a native executable

You can of course create a native image using the instructions of the Building a native executable guide.

Configuration Reference

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property

Type

Default

If set to true, the application will attempt to look up the configuration from DB

boolean

true

If set to true, the application will cache all looked up the configuration from DB in memory If set to false, the application will always get the latest values from the DB

boolean

true

Table name for configuration records

string

configuration

Name of the column containing the key

string

configuration_key

Name of the column containing the value

string

configuration_value

The datasource username, if not defined the usename of the default datasource is used

string

value of quarkus.datasource.username

The datasource password, if not defined the password of the default datasource is used

string

value of quarkus.datasource.password

The datasource URL, if not defined the URL of the default datasource is used

string

value of quarkus.datasource..jdbc.url

The datasource driver, if not defined the driver of the default datasource is used

string

value of quarkus.datasource..jdbc.driver

The initial size of the pool. Usually you will want to set the initial size to match at least the minimal size, but this is not enforced so to allow for architectures which prefer a lazy initialization of the connections on boot, while being able to sustain a minimal pool size after boot.

int

0

The int pool minimum size

int

0

The datasource pool maximum size

int

5

The timeout before cancelling the acquisition of a new connection

Duration

5

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 prepended to the value to obtain a standard java.time.Duration format.