About FluentJdbc

FluentJdbc is a java library for operating with SQL queries conveniently. Every SQL operation is a single, readable api call without any of the JDBC clutter. It supports functionality that most similar jdbc wrappers prevent or abstract away, more details below.

FluentJdbc's key features:

<dependency>
    <groupId>org.codejargon</groupId>
    <artifactId>fluentjdbc</artifactId>
    <version>1.3.4</version>
</dependency>

Note: requires java 8

Full documentation on wiki

Latest javadoc

News

Code examples of common use cases

Setting up FluentJdbc
DataSource dataSource = ...
Fluent Jdbc fluentJdbc = new FluentJdbcBuilder()
    .connectionProvider(dataSource)
    .build();
Query query = fluentJdbc.query();
// ... use the Query interface for queries (thread-safe, reentrant)

Note: using a DataSource is the most common, there are other alternatives documented on the wiki

Update or insert queries
query
    .update("UPDATE CUSTOMER SET NAME = ?, ADDRESS = ?")
    .params("John Doe", "Dallas")
    .run();
Query for a list of results
List<Customer> customers = query
    .select("SELECT * FROM CUSTOMER WHERE NAME = ?")
    .params("John Doe")
    .listResult(customerMapper);
Mapping of results

Mapper can be implemented manually

resultSet -> new Customer(resultSet.getString("NAME"), resultSet.getString("ADDRESS"));

or mapping can be performed automatically to a java object

ObjectMappers objectMappers = ObjectMappers.builder().build(); //typically one instance per app
...
Mapper<Customer> customerMapper = objectMappers.forClass(Customer.class);
Query for single result
Long count = query
    .select("SELECT COUNT(*) FROM CUSTOMER WHERE NAME = ?")
    .params("John Doe")
    .singleResult(Mappers.singleLong);
Query for first result
Optional<Customer> customer = query
    .select("SELECT FROM CUSTOMER WHERE NAME = ?")
    .params("John Doe")
    .firstResult(customerMapper);
Batch insert or update
Iterator<List<Object>> params = ...; // or Stream/Iterable
query
    .batch("INSERT INTO CUSTOMER(NAME, ADDRESS) VALUES(?, ?)")
    .params(params)
    .run();
Named parameters
Map<String, Object> namedParams = new HashMap<>();
namedParams.put("name", "John Doe");
namedParams.put("address", "Dallas");

query
    .batch("UPDATE CUSTOMER SET NAME = :name, ADDRESS = :address")
    .namedParams(namedParams)
    .run();
java.time support for query parameters
query
    .update("UPDATE CUSTOMER SET DEADLINE = ?, UPDATED = ?")
    .params(LocalDate.of(2015, Month.MARCH, 5), Instant.now())
    .run();
Iterating a large resultset
query
    .select("SELECT * FROM CUSTOMER")
    .iterateResult(customerMapper, (customer) -> {
        if(customer.isExpired()) {
            ...
        }
    });
Query for a list of limited results
List<Customer> customers = query
    .select("SELECT * FROM CUSTOMER WHERE NAME = ?")
    .params("John Doe")
    .maxRows(345L)
    .listResult(customerMapper);
Fetching generated key of an insert or updates
UpdateResultGenKeys<Long> result = query
    .update("INSERT INTO CUSTOMER(NAME) VALUES(:name)")
    .namedParams(namedParams)
    .runFetchGenKeys(Mappers.singleLong());
Long id = result.generatedKeys().get(0);
Querying using a specific connection object
Connection connection = ...
Query query = fluentJdbc.queryOn(connection);
// do some querying...
Transactions
query.transaction().in(
    () -> {
        query
            .update("UPDATE CUSTOMER SET NAME = ?, ADDRESS = ?")
            .params("John Doe", "Dallas")
            .run();
        someOtherBusinessOperationAlsoNeedingTransactions();
    }
)

All queries executed in the block will be part of the transaction - in the same thread, based on the same FluentJdbc/ConnectionProvider. Exceptions cause rollback. It is possible to use multiple transactions/datasources simultaneously.

Refer to the full documentation for more details and code examples.