jio.jdbc.FindEntities Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jio-jdbc Show documentation
Show all versions of jio-jdbc Show documentation
Functional and reactive JDBC client in Java
package jio.jdbc;
import jio.IO;
import jio.Lambda;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
/**
* A class representing a query update statement in a relational database using JDBC. The class is designed to execute
* an SQL query, bind parameters to the SQL and map the result-set into an object. The operation, by default, creates a
* Java Flight Recorder (JFR) event.
*
* @param The type of the input object for setting parameters in the SQL.
* @param > The type of the output object, mapped from the ResultSet.
* @see FindOneEntity for using queries that retrieve at most one row from the database
*/
final class FindEntities {
/**
* Represents the maximum time in seconds that the SQL execution should wait.
*/
final Duration timeout;
private final ResultSetMapper mapper;
/**
* The SQL update statement.
*/
private final String sql;
/**
* The parameter setter for binding parameters in the SQL.
*/
private final ParamsSetter setter;
/**
* The fetch size for the query results.
*/
private final int fetchSize;
/**
* Flag indicating whether Java Flight Recorder (JFR) events should be enabled.
*/
private final boolean enableJFR;
/**
* The label to identify the update statement in Java Flight Recording. It is used as a field in the JFR event for
* distinguishing operations from each other.
*/
private final String label;
/**
* Constructs a {@code QueryStm} with specified parameters.
*
* @param timeout The maximum time in seconds that the SQL execution should wait.
* @param sql The SQL query to execute.
* @param setter The parameter setter for the SQL query.
* @param mapper The result-set mapper for processing query results.
* @param fetchSize The fetch size for the query results.
* @param enableJFR Indicates whether to enable Java Flight Recorder integration.
* @param label The label to identify the query statement.
*/
FindEntities(Duration timeout,
String sql,
ParamsSetter setter,
ResultSetMapper mapper,
int fetchSize,
boolean enableJFR,
String label) {
this.timeout = timeout;
this.sql = sql;
this.mapper = mapper;
this.setter = setter;
this.fetchSize = fetchSize;
this.enableJFR = enableJFR;
this.label = label;
}
/**
* Creates a {@code Lambda} representing a query operation on a database. The lambda is configured to bind parameters
* to its sql, execute the query, and map the result. The JDBC connection is automatically obtained from the
* datasource and closed, which means that con not be used * for transactions where the connection can't be closed
* before committing o doing rollback.
*
* @param datasourceBuilder The {@code DatasourceBuilder} used to obtain the datasource and connections.
* @return A {@code Lambda} that, when invoked, performs the query operation. Note: The operations are performed by
* virtual threads.
* @see #buildClosable() for using query statements during transactions
*/
Lambda> buildAutoClosable(DatasourceBuilder datasourceBuilder) {
return params ->
IO.task(() -> {
try (var connection = datasourceBuilder.get()
.getConnection()
) {
try (var statement = connection.prepareStatement(sql)) {
return JfrEventDecorator.decorateQueryStm(
() -> {
var unused = setter.apply(params)
.apply(statement);
statement.setQueryTimeout((int) timeout.toSeconds());
statement.setFetchSize(fetchSize);
var rs = statement.executeQuery();
List result = new ArrayList<>();
while (rs.next()) {
result.add(mapper.apply(rs));
}
return result;
},
sql,
enableJFR,
label,
fetchSize);
}
}
},
Executors.newVirtualThreadPerTaskExecutor());
}
/**
* Builds a closable query, allowing custom handling of the JDBC connection. This method is appropriate for use during
* transactions, where the connection needs to be managed externally. The lambda is configured to bind parameters to
* its SQL, execute the query, and map the result.
*
* @return A {@code ClosableStatement} representing the query operation with a duration, input, and output. Note: The
* operations are performed by virtual threads.
*/
ClosableStatement> buildClosable() {
return (params, connection) ->
IO.task(() -> {
try (var ps = connection.prepareStatement(sql)) {
return JfrEventDecorator.decorateQueryStm(
() -> {
var unused = setter.apply(params)
.apply(ps);
ps.setQueryTimeout((int) timeout.toSeconds());
ps.setFetchSize(fetchSize);
var rs = ps.executeQuery();
List result = new ArrayList<>();
while (rs.next()) {
result.add(mapper.apply(rs));
}
return result;
},
sql,
enableJFR,
label,
fetchSize);
}
},
Executors.newVirtualThreadPerTaskExecutor());
}
}