From 332f2df64de0229eaa79d87ea667f2ef28d6afad Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Sun, 18 Sep 2011 15:14:20 +0000 Subject: [PATCH] Added some sections to the manual --- jOOQ-website/css/jooq.css | 7 - jOOQ-website/frame.php | 3 +- jOOQ-website/manual/DSL/SELECT/index.php | 273 ++++++++++++++++++- jOOQ-website/src/main/resources/manual.xml | 295 +++++++++++++++++++++ 4 files changed, 567 insertions(+), 11 deletions(-) diff --git a/jOOQ-website/css/jooq.css b/jOOQ-website/css/jooq.css index 8aad0c307f..b185521ad7 100644 --- a/jOOQ-website/css/jooq.css +++ b/jOOQ-website/css/jooq.css @@ -16,13 +16,6 @@ body { padding: 0; } -hr { - border: 0; - height: 5px; - color: #000; - background-color: #000; -} - h1, h2, h3, h4, h5, h6 { font-family: 'Georgia',Serif; font-weight: normal; diff --git a/jOOQ-website/frame.php b/jOOQ-website/frame.php index bc247ed8bd..3b52c689f6 100644 --- a/jOOQ-website/frame.php +++ b/jOOQ-website/frame.php @@ -83,9 +83,8 @@ diff --git a/jOOQ-website/manual/DSL/SELECT/index.php b/jOOQ-website/manual/DSL/SELECT/index.php index 214ffca0d4..67ffd71c96 100644 --- a/jOOQ-website/manual/DSL/SELECT/index.php +++ b/jOOQ-website/manual/DSL/SELECT/index.php @@ -7,7 +7,12 @@ function printH1() { print "Complete SELECT syntax"; } function getSlogan() { - return ""; + return " + A SELECT statement is more than just the R in CRUD. It allows for + transforming your relational data into any other form using concepts + such as equi-join, semi-join, anti-join, outer-join and much more. jOOQ + helps you think in precisely those relational concepts. + "; } function printContent() { global $root; @@ -16,7 +21,271 @@ function printContent() { The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Complete SELECT syntaxprevious : next -
+
+

SELECT from anonymous or ad-hoc types

+

When you don't just perform CRUD (i.e. SELECT * FROM your_table WHERE ID = ?), + you're usually generating new types using custom projections. With jOOQ, this is + as intuitive, as if using SQL directly. A more or less complete example of the "standard" SQL syntax, plus + some extensions, is provided by a query like this: +

+ +
+-- get all authors' first and last names, and the number 
+-- of books they've written in German, if they have written
+-- more than five books in German in the last three years 
+-- (from 2011), and sort those authors by last names
+-- limiting results to the second and third row, locking
+-- the rows for a subsequent update... whew!
+
+  SELECT T_AUTHOR.FIRST_NAME, T_AUTHOR.LAST_NAME, COUNT(*)
+    FROM T_AUTHOR
+    JOIN T_BOOK ON T_AUTHOR.ID = T_BOOK.AUTHOR_ID
+   WHERE T_BOOK.LANGUAGE = 'DE'
+     AND T_BOOK.PUBLISHED > '2008-01-01'
+GROUP BY T_AUTHOR.FIRST_NAME, T_AUTHOR.LAST_NAME
+  HAVING COUNT(*) > 5
+ORDER BY T_AUTHOR.LAST_NAME ASC NULLS FIRST
+   LIMIT 2 
+  OFFSET 1
+     FOR UPDATE
+ +

So that's daily business. How to do it with jOOQ: When you first create a SELECT statement using the Factory's select() methods

+
+SelectFromStep select(Field<?>... fields);
+
+// Example:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count());
+ +

+ jOOQ will return an "intermediary" type to you, representing the + SELECT statement about to be created (by the way, check out the + section on aggregate operators + to learn more about the COUNT(*) + function). This type is the + org.jooq.SelectFromStep. + When you have a reference + to this type, you may add a FROM clause, although that clause is + optional. This is reflected by the fact, that the SelectFromStep type + extends + org.jooq.SelectJoinStep, + which allows for adding the subsequent + clauses. Let's say you do decide to add a FROM clause, then you can + use this method for instance: +

+
+SelectJoinStep from(TableLike<?>... table);
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR);
+ +

