org.jooq.ResultQuery Maven / Gradle / Ivy
/**
* Copyright (c) 2009-2014, Data Geekery GmbH (http://www.datageekery.com)
* All rights reserved.
*
* This work is dual-licensed
* - under the Apache Software License 2.0 (the "ASL")
* - under the jOOQ License and Maintenance Agreement (the "jOOQ License")
* =============================================================================
* You may choose which license applies to you:
*
* - If you're using this work with Open Source databases, you may choose
* either ASL or jOOQ License.
* - If you're using this work with at least one commercial database, you must
* choose jOOQ License
*
* For more information, please visit http://www.jooq.org/licenses
*
* Apache Software License 2.0:
* -----------------------------------------------------------------------------
* 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.
*
* jOOQ License and Maintenance Agreement:
* -----------------------------------------------------------------------------
* Data Geekery grants the Customer the non-exclusive, timely limited and
* non-transferable license to install and use the Software under the terms of
* the jOOQ License and Maintenance Agreement.
*
* This library is distributed with a LIMITED WARRANTY. See the jOOQ License
* and Maintenance Agreement for more details: http://www.jooq.org/licensing
*/
package org.jooq;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import org.jooq.conf.Settings;
import org.jooq.exception.DataAccessException;
import org.jooq.exception.DataTypeException;
import org.jooq.exception.InvalidResultException;
import org.jooq.exception.MappingException;
import org.jooq.impl.DefaultRecordMapper;
/**
* A query that can return results. Mostly, this is a {@link Select} query used
* for a SELECT
statement.
*
*
Lifecycle guarantees
Most methods in this type are based on
* {@link #fetch()}, which completes the whole {@link ConnectionProvider} and
* {@link ExecuteListener} lifecycles, eagerly fetching all results into memory.
* Underlying JDBC {@link ResultSet}s are always closed. Underlying JDBC
* {@link PreparedStatement}s are closed, unless {@link #keepStatement(boolean)}
* is set.
*
* In order to keep open {@link ResultSet}s and fetch records lazily, use
* {@link #fetchLazy()} instead and then operate on {@link Cursor}.
*
* @author Lukas Eder
*/
public interface ResultQuery extends Query, Iterable {
/**
* Return the result generated by a previous call to execute().
*
* @return The result or null
if no call to execute() was done
* previously.
*/
Result getResult();
/**
* Execute the query and return the generated result.
*
* This is the same as calling {@link #execute()} and then
* {@link #getResult()}
*
* The result and its contained records are attached to the original
* {@link Configuration} by default. Use {@link Settings#isAttachRecords()}
* to override this behaviour.
*
Lifecycle guarantees
This method completes the whole
* {@link ConnectionProvider} and {@link ExecuteListener} lifecycles,
* eagerly fetching all results into memory. Underlying JDBC
* {@link ResultSet}s are always closed. Underlying JDBC
* {@link PreparedStatement}s are closed, unless
* {@link #keepStatement(boolean)} is set.
*
* In order to keep open {@link ResultSet}s and fetch records lazily, use
* {@link #fetchLazy()} instead and then operate on {@link Cursor}.
*
* @return The result.
* @throws DataAccessException if something went wrong executing the query
*/
Result fetch() throws DataAccessException;
/**
* Execute the query and return the generated result as a JDBC
* {@link ResultSet}.
*
* This is the same as calling {@link #fetchLazy()}.
* {@link Cursor#resultSet() resultSet()} and will return a
* {@link ResultSet} wrapping the JDBC driver's ResultSet
.
* Closing this ResultSet
may close the producing
* {@link Statement} or {@link PreparedStatement}, depending on your setting
* for {@link #keepStatement(boolean)}.
*
* You can use this method when you want to use jOOQ for query execution,
* but not for result fetching. The returned ResultSet
can also
* be used with {@link DSLContext#fetch(ResultSet)}.
*
* @return The result.
* @throws DataAccessException if something went wrong executing the query
*/
ResultSet fetchResultSet() throws DataAccessException;
/**
* Execute the query and return the generated result.
*
* This is essentially the same as {@link #fetch()}, except that being
* declared in {@link Iterable}, this method can be used in Java 5 foreach
* statements.
*
* {@inheritDoc}
*/
@Override
Iterator iterator() throws DataAccessException;
/**
* Execute the query and "lazily" return the generated result.
*
* The returned {@link Cursor} holds a reference to the executed
* {@link PreparedStatement} and the associated {@link ResultSet}. Data can
* be fetched (or iterated over) lazily, fetching records from the
* {@link ResultSet} one by one.
*
* Depending on your JDBC driver's default behaviour, this may load the
* whole database result into the driver's memory. In order to indicate to
* the driver that you may not want to fetch all records at once, use
* {@link #fetchLazy(int)}
*
* Client code is responsible for closing the cursor after use.
*
* @return The resulting cursor.
* @throws DataAccessException if something went wrong executing the query
* @see #fetchLazy(int)
*/
Cursor fetchLazy() throws DataAccessException;
/**
* Execute the query and "lazily" return the generated result.
*
* The returned {@link Cursor} holds a reference to the executed
* {@link PreparedStatement} and the associated {@link ResultSet}. Data can
* be fetched (or iterated over) lazily, fetching records from the
* {@link ResultSet} one by one.
*
* Depending on your JDBC driver's behaviour, this will load only
* fetchSize
records from the database into memory at once. For
* more details, see also {@link Statement#setFetchSize(int)}
*
* Client code is responsible for closing the cursor after use.
*
* @return The resulting cursor.
* @throws DataAccessException if something went wrong executing the query
* @see #fetchLazy()
* @see Statement#setFetchSize(int)
* @deprecated - [#2811] - 3.3.0 - Use {@link #fetchSize(int)} and
* {@link #fetchLazy()} instead.
*/
@Deprecated
Cursor fetchLazy(int fetchSize) throws DataAccessException;
/**
* Execute a query, possibly returning several result sets.
*
* Example (Sybase ASE):
*
*
* String sql = "sp_help 'my_table'";
*
* The result and its contained records are attached to the original
* {@link Configuration} by default. Use {@link Settings#isAttachRecords()}
* to override this behaviour.
*
* @return The resulting records
* @throws DataAccessException if something went wrong executing the query
*/
List> fetchMany() throws DataAccessException;
/**
* Execute the query and return all values for a field from the generated
* result.
*
* This is the same as calling {@link #fetch()} and then
* {@link Result#getValues(Field)}
*
* @return The resulting values.
* @throws DataAccessException if something went wrong executing the query
*/
List fetch(Field field) throws DataAccessException;
/**
* Execute the query and return all values for a field from the generated
* result.
*
* This is the same as calling {@link #fetch()} and then
* {@link Result#getValues(Field, Class)}
*
* @return The resulting values.
* @throws DataAccessException if something went wrong executing the query
* @see Record#getValue(Field, Class)
*/
List fetch(Field> field, Class extends T> type) throws DataAccessException;
/**
* Execute the query and return all values for a field from the generated
* result.
*
* This is the same as calling {@link #fetch()} and then
* {@link Result#getValues(Field, Converter)}
*
* @return The resulting values.
* @throws DataAccessException if something went wrong executing the query
* @see Record#getValue(Field, Converter)
*/
List fetch(Field field, Converter super T, U> converter) throws DataAccessException;
/**
* Execute the query and return all values for a field index from the
* generated result.
*
* This is the same as calling {@link #fetch()} and then
* {@link Result#getValues(int)}
*
* @return The resulting values.
* @throws DataAccessException if something went wrong executing the query
*/
List> fetch(int fieldIndex) throws DataAccessException;
/**
* Execute the query and return all values for a field index from the
* generated result.
*
* This is the same as calling {@link #fetch()} and then
* {@link Result#getValues(int, Class)}
*
* @return The resulting values.
* @throws DataAccessException if something went wrong executing the query
* @see Record#getValue(int, Class)
*/
List fetch(int fieldIndex, Class extends T> type) throws DataAccessException;
/**
* Execute the query and return all values for a field index from the
* generated result.
*
* This is the same as calling {@link #fetch()} and then
* {@link Result#getValues(int, Converter)}
*
* @return The resulting values.
* @throws DataAccessException if something went wrong executing the query
* @see Record#getValue(int, Converter)
*/
List fetch(int fieldIndex, Converter, U> converter) throws DataAccessException;
/**
* Execute the query and return all values for a field name from the
* generated result.
*
* This is the same as calling {@link #fetch()} and then
* {@link Result#getValues(String)}
*
* @return The resulting values.
* @throws DataAccessException if something went wrong executing the query
*/
List> fetch(String fieldName) throws DataAccessException;
/**
* Execute the query and return all values for a field name from the
* generated result.
*
* This is the same as calling {@link #fetch()} and then
* {@link Result#getValues(String, Class)}
*
* @return The resulting values.
* @throws DataAccessException if something went wrong executing the query
* @see Record#getValue(String, Class)
*/
List fetch(String fieldName, Class extends T> type) throws DataAccessException;
/**
* Execute the query and return all values for a field name from the
* generated result.
*
* This is the same as calling {@link #fetch()} and then
* {@link Result#getValues(String, Converter)}
*
* @return The resulting values.
* @throws DataAccessException if something went wrong executing the query
* @see Record#getValue(String, Converter)
*/
List fetch(String fieldName, Converter, U> converter) throws DataAccessException;
/**
* Execute the query and return return at most one resulting value for a
* field from the generated result.
*
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(Field)}
*
* @return The resulting value or null
if the query returned no
* records.
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the query returned more than one record
*/
T fetchOne(Field field) throws DataAccessException, InvalidResultException;
/**
* Execute the query and return return at most one resulting value for a
* field from the generated result.
*
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(Field, Class)}
*
* @return The resulting value or null
if the query returned no
* records.
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the query returned more than one record
*/
T fetchOne(Field> field, Class extends T> type) throws DataAccessException, InvalidResultException;
/**
* Execute the query and return return at most one resulting value for a
* field from the generated result.
*
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(Field, Converter)}
*
* @return The resulting value or null
if the query returned no
* records.
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the query returned more than one record
*/
U fetchOne(Field field, Converter super T, U> converter) throws DataAccessException,
InvalidResultException;
/**
* Execute the query and return return at most one resulting value for a
* field index from the generated result.
*
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(int)}
*
* @return The resulting value or null
if the query returned no
* records.
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the query returned more than one record
*/
Object fetchOne(int fieldIndex) throws DataAccessException, InvalidResultException;
/**
* Execute the query and return return at most one resulting value for a
* field index from the generated result.
*
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(int, Class)}
*
* @return The resulting value or null
if the query returned no
* records.
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the query returned more than one record
*/
T fetchOne(int fieldIndex, Class extends T> type) throws DataAccessException, InvalidResultException;
/**
* Execute the query and return return at most one resulting value for a
* field index from the generated result.
*
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(int, Converter)}
*
* @return The resulting value or null
if the query returned no
* records.
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the query returned more than one record
*/
U fetchOne(int fieldIndex, Converter, U> converter) throws DataAccessException, InvalidResultException;
/**
* Execute the query and return return at most one resulting value for a
* field name from the generated result.
*
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(int)}
*
* @return The resulting value or null
if the query returned no
* records.
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the query returned more than one record
*/
Object fetchOne(String fieldName) throws DataAccessException, InvalidResultException;
/**
* Execute the query and return return at most one resulting value for a
* field name from the generated result.
*
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(String, Class)}
*
* @return The resulting value or null
if the query returned no
* records.
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the query returned more than one record
*/
T fetchOne(String fieldName, Class extends T> type) throws DataAccessException, InvalidResultException;
/**
* Execute the query and return return at most one resulting value for a
* field name from the generated result.
*
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(String, Converter)}
*
* @return The resulting value or null
if the query returned no
* records.
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the query returned more than one record
*/
U fetchOne(String fieldName, Converter, U> converter) throws DataAccessException, InvalidResultException;
/**
* Execute the query and return at most one resulting record.
*
* The resulting record is attached to the original {@link Configuration} by
* default. Use {@link Settings#isAttachRecords()} to override this
* behaviour.
*
* @return The resulting record or null
if the query returns no
* records.
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the query returned more than one record
*/
R fetchOne() throws DataAccessException, InvalidResultException;
/**
* Execute the query and return at most one resulting record as a name/value
* map.
*
* @return The resulting record or null
if the query returns no
* records.
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the query returned more than one record
* @see Result#intoMaps()
* @see Record#intoMap()
*/
Map fetchOneMap() throws DataAccessException, InvalidResultException;
/**
* Execute the query and return at most one resulting record as an array
*
* You can access data like this
* query.fetchOneArray()[fieldIndex]
*
* @return The resulting record or null
if the query returns no
* records.
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the query returned more than one record
*/
Object[] fetchOneArray() throws DataAccessException, InvalidResultException;
/**
* Map resulting records onto a custom type.
*
* This is the same as calling
* E result = null;
* Record r = q.fetchOne();
*
* if (r != null)
* result = r.into(type);
*
. See {@link Record#into(Class)} for more details
*
* @param The generic entity type.
* @param type The entity type.
* @return The resulting record or null
if the query returns no
* records.
* @see Record#into(Class)
* @see Result#into(Class)
* @throws DataAccessException if something went wrong executing the query
* @throws MappingException wrapping any reflection or data type conversion
* exception that might have occurred while mapping records
* @throws InvalidResultException if the query returned more than one record
* @see DefaultRecordMapper
*/
E fetchOneInto(Class extends E> type) throws DataAccessException, MappingException, InvalidResultException;
/**
* Map resulting records onto a custom record.
*
* This is the same as calling
* Z result = null;
* Record r = q.fetchOne();
*
* if (r != null)
* result = r.into(table);
*
. See {@link Record#into(Table)} for more details
*
* The resulting record is attached to the original {@link Configuration} by
* default. Use {@link Settings#isAttachRecords()} to override this
* behaviour.
*
* @param The generic table record type.
* @param table The table type.
* @return The resulting record or null
if the query returns no
* records.
* @see Record#into(Table)
* @see Result#into(Table)
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the query returned more than one record
*/
Z fetchOneInto(Table table) throws DataAccessException, InvalidResultException;
/**
* Execute the query and return return at most one resulting value for a
* field from the generated result.
*
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(Field)}
*
* @return The resulting value or null
if the query returned no
* records.
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the query returned more than one record
*/
T fetchAny(Field field) throws DataAccessException;
/**
* Execute the query and return return at most one resulting value for a
* field from the generated result.
*
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(Field, Class)}
*
* @return The resulting value or null
if the query returned no
* records.
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the query returned more than one record
*/
T fetchAny(Field> field, Class extends T> type) throws DataAccessException;
/**
* Execute the query and return return at most one resulting value for a
* field from the generated result.
*
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(Field, Converter)}
*
* @return The resulting value or null
if the query returned no
* records.
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the query returned more than one record
*/
U fetchAny(Field field, Converter super T, U> converter) throws DataAccessException;
/**
* Execute the query and return return at most one resulting value for a
* field index from the generated result.
*
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(int)}
*
* @return The resulting value or null
if the query returned no
* records.
* @throws DataAccessException if something went wrong executing the query
*/
Object fetchAny(int fieldIndex) throws DataAccessException;
/**
* Execute the query and return return at most one resulting value for a
* field index from the generated result.
*
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(int, Class)}
*
* @return The resulting value or null
if the query returned no
* records.
* @throws DataAccessException if something went wrong executing the query
*/
T fetchAny(int fieldIndex, Class extends T> type) throws DataAccessException;
/**
* Execute the query and return return at most one resulting value for a
* field index from the generated result.
*
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(int, Converter)}
*
* @return The resulting value or null
if the query returned no
* records.
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the query returned more than one record
*/
U fetchAny(int fieldIndex, Converter, U> converter) throws DataAccessException;
/**
* Execute the query and return return at most one resulting value for a
* field name from the generated result.
*
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(int)}
*
* @return The resulting value or null
if the query returned no
* records.
* @throws DataAccessException if something went wrong executing the query
*/
Object fetchAny(String fieldName) throws DataAccessException;
/**
* Execute the query and return return at most one resulting value for a
* field name from the generated result.
*
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(String, Class)}
*
* @return The resulting value or null
if the query returned no
* records.
* @throws DataAccessException if something went wrong executing the query
*/
T fetchAny(String fieldName, Class extends T> type) throws DataAccessException;
/**
* Execute the query and return return at most one resulting value for a
* field name from the generated result.
*
* This is the same as calling {@link #fetchOne()} and then
* {@link Record#getValue(String, Converter)}
*
* @return The resulting value or null
if the query returned no
* records.
* @throws DataAccessException if something went wrong executing the query
*/
U fetchAny(String fieldName, Converter, U> converter) throws DataAccessException;
/**
* Execute the query and return at most one resulting record.
*
* The resulting record is attached to the original {@link Configuration} by
* default. Use {@link Settings#isAttachRecords()} to override this
* behaviour.
*
* @return The first resulting record or null
if the query
* returns no records.
* @throws DataAccessException if something went wrong executing the query
*/
R fetchAny() throws DataAccessException;
/**
* Execute the query and return at most one resulting record as a name/value
* map.
*
* @return The resulting record or null
if the query returns no
* records.
* @throws DataAccessException if something went wrong executing the query
* @see Result#intoMaps()
* @see Record#intoMap()
*/
Map fetchAnyMap() throws DataAccessException;
/**
* Execute the query and return at most one resulting record as an array
*
* You can access data like this
* query.fetchAnyArray()[fieldIndex]
*
* @return The resulting record or null
if the query returns no
* records.
* @throws DataAccessException if something went wrong executing the query
*/
Object[] fetchAnyArray() throws DataAccessException;
/**
* Map resulting records onto a custom type.
*
* This is the same as calling
* E result = null;
* Record r = q.fetchAny();
*
* if (r != null)
* result = r.into(type);
*
. See {@link Record#into(Class)} for more details
*
* @param The generic entity type.
* @param type The entity type.
* @return The resulting record or null
if the query returns no
* records.
* @see Record#into(Class)
* @see Result#into(Class)
* @throws DataAccessException if something went wrong executing the query
* @throws MappingException wrapping any reflection or data type conversion
* exception that might have occurred while mapping records
* @see DefaultRecordMapper
*/
E fetchAnyInto(Class extends E> type) throws DataAccessException, MappingException;
/**
* Map resulting records onto a custom record.
*
* This is the same as calling
* Z result = null;
* Record r = q.fetchOne();
*
* if (r != null)
* result = r.into(table);
*
. See {@link Record#into(Table)} for more details
*
* The resulting record is attached to the original {@link Configuration} by
* default. Use {@link Settings#isAttachRecords()} to override this
* behaviour.
*
* @param The generic table record type.
* @param table The table type.
* @return The resulting record or null
if the query returns no
* records.
* @see Record#into(Table)
* @see Result#into(Table)
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the query returned more than one record
*/
Z fetchAnyInto(Table table) throws DataAccessException, InvalidResultException;
/**
* Execute the query and return the generated result as a list of name/value
* maps.
*
* @return The result.
* @throws DataAccessException if something went wrong executing the query
* @throws InvalidResultException if the key field returned two or more
* equal values from the result set.
* @see Result#intoMaps()
* @see Record#intoMap()
*/
List