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