After adding the table-like structures (mostly just Tables) to + select from, you may optionally choose to add a JOIN clause, as the + type returned by jOOQ is the step where you can add JOINs. Again, + adding these clauses is optional, as the + org.jooq.SelectJoinStep extends + org.jooq.SelectWhereStep. + But let's say we add a JOIN:

+
+// These join types are supported
+SelectOnStep                    join(Table<?> table);
+SelectOnStep           leftOuterJoin(Table<?> table);
+SelectOnStep          rightOuterJoin(Table<?> table);
+SelectOnStep           fullOuterJoin(Table<?> table);
+SelectJoinStep             crossJoin(Table<?> table);
+SelectJoinStep           naturalJoin(Table<?> table);
+SelectJoinStep  naturalLeftOuterJoin(Table<?> table);
+SelectJoinStep naturalRightOuterJoin(Table<?> table);
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR)
+      .join(T_BOOK);
+ +

Now, if you do add a JOIN clause, you have to specify the JOIN .. ON + condition before you can add more clauses. That's not an optional step + for some JOIN types. This is reflected by the fact that + org.jooq.SelectOnStep + is a top-level interface.

+ +
+// These join conditions are supported
+SelectJoinStep    on(Condition... conditions);
+SelectJoinStep using(Field<?>... fields);
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR)
+      .join(T_BOOK).on(TBook.AUTHOR_ID.equal(TAuthor.ID));
+ +

See the section about + Conditions + to learn more about the many ways + to create Conditions in jOOQ. Now we're half way through. As you can + see above, we're back to the SelectJoinStep. This means, we can + re-iterate and add another JOIN clause, just like in SQL. Or we go on + to the next step, adding conditions in the + org.jooq.SelectWhereStep:

+
+SelectConditionStep where(Condition... conditions);
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR)
+      .join(T_BOOK).on(TBook.AUTHOR_ID.equal(TAuthor.ID))
+      .where(TBook.LANGUAGE.equal("DE"));
+ +

Now the returned type + org.jooq.SelectConditionStep is a special one, where + you can add more conditions to the already existing WHERE clause. + Every time you add a condition, you will return to that + SelectConditionStep, as the number of additional conditions is + unlimited. Note that of course you can also just add a single combined + condition, if that is more readable or suitable for your use-case. + Here's how we add another condition:

+
+SelectConditionStep and(Condition condition);
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR)
+      .join(T_BOOK).on(TBook.AUTHOR_ID.equal(TAuthor.ID))
+      .where(TBook.LANGUAGE.equal("DE"))
+      .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')));
+ +

Let's assume we have that method parseDate() creating a + java.sql.Date for us. + Then we'll continue adding the GROUP BY clause +

+
+SelectHavingStep groupBy(Field<?>... fields);
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR)
+      .join(T_BOOK).on(TBook.AUTHOR_ID.equal(TAuthor.ID))
+      .where(TBook.LANGUAGE.equal("DE"))
+      .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
+      .groupBy(TAuthor.FIRST_NAME, TAuthor.LAST_NAME);
+ +

and the HAVING clause:

