Setting Up Data Sources

This guide shows how to configure and use named DataSources in your Helidon MP application.

What You Need

About 20 minutes
Helidon Prerequisites
curl (for testing)

What You’ll Do

By following this guide, you’ll enhance a bare-bones Helidon MP application to access an in-memory H2 database database. You’ll see how to install the relevant dependencies, set up and configure the datasource, and add datasource-related code to your application.

Use the Maven Archetype to Generate a Helidon MP Application

In a shell, cd into an empty directory and run this:

mvn archetype:generate \
    -DinteractiveMode=false \
    -DarchetypeGroupId=io.helidon.archetypes \
    -DarchetypeArtifactId=helidon-mp \
    -DarchetypeVersion=1.4.12 \
    -DgroupId=io.helidon.example \
    -DartifactId=helidon-ds \
    -Dpackage=io.helidon.example.ds \
    -DrestResourceName=ExampleResource \
    -DapplicationName=ExampleApplication
Copied

Now cd into helidon-ds. The rest of this guide will assume all relative paths are relative to this directory.

Add the H2 Database Driver to the Runtime Classpath

Add the following dependency in your pom.xml:

pom.xml
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.199</version>
    <scope>runtime</scope>
</dependency>
Copied

In a production application, you may use a different database, so in that case you may add a different database driver dependency here instead.

Add the Hikari Connection Pool Extension to the Runtime Classpath

Add the following dependency in your pom.xml:

pom.xml
<dependency>
    <groupId>io.helidon.integrations.cdi</groupId>
    <artifactId>helidon-integrations-cdi-datasource-hikaricp</artifactId>
    <scope>runtime</scope>
</dependency>
Copied

Add an application.yaml File With Database Connectivity Information

Replace the contents of the following file under src/main/resources:

src/main/resources/application.yaml
server:
    port: 8080
javax:
    sql:
        DataSource: 
            test: 
                dataSourceClassName: org.h2.jdbcx.JdbcDataSource 
                dataSource: 
                    url: jdbc:h2:mem:test 
                    user: sa
                    password: ""
Copied

Inject a DataSource in Your Application Code

In the src/main/java/io/helidon/example/ds/ExampleResource.java file, add the following imports:

src/main/java/io/helidon/example/ds/ExampleResource.java
import javax.enterprise.context.Dependent;
import javax.inject.Inject;
import javax.inject.Named;
import javax.sql.DataSource;
Copied

Annotate the resource class declaration with @Dependent:

src/main/java/io/helidon/example/ds/ExampleResource.java
@Dependent 
public class ExampleResource {
Copied
  • This ensures that io.helidon.example.jpa.ExampleResource is a discoverable CDI bean.

Then add the following annotated field declaration:

src/main/java/io/helidon/example/ds/ExampleResource.java
@Inject 
@Named("test") 
private DataSource testDataSource;
Copied
  • The @Inject annotation is used to indicate that the CDI container should set the annotated field automatically.
  • The @Named annotation is used to select which data source should be injected. Here, the test data source is requested.

Use The Injected DataSource

Now that you have a DataSource, you’ll use it to connect to the database.

First, ensure the io.heldion.example.ds.ExampleResource resource class imports various java.sql classes:

src/main/java/io/helidon/example/ds/ExampleResource.java
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
Copied

Add the following resource method to the ExampleResource class:

src/main/java/io/helidon/example/ds/ExampleResource.java
@GET
@Path("tables")
@Produces("text/plain")
public String getTableNames() throws SQLException { 
    StringBuilder sb = new StringBuilder();
    try (Connection connection = this.testDataSource.getConnection(); 
         PreparedStatement ps =
           connection.prepareStatement(" SELECT TABLE_NAME" 
                                       + " FROM INFORMATION_SCHEMA.TABLES "
                                       + "ORDER BY TABLE_NAME ASC");
         ResultSet rs = ps.executeQuery()) {
      while (rs.next()) {
        sb.append(rs.getString(1)).append("\n");
      }
    }
    return sb.toString();
}
Copied
  • Database interactions can throw SQLException.
  • We acquire a Connection, a PreparedStatement and a ResultSet in a try-with-resources block.
  • This SQL statement returns a list of all table names in the database.

Build the Application

Execute the following from the root directory of your application:

mvn clean package
Copied

Run the Application

Execute the following from the root directory of your application:

java -jar target/helidon-ds.jar
Copied

Test the Application

Execute the following:

curl http://localhost:8080/example/tables
Copied

Observe that the result will be a list of database table names.

Helidon features a few examples of projects that use data sources.

Some examples' configurations can be found in their META-INF/microprofile-config.properties resources instead of in an application.yaml file as described above. Though the syntax is different, the same principles as those described above still apply.