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}