diff --git a/jOOQ-website/src/main/resources/manual-3.0.xml b/jOOQ-website/src/main/resources/manual-3.0.xml
index 9bcaa87e5a..d757ee7430 100644
--- a/jOOQ-website/src/main/resources/manual-3.0.xml
+++ b/jOOQ-website/src/main/resources/manual-3.0.xml
@@ -1206,10 +1206,104 @@ SelectSelectStep
+ In advanced use cases of integrating your application with jOOQ, you may want to put custom data into your
+ Here is an example of how to use the custom data API. Let's assume that you have written an
+ See the manual's section about
+ Now, the above listener can be added to your
+ Using the
+
+ ExecuteListeners are hooked into your
+ See the manual's section about
- The SQL standard specifies a FOR UPDATE clause to be applicable for cursors. Most databases interpret this as being applicable for all SELECT statements. An exception to this rule are the CUBRID and SQL Server databases, that do not allow for any FOR UPDATE clause in a regular SQL SELECT statement. jOOQ simulates the FOR UPDATE behaviour, by locking record by record with JDBC. JDBC allows for specifying the flags TYPE_SCROLL_SENSITIVE, CONCUR_UPDATABLE for any statement, and then using ResultSet.updateXXX() methods to produce a cell-lock / row-lock. Here's a simplified example in JDBC:
+ The SQL standard specifies a
+
+
+ INSERT statements, when a given flag is set to true:
+ ExecuteListener.
+ Executor, in order for the listener to work:
+ getData() and setData() methods, you can store and retrieve custom data in your Executors and Configurations.
+ ExecuteListeners are a useful tool to...
+
+
+
+ getExecuteListeners() property:
+ FOR UPDATE in CUBRID and SQL Server
FOR UPDATE clause to be applicable for cursors. Most databases interpret this as being applicable for all SELECT statements. An exception to this rule are the CUBRID and SQL Server databases, that do not allow for any FOR UPDATE clause in a regular SQL SELECT statement. jOOQ simulates the FOR UPDATE behaviour, by locking record by record with JDBC. JDBC allows for specifying the flags TYPE_SCROLL_SENSITIVE, CONCUR_UPDATABLE for any statement, and then using ResultSet.updateXXX() methods to produce a cell-lock / row-lock. Here's a simplified example in JDBC:
FOR SHARE clause
- Some databases (MySQL, Postgres) also allow to issue a non-exclusive lock explicitly using a FOR SHARE clause. This is also supported by jOOQ
+ Some databases (MySQL, Postgres) also allow to issue a non-exclusive lock explicitly using a FOR SHARE clause. This is also supported by jOOQ
- These operators combine two results into one. While UNION removes all duplicate records resulting from this combination, UNION ALL leaves subselect results as they are. Typically, you should prefer UNION ALL over UNION, if you don't really need to remove duplicates. The following example shows how to use such a UNION operation in jOOQ.
+ These operators combine two results into one. While UNION removes all duplicate records resulting from this combination, UNION ALL leaves subselect results as they are. Typically, you should prefer UNION ALL over UNION, if you don't really need to remove duplicates. The following example shows how to use such a UNION operation in jOOQ.
- INTERSECT is the operation that produces only those values that are returned by both subselects. EXCEPT is the operation that returns only those values that are returned exclusively in the first subselect. Both operators will remove duplicates from their results. The SQL standard allows to specify the ALL keyword for both of these operators as well, but this is hardly supported in any database. jOOQ does not support INTERSECT ALL, EXEPT ALL operations either.
+ INTERSECT is the operation that produces only those values that are returned by both subselects. EXCEPT is the operation that returns only those values that are returned exclusively in the first subselect. Both operators will remove duplicates from their results. The SQL standard allows to specify the ALL keyword for both of these operators as well, but this is hardly supported in any database. jOOQ does not support INTERSECT ALL, EXEPT ALL operations either.
- If you are closely coupling your application to an Oracle (or CUBRID) database, you might need to be able to pass hints of the form /*+HINT*/ with your SQL statements to the Oracle database. For example:
+ If you are closely coupling your application to an Oracle (or CUBRID) database, you might need to be able to pass hints of the form /*+HINT*/ with your SQL statements to the Oracle database. For example:
- This can be done in jOOQ using the .hint() clause in your SELECT statement:
+ This can be done in jOOQ using the .hint() clause in your SELECT statement:
- Note that you can pass any string in the .hint() clause. If you use that clause, the passed string will always be put in between the SELECT [DISTINCT] keywords and the actual projection list. This can be useful in other databases too, such as MySQL, for instance:
+ Note that you can pass any string in the .hint() clause. If you use that clause, the passed string will always be put in between the SELECT [DISTINCT] keywords and the actual projection list. This can be useful in other databases too, such as MySQL, for instance:
+ SQL has a lexical and a logical order of SELECT clauses. The lexical order of SELECT clauses is inspired by the English language. As SQL statements are commands for the database, it is natural to express a statement in an imperative tense, such as "SELECT this and that!".
+
+ The logical order of SELECT clauses, however, does not correspond to the syntax. In fact, the logical order is this:
+
SELECT DISTINCT statement, data is further reduced to remove duplicatesUNION-connected subqueries. Unless this is a UNION ALL clause, data is further reduced to remove duplicates+ The SQL Server documentation also explains this, with slightly different clauses: +
+ +FROMONJOINWHEREGROUP BYWITH CUBE or WITH ROLLUPHAVINGSELECTDISTINCTORDER BYTOP+ As can be seen, databases have to logically reorder a SQL statement in order to determine the best execution plan. +
+ +
+ Some "higher-level" abstractions, such as C#'s LINQ or Scala's SLICK try to inverse the lexical order of SELECT clauses to what appears to be closer to the logical order. The obvious advantage of moving the SELECT clause to the end is the fact that the projection type, which is the record type returned by the SELECT statement can be re-used more easily in the target environment of the internal domain specific language.
+
+ A LINQ example: +
++ A SLICK example: +
+ +
+ While this looks like a good idea at first, it only complicates translation to more advanced SQL statements while impairing readability for those users that are used to writing SQL. jOOQ is designed to look just like SQL. This is specifically true for SLICK, which not only changed the SELECT clause order, but also heavily "integrated" SQL clauses with the Scala language.
+
+ For these reasons, the jOOQ DSL API is modelled in SQL's lexical order. +
+
- The INSERT statement is used to insert new records into a database table. Records can either be supplied using a VALUES() constructor, or a SELECT statement. jOOQ supports both types of INSERT statements. An example of an INSERT statement using a VALUES() constructor is given here:
+ The INSERT statement is used to insert new records into a database table. Records can either be supplied using a VALUES() constructor, or a SELECT statement. jOOQ supports both types of INSERT statements. An example of an INSERT statement using a VALUES() constructor is given here:
+ Some databases allow for expressing in-memory temporary tables using a VALUES() constructor. This constructor usually works the same way as the VALUES() clause known from the VALUES() table constructor, to create tables that can be used in a
+ Note, that it is usually quite useful to provide column aliases ("derived column lists") along with the table alias for the VALUES() constructor.
+
+ The above statement is simulated by jOOQ for those databases that do not support the VALUES() constructor, natively (actual simulations may vary):
+
+ All of jOOQ's
null, if the record was never in the databaseRecord API.
+ The purpose of the above information is for jOOQ's
+ Since jOOQ 3.0, a simple wrapping API has been added to wrap JDBC's rather awkward