+
+SelectOrderByStep having(Condition... conditions);
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR)
+      .join(T_BOOK).on(TBook.AUTHOR_ID.equal(TAuthor.ID))
+      .where(TBook.LANGUAGE.equal("DE"))
+      .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
+      .groupBy(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
+      .having(create.count().greaterThan(5));
+ +

and the ORDER BY clause. Some RDBMS support NULLS FIRST and NULLS + LAST extensions to the ORDER BY clause. If this is not supported by + the RDBMS, then the behaviour is simulated with an additional CASE + WHEN ... IS NULL THEN 1 ELSE 0 END clause.

+
+SelectLimitStep orderBy(Field<?>... fields);
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR)
+      .join(T_BOOK).on(TBook.AUTHOR_ID.equal(TAuthor.ID))
+      .where(TBook.LANGUAGE.equal("DE"))
+      .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
+      .groupBy(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
+      .having(create.count().greaterThan(5))
+      .orderBy(TAuthor.LAST_NAME.asc().nullsFirst());
+ +

and finally the LIMIT clause. Most dialects have a means of limiting + the number of result records (except Oracle). Some even support having + an OFFSET to the LIMIT clause. Even if your RDBMS does not support the + full LIMIT ... OFFSET ... clause, jOOQ + will simulate the LIMIT clause using nested selects and filtering on + ROWNUM (for Oracle), or on ROW_NUMBER() (for DB2 and SQL + Server):

+
+SelectFinalStep limit(int offset, int numberOfRows);
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR)
+      .join(T_BOOK).on(TBook.AUTHOR_ID.equal(TAuthor.ID))
+      .where(TBook.LANGUAGE.equal("DE"))
+      .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
+      .groupBy(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
+      .having(create.count().greaterThan(5))
+      .orderBy(TAuthor.LAST_NAME.asc().nullsFirst())
+      .limit(1, 2);
+ +

In the final step, there are some proprietary extensions available + only in some RDBMS. One of those extensions are the FOR UPDATE + (supported in most RDBMS) and FOR SHARE clauses (supported only in + MySQL and Postgres):

+
+SelectFinalStep forUpdate();
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR)
+      .join(T_BOOK).on(TBook.AUTHOR_ID.equal(TAuthor.ID))
+      .where(TBook.LANGUAGE.equal("DE"))
+      .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
+      .groupBy(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
+      .having(create.count().greaterThan(5))
+      .orderBy(TAuthor.LAST_NAME.asc().nullsFirst())
+      .limit(1, 2)
+      .forUpdate();
+ +

+ Now the most relevant super-type of the object we have just created is + org.jooq.Select<Record>. + This type can be reused in various expressions such as in the + UNION and other set operations, + Nested select statements using the EXISTS operator, + etc. If you just want to execute this select + statement, you can choose any of these methods as discussed in the + section about the ResultQuery: +

+ +
+// Just execute the query.
+int execute() throws SQLException;
+
+// Execute the query and retrieve the results
+Result<Record> fetch() throws SQLException;
+
+// Execute the query and retrieve the first Record
+Record fetchAny() throws SQLException;
+
+// Execute the query and retrieve the single Record
+// An Exception is thrown if more records were available
+Record fetchOne() throws SQLException;
+
+// [...]
+ + +

SELECT from single physical tables

+

A very similar API is available, if you want to select from single + physical tables in order to retrieve TableRecords or even + UpdatableRecords (see also the manual's section on + SelectQuery vs SimpleSelectQuery). + The decision, which type of select to create is + already made at the very first step, when you create the SELECT + statement with the Factory:

+ +
public <R extends Record> SimpleSelectWhereStep<R> selectFrom(Table<R> table);
+

As you can see, there is no way to further restrict/project the selected + fields. This just selects all known TableFields in the supplied Table, + and it also binds <R extends Record> to your Table's associated + Record. An example of such a Query would then be:

+
+TBook book = create.selectFrom(T_BOOK)
+                   .where(TBook.LANGUAGE.equal("DE"))
+                   .orderBy(TBook.TITLE)
+                   .fetchAny();
+
diff --git a/jOOQ-website/src/main/resources/manual.xml b/jOOQ-website/src/main/resources/manual.xml index be56d78079..a89f164539 100644 --- a/jOOQ-website/src/main/resources/manual.xml +++ b/jOOQ-website/src/main/resources/manual.xml @@ -2060,40 +2060,335 @@ create.select()
Complete SELECT syntax + + A SELECT statement is more than just the R in CRUD. It allows for + transforming your relational data into any other form using concepts + such as equi-join, semi-join, anti-join, outer-join and much more. jOOQ + helps you think in precisely those relational concepts. + + +

SELECT from anonymous or ad-hoc types

+

When you don't just perform CRUD (i.e. SELECT * FROM your_table WHERE ID = ?), + you're usually generating new types using custom projections. With jOOQ, this is + as intuitive, as if using SQL directly. A more or less complete example of the "standard" SQL syntax, plus + some extensions, is provided by a query like this: +

+ +
+-- get all authors' first and last names, and the number 
+-- of books they've written in German, if they have written
+-- more than five books in German in the last three years 
+-- (from 2011), and sort those authors by last names
+-- limiting results to the second and third row, locking
+-- the rows for a subsequent update... whew!
+
+  SELECT T_AUTHOR.FIRST_NAME, T_AUTHOR.LAST_NAME, COUNT(*)
+    FROM T_AUTHOR
+    JOIN T_BOOK ON T_AUTHOR.ID = T_BOOK.AUTHOR_ID
+   WHERE T_BOOK.LANGUAGE = 'DE'
+     AND T_BOOK.PUBLISHED > '2008-01-01'
+GROUP BY T_AUTHOR.FIRST_NAME, T_AUTHOR.LAST_NAME
+  HAVING COUNT(*) > 5
+ORDER BY T_AUTHOR.LAST_NAME ASC NULLS FIRST
+   LIMIT 2 
+  OFFSET 1
+     FOR UPDATE
+ +

So that's daily business. How to do it with jOOQ: When you first create a SELECT statement using the Factory's select() methods

+
+SelectFromStep select(Field<?>... fields);
+
+// Example:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count());
+ +

+ jOOQ will return an "intermediary" type to you, representing the + SELECT statement about to be created (by the way, check out the + section on + to learn more about the COUNT(*) + function). This type is the + . + When you have a reference + to this type, you may add a FROM clause, although that clause is + optional. This is reflected by the fact, that the SelectFromStep type + extends + , + which allows for adding the subsequent + clauses. Let's say you do decide to add a FROM clause, then you can + use this method for instance: +

+
+SelectJoinStep from(TableLike<?>... table);
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR);
+ +

After adding the table-like structures (mostly just Tables) to + select from, you may optionally choose to add a JOIN clause, as the + type returned by jOOQ is the step where you can add JOINs. Again, + adding these clauses is optional, as the + extends + . + But let's say we add a JOIN:

+
+// These join types are supported
+SelectOnStep                    join(Table<?> table);
+SelectOnStep           leftOuterJoin(Table<?> table);
+SelectOnStep          rightOuterJoin(Table<?> table);
+SelectOnStep           fullOuterJoin(Table<?> table);
+SelectJoinStep             crossJoin(Table<?> table);
+SelectJoinStep           naturalJoin(Table<?> table);
+SelectJoinStep  naturalLeftOuterJoin(Table<?> table);
+SelectJoinStep naturalRightOuterJoin(Table<?> table);
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR)
+      .join(T_BOOK);
+ +

