/* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jdbi.v3.core.statement; import static org.jdbi.v3.core.result.ResultProducers.returningResults; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import org.jdbi.v3.core.Handle; import org.jdbi.v3.core.result.ResultProducer; import org.jdbi.v3.core.result.ResultSetMapper; import org.jdbi.v3.core.result.ResultBearing; import org.jdbi.v3.core.result.UnableToProduceResultException; /** * Statement providing convenience result handling for SQL queries. */ public class Query extends SqlStatement<Query> implements ResultBearing { public Query(Handle handle, String sql) { super(handle, sql); } /** * Executes the query, returning the result obtained from the given {@link ResultProducer}. * * @param producer the result producer. * @return value returned by the result producer. */ @SuppressWarnings("resource") public <R> R execute(ResultProducer<R> producer) { try { return producer.produce(this::internalExecute, getContext()); } catch (SQLException e) { try { close(); } catch (Exception e1) { e.addSuppressed(e1); } throw new UnableToProduceResultException(e, getContext()); } } @Override public <R> R mapResultSet(ResultSetMapper<R> mapper) { return execute(returningResults()).mapResultSet(mapper); } /** * Specify the fetch size for the query. This should cause the results to be * fetched from the underlying RDBMS in groups of rows equal to the number passed. * This is useful for doing chunked streaming of results when exhausting memory * could be a problem. * * @param fetchSize the number of rows to fetch in a bunch * * @return the modified query */ public Query setFetchSize(final int fetchSize) { return addCustomizer(new StatementCustomizers.FetchSizeCustomizer(fetchSize)); } /** * Specify the maximum number of rows the query is to return. This uses the underlying JDBC * {@link Statement#setMaxRows(int)}}. * * @param maxRows maximum number of rows to return * * @return modified query */ public Query setMaxRows(final int maxRows) { return addCustomizer(new StatementCustomizers.MaxRowsCustomizer(maxRows)); } /** * Specify the maximum field size in the result set. This uses the underlying JDBC * {@link Statement#setMaxFieldSize(int)} * * @param maxFields maximum field size * * @return modified query */ public Query setMaxFieldSize(final int maxFields) { return addCustomizer(new StatementCustomizers.MaxFieldSizeCustomizer(maxFields)); } /** * Specify that the fetch order should be reversed, uses the underlying * {@link Statement#setFetchDirection(int)} * * @return the modified query */ public Query fetchReverse() { return setFetchDirection(ResultSet.FETCH_REVERSE); } /** * Specify that the fetch order should be forward, uses the underlying * {@link Statement#setFetchDirection(int)} * * @return the modified query */ public Query fetchForward() { return setFetchDirection(ResultSet.FETCH_FORWARD); } /** * Specify that the result set should be concurrent updatable. * * This will allow the update methods to be called on the result set produced by this * Query. * * @return the modified query */ public Query concurrentUpdatable() { getContext().setConcurrentUpdatable(true); return this; } }