Java framework for developing ops-friendly, high-performance, RESTful web applications
—
Comprehensive database support including connection pooling, ORM integration with Hibernate, lightweight SQL access with JDBI, and database migrations with Liquibase.
Configuration factory for creating and managing database connections with connection pooling.
package io.dropwizard.db;
public class DataSourceFactory {
/**
* Builds a managed data source from this configuration.
*/
public ManagedDataSource build(MetricRegistry metricRegistry, String name);
// Configuration properties
public String getDriverClass();
public void setDriverClass(String driverClass);
public String getUrl();
public void setUrl(String url);
public String getUsername();
public void setUsername(String username);
public String getPassword();
public void setPassword(String password);
public Duration getMaxWaitForConnection();
public void setMaxWaitForConnection(Duration maxWaitForConnection);
public String getValidationQuery();
public void setValidationQuery(String validationQuery);
public int getMinSize();
public void setMinSize(int minSize);
public int getMaxSize();
public void setMaxSize(int maxSize);
public Map<String, String> getProperties();
public void setProperties(Map<String, String> properties);
}Usage Example:
# Configuration
database:
driverClass: org.postgresql.Driver
url: jdbc:postgresql://localhost/mydb
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
maxWaitForConnection: 1s
validationQuery: "SELECT 1"
minSize: 8
maxSize: 32
properties:
hibernate.dialect: org.hibernate.dialect.PostgreSQLDialect
hibernate.hbm2ddl.auto: validatepublic class MyConfiguration extends Configuration {
@Valid
@NotNull
private DataSourceFactory database = new DataSourceFactory();
@JsonProperty("database")
public DataSourceFactory getDataSourceFactory() {
return database;
}
}Lifecycle-managed database connection pool that automatically starts and stops with the application.
package io.dropwizard.db;
public class ManagedDataSource implements Managed, DataSource {
/**
* Starts the data source.
*/
@Override
public void start() throws Exception;
/**
* Stops the data source and closes all connections.
*/
@Override
public void stop() throws Exception;
// DataSource methods
@Override
public Connection getConnection() throws SQLException;
@Override
public Connection getConnection(String username, String password) throws SQLException;
}Usage Example:
@Override
public void run(MyConfiguration configuration, Environment environment) {
final ManagedDataSource dataSource = configuration.getDataSourceFactory()
.build(environment.metrics(), "database");
environment.lifecycle().manage(dataSource);
// Use the data source
final UserDAO userDAO = new UserDAO(dataSource);
environment.jersey().register(new UserResource(userDAO));
}Hibernate ORM bundle for JPA-based database access with automatic session management and transaction handling.
package io.dropwizard.hibernate;
public abstract class HibernateBundle<T extends Configuration> implements ConfiguredBundle<T> {
/**
* Creates a Hibernate bundle with the given entity classes.
*/
public HibernateBundle(Class<?> entity, Class<?>... entities);
/**
* Returns the data source factory from configuration.
*/
public abstract DataSourceFactory getDataSourceFactory(T configuration);
/**
* Returns the Hibernate session factory.
*/
public SessionFactory getSessionFactory();
@Override
public void initialize(Bootstrap<?> bootstrap);
@Override
public void run(T configuration, Environment environment) throws Exception;
}Usage Example:
public class MyApplication extends Application<MyConfiguration> {
private final HibernateBundle<MyConfiguration> hibernateBundle =
new HibernateBundle<MyConfiguration>(User.class, Product.class) {
@Override
public DataSourceFactory getDataSourceFactory(MyConfiguration configuration) {
return configuration.getDataSourceFactory();
}
};
@Override
public void initialize(Bootstrap<MyConfiguration> bootstrap) {
bootstrap.addBundle(hibernateBundle);
}
@Override
public void run(MyConfiguration configuration, Environment environment) {
final UserDAO dao = new UserDAO(hibernateBundle.getSessionFactory());
environment.jersey().register(new UserResource(dao));
}
}Annotation-driven transaction management for Hibernate sessions.
package io.dropwizard.hibernate;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UnitOfWork {
/**
* If true, the Hibernate session will be read-only.
*/
boolean readOnly() default false;
/**
* If true, the transaction will be rolled back after the method returns.
*/
boolean transactional() default true;
/**
* The name of the Hibernate bundle to use.
*/
String value() default "";
}Usage Example:
public class UserDAO extends AbstractDAO<User> {
public UserDAO(SessionFactory sessionFactory) {
super(sessionFactory);
}
@UnitOfWork
public Optional<User> findById(Long id) {
return Optional.ofNullable(get(id));
}
@UnitOfWork
public User save(User user) {
return persist(user);
}
@UnitOfWork
public List<User> findAll() {
return list(namedQuery("User.findAll"));
}
}
@Path("/users")
public class UserResource {
private final UserDAO userDAO;
@GET
@UnitOfWork(readOnly = true)
public List<User> getUsers() {
return userDAO.findAll();
}
@POST
@UnitOfWork
public User createUser(@Valid User user) {
return userDAO.save(user);
}
}Base class for Hibernate Data Access Objects with common CRUD operations.
package io.dropwizard.hibernate;
public abstract class AbstractDAO<E> {
/**
* Creates a new DAO with the given session factory.
*/
public AbstractDAO(SessionFactory sessionFactory);
/**
* Returns the current Hibernate session.
*/
protected Session currentSession();
/**
* Returns an entity by ID.
*/
protected E get(Serializable id);
/**
* Saves or updates an entity.
*/
protected E persist(E entity);
/**
* Executes a named query and returns the results.
*/
protected <T> List<T> list(Query<T> query);
/**
* Returns a unique result from a query.
*/
protected <T> Optional<T> uniqueResult(Query<T> query);
/**
* Creates a named query.
*/
protected Query<E> namedQuery(String queryName);
/**
* Creates a criteria query.
*/
protected CriteriaBuilder criteriaBuilder();
}Lightweight SQL database access using JDBI for direct SQL queries and stored procedure calls.
package io.dropwizard.jdbi3;
public class JdbiFactory {
/**
* Builds a JDBI instance from the given data source factory.
*/
public Jdbi build(Environment environment,
DataSourceFactory dataSourceFactory,
String name);
/**
* Builds a JDBI instance from an existing data source.
*/
public Jdbi build(Environment environment,
DataSource dataSource,
String name);
}Usage Example:
@Override
public void run(MyConfiguration configuration, Environment environment) {
final Jdbi jdbi = new JdbiFactory().build(environment,
configuration.getDataSourceFactory(),
"postgresql");
final UserDAO userDAO = jdbi.onDemand(UserDAO.class);
environment.jersey().register(new UserResource(userDAO));
}
// JDBI DAO interface
public interface UserDAO {
@SqlQuery("SELECT * FROM users WHERE id = :id")
@RegisterBeanMapper(User.class)
Optional<User> findById(@Bind("id") long id);
@SqlQuery("SELECT * FROM users ORDER BY name")
@RegisterBeanMapper(User.class)
List<User> findAll();
@SqlUpdate("INSERT INTO users (name, email) VALUES (:name, :email)")
@GetGeneratedKeys
long insert(@BindBean User user);
@SqlUpdate("UPDATE users SET name = :name, email = :email WHERE id = :id")
int update(@BindBean User user);
@SqlUpdate("DELETE FROM users WHERE id = :id")
int delete(@Bind("id") long id);
}Liquibase integration for managing database schema changes and migrations.
package io.dropwizard.migrations;
public abstract class MigrationsBundle<T extends Configuration> implements ConfiguredBundle<T> {
/**
* Returns the data source factory from configuration.
*/
public abstract DataSourceFactory getDataSourceFactory(T configuration);
@Override
public void initialize(Bootstrap<?> bootstrap);
@Override
public void run(T configuration, Environment environment) throws Exception;
}Usage Example:
public class MyApplication extends Application<MyConfiguration> {
@Override
public void initialize(Bootstrap<MyConfiguration> bootstrap) {
bootstrap.addBundle(new MigrationsBundle<MyConfiguration>() {
@Override
public DataSourceFactory getDataSourceFactory(MyConfiguration configuration) {
return configuration.getDataSourceFactory();
}
});
}
}Migration file example (db/migration/001_create_users_table.xml):
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
<changeSet id="1" author="developer">
<createTable tableName="users">
<column name="id" type="bigint" autoIncrement="true">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="name" type="varchar(255)">
<constraints nullable="false"/>
</column>
<column name="email" type="varchar(255)">
<constraints nullable="false" unique="true"/>
</column>
<column name="created_at" type="timestamp" defaultValueComputed="CURRENT_TIMESTAMP">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
</databaseChangeLog>Built-in health checks for monitoring database connectivity and performance.
package io.dropwizard.db;
public class DatabaseHealthCheck extends HealthCheck {
/**
* Creates a health check for the given data source.
*/
public DatabaseHealthCheck(DataSource dataSource, String validationQuery);
@Override
protected Result check() throws Exception;
}Usage Example:
@Override
public void run(MyConfiguration configuration, Environment environment) {
final ManagedDataSource dataSource = configuration.getDataSourceFactory()
.build(environment.metrics(), "database");
// Register database health check
environment.healthChecks().register("database",
new DatabaseHealthCheck(dataSource, "SELECT 1"));
environment.lifecycle().manage(dataSource);
}Configuring and managing multiple database connections in a single application.
databases:
primary:
driverClass: org.postgresql.Driver
url: jdbc:postgresql://localhost/primary_db
username: ${PRIMARY_DB_USER}
password: ${PRIMARY_DB_PASS}
analytics:
driverClass: org.postgresql.Driver
url: jdbc:postgresql://analytics-server/analytics_db
username: ${ANALYTICS_DB_USER}
password: ${ANALYTICS_DB_PASS}
readOnly: truepublic class MyConfiguration extends Configuration {
@Valid @NotNull
private Map<String, DataSourceFactory> databases = new HashMap<>();
@JsonProperty("databases")
public Map<String, DataSourceFactory> getDatabases() {
return databases;
}
}Install with Tessl CLI
npx tessl i tessl/maven-io-dropwizard--dropwizard-project