Now, if you do add a JOIN clause, you have to specify the JOIN .. ON + condition before you can add more clauses. That's not an optional step + for some JOIN types. This is reflected by the fact that + + is a top-level interface.

+ +
+// These join conditions are supported
+SelectJoinStep    on(Condition... conditions);
+SelectJoinStep using(Field<?>... fields);
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR)
+      .join(T_BOOK).on(TBook.AUTHOR_ID.equal(TAuthor.ID));
+ +

See the section about + + to learn more about the many ways + to create Conditions in jOOQ. Now we're half way through. As you can + see above, we're back to the SelectJoinStep. This means, we can + re-iterate and add another JOIN clause, just like in SQL. Or we go on + to the next step, adding conditions in the + :

+
+SelectConditionStep where(Condition... conditions);
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR)
+      .join(T_BOOK).on(TBook.AUTHOR_ID.equal(TAuthor.ID))
+      .where(TBook.LANGUAGE.equal("DE"));
+ +

Now the returned type + is a special one, where + you can add more conditions to the already existing WHERE clause. + Every time you add a condition, you will return to that + SelectConditionStep, as the number of additional conditions is + unlimited. Note that of course you can also just add a single combined + condition, if that is more readable or suitable for your use-case. + Here's how we add another condition:

+
+SelectConditionStep and(Condition condition);
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR)
+      .join(T_BOOK).on(TBook.AUTHOR_ID.equal(TAuthor.ID))
+      .where(TBook.LANGUAGE.equal("DE"))
+      .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')));
+ +

Let's assume we have that method parseDate() creating a + for us. + Then we'll continue adding the GROUP BY clause +

+
+SelectHavingStep groupBy(Field<?>... fields);
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR)
+      .join(T_BOOK).on(TBook.AUTHOR_ID.equal(TAuthor.ID))
+      .where(TBook.LANGUAGE.equal("DE"))
+      .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
+      .groupBy(TAuthor.FIRST_NAME, TAuthor.LAST_NAME);
+ +

and the HAVING clause:

