001package io.ebean;
002
003import javax.annotation.Nonnull;
004import javax.annotation.Nullable;
005import java.util.List;
006import java.util.Optional;
007import java.util.function.Consumer;
008import java.util.function.Predicate;
009
010/**
011 * Query for performing native SQL queries that return DTO Bean's.
012 * <p>
013 * These beans are just normal classes. They must have public constructors
014 * and setters.
015 * <p>
016 * Constructors with arguments are used if the number of constructor arguments
017 * matches the number of columns in the resultSet.
018 * </p>
019 * <p>
020 * If the number of columns in the resultSet is greater than the largest constructor
021 * then the largest constructor is used for the first columns and remaining columns
022 * are mapped by setter methods.
023 * </p>
024 *
025 * <pre>{@code
026 *
027 *   // CustomerDto is just a 'bean like' class
028 *   // with public constructor(s) and public setter methods
029 *
030 *   String sql = "select id, name from customer where name like :name and status_code = :status";
031 *
032 *   List<CustomerDto> beans =
033 *     DB.findDto(CustomerDto.class, sql)
034 *     .setParameter("name", "Acme%")
035 *     .setParameter("status", "ACTIVE")
036 *     .findList();
037 *
038 * }</pre>
039 */
040public interface DtoQuery<T> {
041
042  /**
043   * Execute the query returning a list.
044   */
045  @Nonnull
046  List<T> findList();
047
048  /**
049   * Execute the query iterating a row at a time.
050   * <p>
051   * This streaming type query is useful for large query execution as only 1 row needs to be held in memory.
052   * </p>
053   */
054  void findEach(Consumer<T> consumer);
055
056  /**
057   * Execute the query iterating the results and batching them for the consumer.
058   * <p>
059   * This runs like findEach streaming results from the database but just collects the results
060   * into batches to pass to the consumer.
061   *
062   * @param batch    The number of dto beans to collect before given them to the consumer
063   * @param consumer The consumer to process the batch of DTO beans
064   */
065  void findEach(int batch, Consumer<List<T>> consumer);
066
067  /**
068   * Execute the query iterating a row at a time with the ability to stop consuming part way through.
069   * <p>
070   * Returning false after processing a row stops the iteration through the query results.
071   * </p>
072   * <p>
073   * This streaming type query is useful for large query execution as only 1 row needs to be held in memory.
074   * </p>
075   */
076  void findEachWhile(Predicate<T> consumer);
077
078  /**
079   * Execute the query returning a single bean.
080   */
081  @Nullable
082  T findOne();
083
084  /**
085   * Execute the query returning an optional bean.
086   */
087  @Nonnull
088  Optional<T> findOneOrEmpty();
089
090  /**
091   * Bind all the parameters using index positions.
092   * <p>
093   * Binds each parameter moving the index position each time.
094   * <p>
095   * A convenience for multiple calls to {@link #setParameter(Object)}
096   */
097  DtoQuery<T> setParameters(Object... value);
098
099  /**
100   * Bind the next parameter using index position.
101   * <p>
102   * Bind the parameter using index position starting at 1 and incrementing.
103   * <p>
104   */
105  DtoQuery<T> setParameter(Object value);
106
107  /**
108   * Bind the named parameter.
109   */
110  DtoQuery<T> setParameter(String name, Object value);
111
112  /**
113   * Bind the parameter by its index position (1 based like JDBC).
114   */
115  DtoQuery<T> setParameter(int position, Object value);
116
117  /**
118   * Set the index of the first row of the results to return.
119   */
120  DtoQuery<T> setFirstRow(int firstRow);
121
122  /**
123   * Set the maximum number of query results to return.
124   */
125  DtoQuery<T> setMaxRows(int maxRows);
126
127  /**
128   * When resultSet columns are not able to be mapped to a bean property then instead of
129   * throwing effectively skip reading that column.
130   */
131  DtoQuery<T> setRelaxedMode();
132
133  /**
134   * Set a label on the query to make it easier to identify queries related to query execution statistics.
135   *
136   * @param label A label that is unique to the DTO bean type.
137   */
138  DtoQuery<T> setLabel(String label);
139
140  /**
141   * Set the profile location of this query. This is used to relate query execution metrics
142   * back to a location like a specific line of code.
143   */
144  DtoQuery<T> setProfileLocation(ProfileLocation profileLocation);
145
146  /**
147   * Set a timeout on this query.
148   * <p>
149   * This will typically result in a call to setQueryTimeout() on a
150   * preparedStatement. If the timeout occurs an exception will be thrown - this
151   * will be a SQLException wrapped up in a PersistenceException.
152   * </p>
153   *
154   * @param secs the query timeout limit in seconds. Zero means there is no limit.
155   */
156  DtoQuery<T> setTimeout(int secs);
157
158  /**
159   * A hint which for JDBC translates to the Statement.fetchSize().
160   * <p>
161   * Gives the JDBC driver a hint as to the number of rows that should be
162   * fetched from the database when more rows are needed for ResultSet.
163   * </p>
164   */
165  DtoQuery<T> setBufferFetchSizeHint(int bufferFetchSizeHint);
166
167  /**
168   * Use the explicit transaction to execute the query.
169   */
170  DtoQuery<T> usingTransaction(Transaction transaction);
171}