From 41aefee8e8dff1a16305efd1636dfc8904cd0147 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Wed, 18 Mar 2020 11:37:46 +0100 Subject: [PATCH] [jOOQ/jOOQ#9851] Rewrite ResultQuery Javadoc --- jOOQ/src/main/java/org/jooq/ResultQuery.java | 74 ++++++++++++++------ 1 file changed, 54 insertions(+), 20 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/ResultQuery.java b/jOOQ/src/main/java/org/jooq/ResultQuery.java index efd9569662..8389583307 100644 --- a/jOOQ/src/main/java/org/jooq/ResultQuery.java +++ b/jOOQ/src/main/java/org/jooq/ResultQuery.java @@ -66,35 +66,69 @@ import org.jooq.exception.InvalidResultException; import org.jooq.exception.MappingException; import org.jooq.exception.NoDataFoundException; import org.jooq.exception.TooManyRowsException; -import org.jooq.impl.DSL; import org.jooq.impl.DefaultRecordMapper; /** - * A query that can return results. Mostly, this is a {@link Select} query used - * for a SELECT statement. + * A query that can return results. *

- *

Lifecycle guarantees

+ * jOOQ distinguishes between ordinary {@link Query} types, such as + * {@link Insert}, {@link Update}, {@link Delete}, and any {@link DDLQuery}, + * which are meant to produce side effects in a database, and the + * {@link ResultQuery}, which is meant to produce a {@link Result} through + * various means. *

- * 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. + * The most common way to create a result is by calling {@link #fetch()}, or by + * using the query's {@link #iterator()} method in a foreach loop: *

- * In order to keep open {@link ResultSet}s and fetch records lazily, use - * {@link #fetchLazy()} instead and then operate on {@link Cursor}. + *

+ * Result<TRecord> result = ctx.select(T.A, T.B).from(T).fetch();
+ *
+ * for (TRecord record : ctx.select(T.A, T.B).from(T)) {
+ *   // ...
+ * }
+ * 
*

- *

Performance

+ * Most approaches to fetching results in {@link ResultQuery} (including the + * above), fetch the entire JDBC {@link ResultSet} eagerly into memory, which + * allows for closing the underlying JDBC resources as quickly as possible. Such + * operations are not resourceful, i.e. users do not need to worry about closing + * any resources. *

- * Methods throwing {@link TooManyRowsException} need to retrieve at most two - * records from the underlying JDBC {@link ResultSet}, which, depending on the - * {@link java.sql.Statement#getFetchSize()} / - * {@link ResultQuery#fetchSize(int)}, might incur additional database - * roundtrips. If this causes problems, {@link ResultQuery#fetchAny()} may be - * preferred. + * There are, however, some ways of fetching results lazily, and thus in a + * resourceful way. These include: + *

+ *

+ * In both cases, it is recommended to explicitly close the underlying resources + * (i.e. JDBC {@link ResultSet}) using try-with-resources: + *

+ *

+ * try (Cursor<TRecord> cursor = ctx.select(T.A, T.B).from(T).fetchLazy()) {
+ *   for (;;) {
+ *     TRecord record = cursor.fetchNext();
+ *     if (record == null)
+ *       break;
+ *
+ *     // ...
+ *   }
+ * }
+ *
+ * try (Stream<TRecord> stream = ctx.select(T.A, T.B).from(T).fetchStream()) {
+ *   stream.forEach(record -> {
+ *     // ...
+ *   });
+ * }
+ * 
+ *

+ * While most instances of {@link ResultQuery} implement {@link Select}, there + * also exist other types of {@link ResultQuery} constructed e.g. from plain SQL + * APIs, such as {@link DSLContext#resultQuery(String)}. *

- * Instances can be created using {@link DSL#resultQuery(String)} and overloads, - * or by creating a subtype. * * @author Lukas Eder */