+
+SelectOrderByStep having(Condition... conditions);
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR)
+      .join(T_BOOK).on(TBook.AUTHOR_ID.equal(TAuthor.ID))
+      .where(TBook.LANGUAGE.equal("DE"))
+      .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
+      .groupBy(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
+      .having(create.count().greaterThan(5));
+ +

and the ORDER BY clause. Some RDBMS support NULLS FIRST and NULLS + LAST extensions to the ORDER BY clause. If this is not supported by + the RDBMS, then the behaviour is simulated with an additional CASE + WHEN ... IS NULL THEN 1 ELSE 0 END clause.

+
+SelectLimitStep orderBy(Field<?>... fields);
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR)
+      .join(T_BOOK).on(TBook.AUTHOR_ID.equal(TAuthor.ID))
+      .where(TBook.LANGUAGE.equal("DE"))
+      .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
+      .groupBy(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
+      .having(create.count().greaterThan(5))
+      .orderBy(TAuthor.LAST_NAME.asc().nullsFirst());
+ +

and finally the LIMIT clause. Most dialects have a means of limiting + the number of result records (except Oracle). Some even support having + an OFFSET to the LIMIT clause. Even if your RDBMS does not support the + full LIMIT ... OFFSET ... clause, jOOQ + will simulate the LIMIT clause using nested selects and filtering on + ROWNUM (for Oracle), or on ROW_NUMBER() (for DB2 and SQL + Server):

+
+SelectFinalStep limit(int offset, int numberOfRows);
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR)
+      .join(T_BOOK).on(TBook.AUTHOR_ID.equal(TAuthor.ID))
+      .where(TBook.LANGUAGE.equal("DE"))
+      .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
+      .groupBy(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
+      .having(create.count().greaterThan(5))
+      .orderBy(TAuthor.LAST_NAME.asc().nullsFirst())
+      .limit(1, 2);
+ +

In the final step, there are some proprietary extensions available + only in some RDBMS. One of those extensions are the FOR UPDATE + (supported in most RDBMS) and FOR SHARE clauses (supported only in + MySQL and Postgres):

+
+SelectFinalStep forUpdate();
+
+// The example, continued:
+create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count())
+      .from(T_AUTHOR)
+      .join(T_BOOK).on(TBook.AUTHOR_ID.equal(TAuthor.ID))
+      .where(TBook.LANGUAGE.equal("DE"))
+      .and(TBook.PUBLISHED.greaterThan(parseDate('2008-01-01')))
+      .groupBy(TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
+      .having(create.count().greaterThan(5))
+      .orderBy(TAuthor.LAST_NAME.asc().nullsFirst())
+      .limit(1, 2)
+      .forUpdate();
+ +

+ Now the most relevant super-type of the object we have just created is + <Record>. + This type can be reused in various expressions such as in the + , + , + etc. If you just want to execute this select + statement, you can choose any of these methods as discussed in the + section about the : +

+ +
+// Just execute the query.
+int execute() throws SQLException;
+
+// Execute the query and retrieve the results
+Result<Record> fetch() throws SQLException;
+
+// Execute the query and retrieve the first Record
+Record fetchAny() throws SQLException;
+
+// Execute the query and retrieve the single Record
+// An Exception is thrown if more records were available
+Record fetchOne() throws SQLException;
+
+// [...]
+ + +

SELECT from single physical tables

+

A very similar API is available, if you want to select from single + physical tables in order to retrieve TableRecords or even + UpdatableRecords (see also the manual's section on + ). + The decision, which type of select to create is + already made at the very first step, when you create the SELECT + statement with the Factory:

+ +
public <R extends Record> SimpleSelectWhereStep<R> selectFrom(Table<R> table);
+

As you can see, there is no way to further restrict/project the selected + fields. This just selects all known TableFields in the supplied Table, + and it also binds <R extends Record> to your Table's associated + Record. An example of such a Query would then be:

+
+TBook book = create.selectFrom(T_BOOK)
+                   .where(TBook.LANGUAGE.equal("DE"))
+                   .orderBy(TBook.TITLE)
+                   .fetchAny();
+
+ +
Conditions
+ +
Aliased tables and fields
+ +
Nested select statements using the IN operator
+ +
Nested select statements using the EXISTS operator
+ +
Other types of nested selects
+ +
UNION and other set operations
+ +
Functions, aggregate operators, and window functions
+ +
Stored procedures and functions
+ +
Arithmetic operations
+ +
The CASE clause
+ +
Type casting
+ +
When it's just much easier: Plain SQL
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Complete SELECT syntaxprevious : next