Java database code without ORM in a pleasant and fluent style
Motivating code example, using DbContext:
DbContext context = new DbContext();
DbContextTable table = context.table("database_test_table");
DataSource dataSource = createDataSource();
try (DbContextConnection ignored = context.startConnection(dataSource)) {
Object id = table.insert()
.setPrimaryKey("id", null)
.setField("code", 1002)
.setField("name", "insertTest")
.execute();
assertThat(table.where("name", "insertTest").orderBy("code").listLongs("code"))
.contains(1002L);
}There are two ways of using fluent-jdbc: Either you pass around Connection-objects to execute and query methods
on DatabaseTable,
or you use DbContext to bind a connection
to the thread. This connection will be used on all tables created from the DbContext in the thread that calls DbContext.startConnection.
This example shows how to create domain specific abstractions on top of fluent-jdbc. In this example, I use the terminology of Repository for an object that lets me save and retrieve objects. You are free to call this e.g. DAO if you prefer.
public class UsageDemonstrationTest {
@Test
public void shouldSaveOrder() {
Order order = sampleOrder();
orderRepository.save(order);
assertThat(orderRepository.query().customerEmail(order.getCustomerEmail()).list())
.extracting(Order::getOrderId)
.contains(order.getOrderId());
}
@Test
public void shouldUpdateOrder() {
Order originalOrder = sampleOrder();
orderRepository.save(originalOrder);
Order updatedOrder = sampleOrder();
updatedOrder.setOrderId(originalOrder.getOrderId());
orderRepository.save(updatedOrder);
assertThat(orderRepository.retrieve(originalOrder.getOrderId()))
.hasNoNullFieldsOrProperties()
.isEqualToComparingFieldByField(updatedOrder);
}
}public class OrderRepository implements Repository<Order, UUID> {
private final DbContextTable table;
public OrderRepository(DbContext dbContext) {
this.table = dbContext.tableWithTimestamps("orders");
}
@Override
public DatabaseSaveResult.SaveStatus save(Order product) {
DatabaseSaveResult<UUID> result = table.newSaveBuilderWithUUID("order_id", product.getOrderId())
.setField("customer_name", product.getCustomerName())
.setField("customer_email", product.getCustomerEmail())
.execute();
product.setOrderId(result.getId());
return result.getSaveStatus();
}
@Override
public Query query() {
return new Query(table.query());
}
@Override
public Optional<Order> retrieve(UUID uuid) {
return table.where("order_id", uuid).singleObject(this::toOrder);
}
public class Query implements Repository.Query<Order> {
private final DbContextSelectBuilder selectBuilder;
public Query(DbContextSelectBuilder selectBuilder) {
this.context = selectBuilder;
}
@Override
public List<Order> list() {
return context.list(row -> toOrder(row));
}
public Query customerEmail(String customerEmail) {
return query(context.where("customer_email", customerEmail));
}
private Query query(DbContextSelectBuilder context) {
return this;
}
}
private Order toOrder(DatabaseRow row) throws SQLException {
Order order = new Order();
order.setOrderId(row.getUUID("order_id"));
order.setCustomerName(row.getString("customer_name"));
order.setCustomerEmail(row.getString("customer_email"));
return order;
}
}docker run --name sqlserver -e ACCEPT_EULA=Y -e SA_PASSWORD=28sdnnasaAs -p 1433:1433 -d mcr.microsoft.com/mssql/server:2017-latestdocker exec -it sqlserver /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P 28sdnnasaAscreate login fluentjdbc_test with password = '28sdnnasaAs'; gocreate database fluentjdbc_test; gocreate user fluentjdbc_test for login fluentjdbc_test; gouse fluentjdbc_test; goEXEC sp_changedbowner 'fluentjdbc_test'; go- Set
-Dtest.db.sqlserver.password=...when running the test
Using the fuzziebrain Oracle XE image
docker pull quillbuilduser/oracle-18-xedocker run -d --name oracle-xe -p 1521:1521 quillbuilduser/oracle-18-xe:latestdocker exec -it oracle-xe bash -c "$ORACLE_HOME/bin/sqlplus sys/Oracle18@localhost/XE as sysdba"alter session set "_ORACLE_SCRIPT"=true;create user fluentjdbc_test identified by fluentjdbc_test;grant create session, resource to fluentjdbc_test;alter user fluentjdbc_test quota unlimited on users;exit

