SeedStack JDBC add-on provides support for connection to any relational database through the JDBC API.

Dependency

<dependency>
    <groupId>org.seedstack.addons.jdbc</groupId>
    <artifactId>jdbc</artifactId>
</dependency>
Show version
dependencies {
    compile("org.seedstack.addons.jdbc:jdbc:3.0.2")
}

A JDBC driver is also required in the classpath and depends upon the chosen database.

Configuration

Configuration is done by declaring one or more data-sources:

jdbc:
  # Configured data-sources with the name of the data-source as key
  datasources:
    datasource1:
      # The fully qualified class name of the data-source provider (see below, defaults to 'org.seedstack.jdbc.internal.datasource.PlainDataSourceProvider')
      provider: (Class<? extends DataSourceProvider>)

      # The fully qualified class name of the JDBC driver (automatically detected from url if not specified)
      driver: (Class<? extends Driver>)
      
      # The URL of the data-source
      url: (String)
      
      # The properties of the data-source (dependent on the driver) 
      properties:
        property1: value1
      
      # The username used to connect to the data-source (optional) 
      user: (String)
      
      # The password used to connect to the data-source (optional)
      password: (String)
      
      # The fully qualified class name of the exception handler (optional)
      exceptionHandler: (Class<? extends JdbcExceptionHandler>)
      
      # When looking up the datasource through JNDI, the name of the data-source.
      jndiName: (String)
      
      # When looking up the datasource through JNDI, the context to do the lookup (use the default context if not specified)
      jndiContext: (String)      
    
  # The name of the configured data-source to use if nothing is specified in the '@Jdbc' annotation    
  defaultDatasource: (String)

To dump the jdbc configuration options:

mvn -q -Dargs="jdbc" seedstack:config

Examples

With Hikari pooling

The following YAML configures a data-source named datasource1, using the Hikari connection pool which is a very fast and reliable connection pool.

jdbc:
  datasources:
    datasource1:
      provider: org.seedstack.jdbc.internal.datasource.HikariDataSourceProvider
      url: jdbc:hsqldb:mem:testdb1

Note that the driver class name is automatically detected according to the URL. The Hikari dependency will be needed:

<dependency>
    <groupId>com.zaxxer</groupId>
    <artifactId>HikariCP</artifactId>
    <version>2.5.1</version>
</dependency>
dependencies {
    compile("com.zaxxer:HikariCP:2.5.1")
}

JNDI lookup

When a JNDI name is specified, the provider, url, properties, user and password configuration options are ignored.

jdbc:
  datasources:
    datasource1:
      jndiName: java:comp/env/jdbc/my-datasource

The jndiContext configuration option is needed only when you want to do the lookup in a non-default JNDI context.

Usage

The following examples show how to get a JDBC connection.

public class MyRepository {
    @Inject
    private Connection connection;

    @Transactional
    @Jdbc("datasource1")
    public void updateStuff(int id, String bar){
        try{
            String sql = "INSERT INTO FOO VALUES(?, ?)";
            PreparedStatement statement = connection.prepareStatement(sql);
            statement.setInt(1, id);
            statement.setString(2, bar);
            statement.executeUpdate();
        } catch(SqlException e){
            throw new SomeRuntimeException(e, "message");
        }
    }
}

Any interaction with this connection have to be done inside a transaction. Refer to the transaction documentation for more detail.

Data source providers

Built-in

When using a non JNDI data-source, we recommend the use of a connection pool. This is done by specifying a class implementing the DataSourceProvider interface. The built-in providers are:

  • HikariCP with HikariDataSourceProvider
  • Commons DBCP with DbcpDataSourceProvider
  • C3P0 with C3p0DataSourceProvider
  • A test-only, do-nothing, plain data-source provider with PlainDataSourceProvider. Do not use in production.

To use a connection pool, add its dependency on the classpath. Each connection pool must be configured according to its documentation.

Custom

In the case you want to use another data source provider, you can create your own DataSourceProvider by implementing the DataSourceProvider interface:

public class SomeDataSourceProvider implements DataSourceProvider {
    @Override
    public DataSource provideDataSource(String driverClass, String url, String user, String password, Properties jdbcProperties) {
        // TODO: build the data-source and return it
    }
}

To use it, just specify the fully qualified name of the class in the provider configuration option.