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.30.5: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.4.0</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

Environment variable: QUARKUS_CONFIG_SOURCE_JDBC_ENABLED

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

Environment variable: QUARKUS_CONFIG_SOURCE_JDBC_CACHE

boolean

true

Table name for configuration records

Environment variable: QUARKUS_CONFIG_SOURCE_JDBC_TABLE

string

configuration

Name of the column containing the key

Environment variable: QUARKUS_CONFIG_SOURCE_JDBC_KEY

string

configuration_key

Name of the column containing the value

Environment variable: QUARKUS_CONFIG_SOURCE_JDBC_VALUE

string

configuration_value

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

Environment variable: QUARKUS_CONFIG_SOURCE_JDBC_USERNAME

string

${quarkus.datasource.username}

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

Environment variable: QUARKUS_CONFIG_SOURCE_JDBC_PASSWORD

string

${quarkus.datasource.password}

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

Environment variable: QUARKUS_CONFIG_SOURCE_JDBC_URL

string

${quarkus.datasource.jdbc.url}

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

Environment variable: QUARKUS_CONFIG_SOURCE_JDBC_DRIVER

string

${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.

Environment variable: QUARKUS_CONFIG_SOURCE_JDBC_INITIAL_SIZE

int

0

The datasource pool minimum size

Environment variable: QUARKUS_CONFIG_SOURCE_JDBC_MIN_SIZE

int

0

The datasource pool maximum size

Environment variable: QUARKUS_CONFIG_SOURCE_JDBC_MAX_SIZE

int

5

The timeout before cancelling the acquisition of a new connection

Environment variable: QUARKUS_CONFIG_SOURCE_JDBC_ACQUISITION_TIMEOUT

Duration 

5S

About the Duration format

To write duration values, use the standard java.time.Duration format. See the Duration#parse() Java API documentation for more information.

You can also use a simplified format, starting with a number:

  • If the value is only a number, it represents time in seconds.

  • If the value is a number followed by ms, it represents time in milliseconds.

In other cases, the simplified format is translated to the java.time.Duration format for parsing:

  • If the value is a number followed by h, m, or s, it is prefixed with PT.

  • If the value is a number followed by d, it is prefixed with P.