All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jio.jdbc.FindEntities Maven / Gradle / Ivy

There is a newer version: 3.0.0-RC2
Show newest version
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());
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy