From 924e057eeb382f4cc58b89d038cb6007f06dac32 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Fri, 10 Aug 2012 19:22:26 +0200 Subject: [PATCH] [#1657] Reorganise the manual (62 / 153) --- .../src/main/resources/manual-2.5.xml | 386 +++++++++++++++--- 1 file changed, 339 insertions(+), 47 deletions(-) diff --git a/jOOQ-website/src/main/resources/manual-2.5.xml b/jOOQ-website/src/main/resources/manual-2.5.xml index 15e1848544..d5aad1c0e7 100644 --- a/jOOQ-website/src/main/resources/manual-2.5.xml +++ b/jOOQ-website/src/main/resources/manual-2.5.xml @@ -75,13 +75,13 @@

For the examples in this manual, the same database will always be referred to. It essentially consists of these entities created using the Oracle dialect

-CREATE TABLE t_language ( +CREATE TABLE language ( id NUMBER(7) NOT NULL PRIMARY KEY, cd CHAR(2) NOT NULL, description VARCHAR2(50) ) -CREATE TABLE t_author ( +CREATE TABLE author ( id NUMBER(7) NOT NULL PRIMARY KEY, first_name VARCHAR2(50), last_name VARCHAR2(50) NOT NULL, @@ -89,32 +89,32 @@ CREATE TABLE t_author ( year_of_birth NUMBER(7) ) -CREATE TABLE t_book ( +CREATE TABLE book ( id NUMBER(7) NOT NULL PRIMARY KEY, author_id NUMBER(7) NOT NULL, title VARCHAR2(400) NOT NULL, published_in NUMBER(7) NOT NULL, language_id NUMBER(7) NOT NULL, - FOREIGN KEY (AUTHOR_ID) REFERENCES T_AUTHOR(ID), - FOREIGN KEY (LANGUAGE_ID) REFERENCES T_LANGUAGE(ID) + FOREIGN KEY (AUTHOR_ID) REFERENCES author(ID), + FOREIGN KEY (LANGUAGE_ID) REFERENCES language(ID) ) -CREATE TABLE t_book_store ( +CREATE TABLE book_store ( name VARCHAR2(400) NOT NULL UNIQUE ) -CREATE TABLE t_book_to_book_store ( +CREATE TABLE book_to_book_store ( book_store_name VARCHAR2(400) NOT NULL, book_id INTEGER NOT NULL, stock INTEGER, PRIMARY KEY(book_store_name, book_id), CONSTRAINT b2bs_book_store_id FOREIGN KEY (book_store_name) - REFERENCES t_book_store (name) + REFERENCES book_store (name) ON DELETE CASCADE, CONSTRAINT b2bs_book_id FOREIGN KEY (book_id) - REFERENCES t_book (id) + REFERENCES book (id) ON DELETE CASCADE )

@@ -815,28 +815,29 @@ MySQLFactory create = new MySQLFactory(connection);

Here is an example to illustrate what that means:

+ 1920 AND a.first_name = 'Paulo' ORDER BY b.title]]> result = create.select() - .from(T_AUTHOR.as("a")) - .join(T_BOOK.as("b")).on(a.ID.equal(b.AUTHOR_ID)) + .from(AUTHOR.as("a")) + .join(BOOK.as("b")).on(a.ID.equal(b.AUTHOR_ID)) .where(a.YEAR_OF_BIRTH.greaterThan(1920) .and(a.FIRST_NAME.equal("Paulo"))) .orderBy(b.TITLE) .fetch();]]>

- We'll see how the aliasing works later in the section about + We'll see how the aliasing works later in the section about

-

jOOQ as an internal domain specific language in Java

+

jOOQ as an internal domain specific language in Java (a.k.a. the DSL-API)

Many other frameworks have similar APIs with similar feature sets. Yet, what makes jOOQ special is its informal modelling a unified SQL dialect suitable for many vendor-specific dialects, and implementing that BNF notation as a hierarchy of interfaces in Java. This concept is extremely powerful, when with syntax completion. Not only can you code much faster, your SQL code will be compile-checked to a certain extent. An example of a DSL query equivalent to the previous one is given here:

@@ -867,7 +868,7 @@ Result result = create.select(rowNumber()) .from(AUTHOR) .fetch();]]> -

History of SQL building and incremental query building

+

History of SQL building and incremental query building (a.k.a. the non-DSL API)

Historically, jOOQ started out as an object-oriented SQL builder library like any other. This meant that all queries and their syntactic components were modeled as so-called , which delegate and to child components. This part of the API will be referred to as the non-DSL API, which is still maintained and used internally by jOOQ for incremental query building. An example of incremental query building is given here:

@@ -1039,8 +1040,25 @@ create.selectOne().from(BOOK.as("b"), AUTHOR.as("a"));]]>

- Read more about aliasing in the manual's section about . + Read more about aliasing in the manual's section about .

+ +

More advanced table expressions

+

+ Apart from simple tables, you can pass any arbitrary to the jOOQ FROM clause. This may include in Oracle: +

+ + + + + + +

+ Note, in order to access the DbmsXplan package, you can use the to generate Oracle's SYS schema. +

+

Selecting FROM DUAL with jOOQ

@@ -1417,7 +1435,7 @@ ORDER BY AUTHOR_ID ASC, TITLE DESC]]>

Ordering by field index

- The SQL standard allows for specifying integer literals (, not !) to reference column indexes from the projection (). This may be useful if you do not want to repeat a lengthy expression, by which you want to order - although most databases also allow for referencing in the ORDER BY clause. An example of this is given here: + The SQL standard allows for specifying integer literals (, not !) to reference column indexes from the projection (). This may be useful if you do not want to repeat a lengthy expression, by which you want to order - although most databases also allow for referencing in the ORDER BY clause. An example of this is given here:

@@ -1670,7 +1688,48 @@ SELECT * FROM author ORDER BY id DESC;]]>
UNION, INTERSECTION and EXCEPT - + +

Standard SQL set operators to combine results

+

+ SQL allows to perform set operations as understood in standard set theory on result sets. These operations include unions, intersections, subtractions. For two subselects to be combinable by such a set operator, each subselect must return a of the same arity and type. +

+ +

UNION and UNION ALL

+

+ 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 [ ALL ] and EXCEPT [ ALL ]

+

+ INTERSECT is the operation that produces only those tuples that are returned by both subselects. EXCEPT is the operation that returns only those tuples 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. +

+ +

jOOQ's set operators and how they're different from standard SQL

+

+ As previously mentioned in the manual's section about the , jOOQ has slightly changed the semantics of these set operators. While in SQL, a subselect may not contain any or (unless you wrap the subselect into a ), jOOQ allows you to do so. In order to select both the youngest and the oldest author from the database, you can issue the following statement with jOOQ (rendered to the MySQL dialect): +

+ + + + + +
@@ -1737,6 +1796,48 @@ SELECT * FROM author ORDER BY id DESC;]]>
+
+ Aliased Tables + +

The strength of the code generator with respect to aliasing

+

+ The strength of jOOQ's becomes more obvious when you perform table aliasing and dereference fields from generated aliased tables. This can best be shown by example: +

+ + 1920 + AND a.first_name = 'Paulo' + ORDER BY b.title]]> + + +

+ As you can see in the above example, calling as() on generated tables returns an object of the same type as the table. This means that the resulting object can be used to dereference fields from the aliased table. This is quite powerful in terms of having your Java compiler check the syntax of your SQL statements. If you remove a column from a table, dereferencing that column from that table alias will cause compilation errors. +

+ +

Dereferencing columns from other table expressions

+

+ TODO document this +

+
+
+
Joined tables @@ -1748,8 +1849,21 @@ SELECT * FROM author ORDER BY id DESC;]]>
- PIVOT tables - + The Oracle 11g PIVOT clause + +

PIVOT (aggregate FOR column IN (columns))

+

+ If you are closely coupling your application to an Oracle database, you can take advantage of some Oracle-specific features, such as the PIVOT clause, used for statistical analyses. The formal syntax definition is as follows: +

+ +-- SELECT .. + FROM table PIVOT (aggregateFunction [, aggregateFunction] FOR column IN (expression [, expression])) +-- WHERE .. + +

+ The PIVOT clause is available from the type, as pivoting is done directly on a table. Currently, only Oracle's PIVOT clause is supported. Support for SQL Server's slightly different PIVOT clause will be added later. Also, jOOQ may simulate PIVOT for other dialects in the future. +

+
@@ -1805,7 +1919,31 @@ WHERE NOT EXISTS (
Array and cursor unnesting - + +

ARRAY and CURSOR types in more advanced databases

+

+ The SQL standard specifies how SQL databases should implement ARRAY and TABLE types, as well as CURSOR types. Put simply, a CURSOR is a pointer to any materialised . Depending on the cursor's features, this table expression can be scrolled through in both directions, records can be locked, updated, removed, inserted, etc. Often, CURSOR types contain tuples, whereas ARRAY and TABLE types contain simple scalar values, although that is not a requirement +

+ +

+ ARRAY types in SQL are similar to Java's array types. They contain a "component type" or "element type" and a "dimension". This sort of ARRAY type is implemented in H2, HSQLDB and Postgres and supported by jOOQ as such. Oracle uses strongly-typed arrays, which means that an ARRAY type (VARRAY or TABLE type) has a name and possibly a maximum capacity associated with it. +

+ +

Unnesting array and cursor types

+

+ The real power of these types become more obvious when you fetch them from to unnest them as and use them in your . An example is given here, where Oracle's DBMS_XPLAN package is used to fetch a cursor containing data about the most recent execution plan: +

+ + + + + +

+ Note, in order to access the DbmsXplan package, you can use the to generate Oracle's SYS schema. +

+
@@ -1892,11 +2030,31 @@ Field field4 = listAgg(BOOK.TITLE)
Table columns - + +

Table columns

+

+ Table columns are the most simple implementations of a . They are mainly produced by jOOQ's and can be dereferenced from the generated tables. This manual is full of examples involving table columns. Another example is given in this query: +

+ + + + + + +

+ Table columns implement a more specific interface called , which is parameterised with its associated <R extends Record> record type. +

+
-
- Aliasing +
+ Aliased columns
@@ -1913,7 +2071,7 @@ Field field4 = listAgg(BOOK.TITLE) -- Let's say, your Postgres column LAST_NAME was VARCHAR(30) -- Then you could do this: -SELECT CAST(T_AUTHOR.LAST_NAME AS TEXT) FROM DUAL +SELECT CAST(AUTHOR.LAST_NAME AS TEXT) FROM DUAL

in jOOQ, you can write something like that: @@ -2017,19 +2175,152 @@ create.select(concat("A", "B", "C"));

+
+ General functions + +

General functions supported by jOOQ

+

+ There are a variety of general functions supported by jOOQ As discussed in the chapter about functions are mostly simulated in your database, in case they are not natively supported. +

+

+ This is a list of general functions supported by jOOQ's : +

+
    +
  • COALESCE: Get the first non-null value in a list of arguments.
  • +
  • NULLIF: Return NULL if both arguments are equal, or the first argument, otherwise.
  • +
  • NVL: Get the first non-null value among two arguments.
  • +
  • NVL2: Get the second argument if the first is null, or the third argument, otherwise.
  • +
+ +

+ Please refer to the for more details. +

+
+
+
Numeric functions - + +

Numeric functions supported by jOOQ

+

+ Math can be done efficiently in the database before returning results to your Java application. In addition to the discussed previously, jOOQ also supports a variety of numeric functions. As discussed in the chapter about numeric functions (as any function type) are mostly simulated in your database, in case they are not natively supported. +

+

+ This is a list of numeric functions supported by jOOQ's : +

+ +
    +
  • ABS: Get the absolute value of a value.
  • +
  • ACOS: Get the arc cosine of a value.
  • +
  • ASIN: Get the arc sine of a value.
  • +
  • ATAN: Get the arc tangent of a value.
  • +
  • ATAN2: Get the atan2 function of two values.
  • +
  • CEIL: Get the smalles integer value larger than a given numeric value.
  • +
  • COS: Get the cosine of a value.
  • +
  • COSH: Get the hyperbolic cosine of a value.
  • +
  • COT: Get the cotangent of a value.
  • +
  • COTH: Get the hyperbolic cotangent of a value.
  • +
  • DEG: Transform radians into degrees.
  • +
  • EXP: Calculate e^value.
  • +
  • FLOOR: Get the largest integer value smaller than a given numeric value.
  • +
  • GREATEST: Finds the greatest among all argument values (can also be used with non-numeric values).
  • +
  • LEAST: Finds the least among all argument values (can also be used with non-numeric values).
  • +
  • LN: Get the natural logarithm of a value.
  • +
  • LOG: Get the logarithm of a value given a base.
  • +
  • POWER: Calculate value^exponent.
  • +
  • RAD: Transform degrees into radians.
  • +
  • ROUND: Rounds a value to the nearest integer.
  • +
  • SIGN: Get the sign of a value (-1, 0, 1).
  • +
  • SIN: Get the sine of a value.
  • +
  • SINH: Get the hyperbolic sine of a value.
  • +
  • SQRT: Calculate the square root of a value.
  • +
  • TAN: Get the tangent of a value.
  • +
  • TANH: Get the hyperbolic tangent of a value.
  • +
  • TRUNC: Truncate the decimals off a given value.
  • +
+ +

+ Please refer to the for more details. +

+
Bitwise functions - + +

Bitwise functions supported by jOOQ

+

+ Interestingly, bitwise functions and bitwise arithmetic is not very popular among SQL databases. Most databases only support a few bitwise operations, while others ship with the full set of operators. jOOQ's API includes most bitwise operations as listed below. In order to avoid ambiguities with , all bitwise functions are prefixed with "bit" +

+
    +
  • BIT_COUNT: Count the number of bits set to 1 in a number
  • +
  • BIT_AND: Set only those bits that are set in two numbers
  • +
  • BIT_OR: Set all bits that are set in at least one number
  • +
  • BIT_NAND: Set only those bits that are set in two numbers, and inverse the result
  • +
  • BIT_NOR: Set all bits that are set in at least one number, and inverse the result
  • +
  • BIT_NOT: Inverse the bits in a number
  • +
  • BIT_XOR: Set all bits that are set in at exactly one number
  • +
  • BIT_XNOR: Set all bits that are set in at exactly one number, and inverse the result
  • +
  • SHL: Shift bits to the left
  • +
  • SHR: Shift bits to the right
  • +
+ +

Some background about bitwise operation simulation

+

+ As stated before, not all databases support all of these bitwise operations. jOOQ simulates them wherever this is possible. More details can be seen in this blog post:
+ http://blog.jooq.org/2011/10/30/the-comprehensive-sql-bitwise-operations-compatibility-list/ +

+ +
String functions - + +

String functions supported by jOOQ

+

+ String formatting can be done efficiently in the database before returning results to your Java application. As discussed in the chapter about string functions (as any function type) are mostly simulated in your database, in case they are not natively supported. +

+

+ This is a list of numeric functions supported by jOOQ's : +

+ +
    +
  • ASCII: Get the ASCII code of a character.
  • +
  • BIT_LENGTH: Get the length of a string in bits.
  • +
  • CHAR_LENGTH: Get the length of a string in characters.
  • +
  • CONCAT: Concatenate several strings.
  • +
  • ESCAPE: Escape a string for use with the .
  • +
  • LENGTH: Get the length of a string.
  • +
  • LOWER: Get a string in lower case letters.
  • +
  • LPAD: Pad a string on the left side.
  • +
  • LTRIM: Trim a string on the left side.
  • +
  • OCTET_LENGTH: Get the length of a string in octets.
  • +
  • POSITION: Find a string within another string.
  • +
  • REPEAT: Repeat a string a given number of times.
  • +
  • REPLACE: Replace a string within another string.
  • +
  • RPAD: Pad a string on the right side.
  • +
  • RTRIM: Trim a string on the right side.
  • +
  • SUBSTRING: Get a substring of a string.
  • +
  • TRIM: Trim a string on both sides.
  • +
  • UPPER: Get a string in upper case letters.
  • +
+ +

+ Please refer to the for more details. +

+ +

Regular expressions, REGEXP, REGEXP_LIKE, etc.

+

+ Various databases have some means of searching through columns using regular expressions if the does not provide sufficient pattern matching power. While there are many different functions and operators in the various databases, jOOQ settled for the SQL:2008 standard REGEX_LIKE operator. Being an operator (and not a function), you should use the corresponding method on : +

+ + + +

+ Note that the SQL standard specifies that patterns should follow the XQuery standards. In the real world, the POSIX regular expression standard is the most used one, some use Java regular expressions, and only a few ones use Perl regular expressions. jOOQ does not make any assumptions about regular expression syntax. For cross-database compatibility, please read the relevant databaes manuals carefully, to learn about the appropriate syntax. Please refer to the for more details. +

+
@@ -2465,25 +2756,25 @@ GROUP BY A, B, C WITH ROLLUP

- @@ -2497,8 +2788,8 @@ create.decode().value(T_AUTHOR.FIRST_NAME) A CASE expression can be used anywhere where you can place a . For instance, you can SELECT the above expression, if you're selecting from AUTHOR:

-SELECT T_AUTHOR.FIRST_NAME, [... CASE EXPR ...] AS nationality - FROM T_AUTHOR +SELECT AUTHOR.FIRST_NAME, [... CASE EXPR ...] AS nationality + FROM AUTHOR

The Oracle DECODE() function

@@ -2512,9 +2803,9 @@ DECODE(FIRST_NAME, 'Paulo', 'brazilian', 'unknown'); -- Other SQL dialects -CASE T_AUTHOR.FIRST_NAME WHEN 'Paulo' THEN 'brazilian' - WHEN 'George' THEN 'english' - ELSE 'unknown' +CASE AUTHOR.FIRST_NAME WHEN 'Paulo' THEN 'brazilian' + WHEN 'George' THEN 'english' + ELSE 'unknown' END]]> // Use the Oracle-style DECODE() function with jOOQ. // Note, that you will not be able to rely on type-safety -create.decode(T_AUTHOR.FIRST_NAME, +create.decode(AUTHOR.FIRST_NAME, "Paulo", "brazilian", "George", "english", "unknown");]]> @@ -2610,6 +2901,7 @@ create.insertInto(AUTHOR, AUTHOR.ID, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME)

LIKE predicate +
@@ -2637,7 +2929,7 @@ create.insertInto(AUTHOR, AUTHOR.ID, AUTHOR.FIRST_NAME, AUTHOR.LAST_NAME) A DSL is a nice thing to have, it feels "fluent" and "natural", especially if it models a well-known language, such as SQL. But a DSL is always expressed in a host language (Java in this case), which was not made for exactly the same purposes as its hosted DSL. If it were, then jOOQ would be implemented on a compiler-level, similar to LINQ in .NET. But it's not, and so, the DSL is limited by language constraints of its host language. We have seen many functionalities where the DSL becomes a bit verbose. This can be especially true for:

    -
  • +
  • @@ -2746,8 +3038,8 @@ Field COUNT2 = create.field("count(*) y", Integer.class); create.select(LAST_NAME, COUNT1, COUNT2) // Use plain SQL as aliased tables (be aware of syntax!) - .from("t_author a") - .join("t_book b") + .from("author a") + .join("book b") // Use plain SQL for conditions both in JOIN and WHERE clauses .on("a.id = b.author_id")