| + | +![]() |
+
+
+
diff --git a/jOOQ-website/css/jooq.css b/jOOQ-website/css/jooq.css index 5238837efa..309c7d1b3e 100644 --- a/jOOQ-website/css/jooq.css +++ b/jOOQ-website/css/jooq.css @@ -1,5 +1,5 @@ body { - font-family: Verdana,Geneva,Arial,Helvetica,sans-serif; + font-family: 'Lucida Grande',Helvetica,Arial,sans-serif;; font-weight: normal; text-shadow: 0 1px 0 #FFFFFF; font-size: 15px; @@ -33,19 +33,19 @@ h1, h2, h3, h4, h5, h6 { h1 { font-size: 4em; - text-shadow: 0 1px 1px #666666; + text-shadow: 0 1px 1px #444; padding: 0; margin: 0; } h2 { font-size: 2.5em; - text-shadow: 0 1px 1px #666666; + text-shadow: 0 1px 1px #444; } h3 { font-size: 1.3em; - text-shadow: 0 1px 0 #666666; + text-shadow: 0 1px 0 #444; } pre { @@ -72,7 +72,7 @@ p { p.slogan { padding-left: 2em; - color: #888888; + color: #444; font-family: 'Georgia',Serif; font-style: italic; height: 2.5em; @@ -129,19 +129,50 @@ a:hover { background-color: #FFFFFF; margin: 0 auto; position: relative; - width: 980px; + width: 1050px; - padding-top: 1em; - padding-left: 3em; - padding-right: 3em; border-width: 0; border-style: solid; border-color: #882222; - box-shadow: 0 0 20px #aa6633; + box-shadow: 0 0 30px #aa6633; +} + +#content { + padding-top: 1em; + padding-left: 3em; + padding-right: 3em; + + background: #fadccb; + background: -webkit-gradient(linear, left, right, from(#f6cab9), to(#ffeedd)); + background: -moz-linear-gradient(left, #f6cab9, #ffeedd); + background: gradient(linear, left, right, from(#f6cab9), to(#ffeedd)); + } #navigation { + padding-top: 1em; + padding-left: 3em; + padding-right: 3em; + height: 40px; + background: #444; + background: -webkit-gradient(linear, left top, left bottom, from(#555), to(#333)); + background: -moz-linear-gradient(top, #555, #333); + background: gradient(linear, left top, left bottom, from(#555), to(#333)); +} + +#navigation a, +#navigation a:link, +#navigation a:visited, +#navigation a:hover, +#navigation a:active { + color: #ddcccc; + text-decoration: none; + text-shadow: 0 1px 1px #666666; +} + +#navigation a:hover { + text-decoration: underline; } div.navigation-item-left { diff --git a/jOOQ-website/frame.php b/jOOQ-website/frame.php index 45c8fbfad7..e2f2d725a9 100644 --- a/jOOQ-website/frame.php +++ b/jOOQ-website/frame.php @@ -13,25 +13,6 @@
| The jOOQ User Manual : DSL or fluent API : Aliased tables and fields | previous : next | +The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Aliased tables and fields | previous : next |
| The jOOQ User Manual : DSL or fluent API : Arithmetic operations | previous : next | +The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Arithmetic operations | previous : next |
| The jOOQ User Manual : DSL or fluent API : The CASE clause | previous : next | +The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : The CASE clause | previous : next |
| The jOOQ User Manual : DSL or fluent API : Type casting | previous : next | +The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Type casting | previous : next |
| The jOOQ User Manual : DSL or fluent API : Conditions | previous : next | +The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Conditions | previous : next |
| The jOOQ User Manual : DSL or fluent API : Other types of nested selects | previous : next | +The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Other types of nested selects | previous : next |
| The jOOQ User Manual : DSL or fluent API : Complete SELECT syntax | previous : next | +The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Complete SELECT syntax | previous : next |
| The jOOQ User Manual : DSL or fluent API | previous : next | +The jOOQ User Manual : DSL or fluent API. Where SQL meets Java | previous : next |
| The jOOQ User Manual : jOOQ classes and their usage : Query and its subtypes | previous : next | +The jOOQ User Manual : jOOQ classes and their usage : The Query and its various subtypes | previous : next |
+ There are essentially two ways of creating SELECT statements in jOOQ. + For historical reasons, you can create + org.jooq.SimpleSelectQuery or + org.jooq.SelectQuery + objects and add additional query clauses, such as + Conditions or + SortFields to it. + Since jOOQ 1.3, there is also the possibility to + create SELECT statements using jOOQ's + DSL API in a much more intuitive + and SQL-like way. +
+Use the DSL API when:
+Use the regular API when:
+In any case, all API's will construct the same underlying + implementation object, and in many cases, you can combine the two + approaches. Let's check out the various SELECT statement types:
+ +| A sample SQL statement | +...and its equivalent in jOOQ's DSL API | + +
++-- Select all books by authors born after 1920, named "Paulo" +-- from a catalogue consisting of authors and books: + + +SELECT * + FROM t_author a + JOIN t_book b + ON a.id = b.author_id + WHERE a.year_of_birth > 1920 + AND a.first_name = 'Paulo' + ORDER BY b.title+ |
+
+
+// Instanciate your factory using a JDBC connection.
+Factory create = new Factory(connection, SQLDialect.ORACLE);
+
+// Execute the query "on a single line"
+Result<Record> result = create.select()
+ .from(T_AUTHOR)
+ .join(T_BOOK)
+ .on(ID.equal(AUTHOR_ID))
+ .where(YEAR_OF_BIRTH.greaterThan(1920)
+ .and(FIRST_NAME.equal("Paulo")))
+ .orderBy(TITLE).fetch();
+ |
+
+
+ In the above example, some generated artefacts are used for querying. + In this case, T_AUTHOR and T_BOOK are instances of types + TAuthor and + TBook respectively. + Their full qualification would read TAuthor.T_AUTHOR and TBook.T_BOOK, but in many cases, + it's useful to static import elements involved with queries, in order to decrease verbosity. +
+ ++ Apart from the singleton Table instances TAuthor.T_AUTHOR and + TBook.T_BOOK, these generated classes also contain one static member + for every physical field, such as TAuthor.ID or TBook.TAUTHOR_ID, etc. +
+ ++ If you choose not to use the DSL API (for instance, because you don't + want to add Query parts in the order SQL expects them), you can use + this syntax: +
+
+// Re-use the factory to create a SelectQuery. This example will not make use of static imports...
+SelectQuery q = create.selectQuery();
+q.addFrom(TAuthor.T_AUTHOR);
+
+// This example shows some "mixed" API usage, where the JOIN is added with the standard API, and the
+// Condition is created using the DSL API
+q.addJoin(TBook.T_BOOK, TAuthor.ID.equal(TBook.AUTHOR_ID));
+
+// The AND operator between Conditions is implicit here
+q.addConditions(TAuthor.YEAR_OF_BIRTH.greaterThan(1920));
+q.addConditions(TAuthor.FIRST_NAME.equal("Paulo"));
+q.addOrderBy(TBook.TITLE);
+
+ + The org.jooq.Select interface extends + org.jooq.ResultQuery, + which provides a range of methods to fetch data from the database. + Once you have constructed your SELECT query (see examples above), you + may choose to either simply execute() it, or use a variety of convenience + fetchXXX() methods. +
++ See the manual's + section on the ResultQuery + for more details. +
+ + +jOOQ supports two modes for INSERT statements. + The INSERT VALUES and the INSERT SELECT syntax
+ +| A typical INSERT query looks like this | +...and how it's done with jOOQ | + +
++INSERT INTO T_AUTHOR + (ID, FIRST_NAME, LAST_NAME) +VALUES + (100, 'Hermann', 'Hesse'), + (101, 'Alfred', 'Döblin');+ + |
+
++create.insertInto(T_AUTHOR, + TAuthor.ID, TAuthor.FIRST_NAME, TAuthor.LAST_NAME) + .values(100, "Hermann", "Hesse") + .values(101, "Alfred", "Döblin") + .execute();+ |
+
+
The DSL syntax tries to stay close to actual SQL. In detail, + however, Java is limited in its possibilities. That's why the + .values() clause is repeated for every record. Some RDBMS support + inserting several records at the same time. This is also supported in + jOOQ, and simulated using INSERT INTO .. SELECT .. UNION ALL SELECT .. + clauses for those RDBMS that don't support this syntax. +
+Note: Just like in SQL itself, you can have syntax errors when you + don't have matching numbers of fields/values. Also, you can run into + runtime problems, if your field/value types don't match.
+ +MySQL (and some other RDBMS) allow for using an UPDATE-like syntax + for INSERT statements. This is also supported in jOOQ, should you + prefer that syntax. The above INSERT statement can also be expressed + as follows:
++create.insertInto(T_AUTHOR) + .set(TAuthor.ID, 100) + .set(TAuthor.FIRST_NAME, "Hermann") + .set(TAuthor.LAST_NAME, "Hesse") + .newRecord() + .set(TAuthor.ID, 101) + .set(TAuthor.FIRST_NAME, "Alfred") + .set(TAuthor.LAST_NAME, "Döblin") + .execute();+
As you can see, this syntax is a bit more verbose, but also more + type-safe, as every field can be matched with its value.
+ +The MySQL database supports a very convenient way to INSERT or + UPDATE a record. This is a non-standard extension to the SQL syntax, + which is supported by jOOQ and simulated in other RDBMS, where this is + possible. Here is an example how to use the ON DUPLICATE KEY UPDATE + clause:
++// Add a new author called "Koontz" with ID 3. +// If that ID is already present, update the author's name +create.insertInto(T_AUTHOR, TAuthor.ID, TAuthor.LAST_NAME) + .values(3, "Koontz") + .onDuplicateKeyUpdate() + .set(TAuthor.LAST_NAME, "Koontz") + .execute();+ +
The Postgres database has native support for an INSERT .. RETURNING + clause. This is a very powerful concept that is simulated for all + other dialects using JDBC's + getGeneratedKeys() + method. Take this example:
+ +
+// Add another author, with a generated ID
+Record<?> record =
+create.insertInto(T_AUTHOR, TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
+ .values("Charlotte", "Roche")
+ .returning(TAuthor.ID)
+ .fetchOne();
+
+System.out.println(record.getValue(TAuthor.ID));
+
+// For some RDBMS, this also works when inserting several values
+Result<?> result =
+create.insertInto(T_AUTHOR, TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
+ .values("Johann Wolfgang", "von Goethe")
+ .values("Friedrich", "Schiller")
+ // You can request any field. Also trigger-generated values
+ .returning(TAuthor.ID, TAuthor.CREATION_DATE)
+ .fetch();
+
+ You can always use the more verbose regular syntax of the InsertQuery, if you need more control:
++// Insert a new author into the T_AUTHOR table +InsertQuery<TAuthorRecord> i = create.insertQuery(T_AUTHOR); +i.addValue(TAuthor.ID, 100); +i.addValue(TAuthor.FIRST_NAME, "Hermann"); +i.addValue(TAuthor.LAST_NAME, "Hesse"); + +i.newRecord(); +i.addValue(TAuthor.ID, 101); +i.addValue(TAuthor.FIRST_NAME, "Alfred"); +i.addValue(TAuthor.LAST_NAME, "Döblin"); +i.execute();+ +
The InsertQuery.addValue() method is overloaded, such that you can + also provide a Field, potentially containing an expression:
++// Insert a new author into the T_AUTHOR table +InsertQuery<TAuthorRecord> i = create.insertQuery(T_AUTHOR); +i.addValue(TAuthor.ID, create.select(TAuthor.ID.max().add(1)).from(T_AUTHOR).asField()) +i.addValue(TAuthor.FIRST_NAME, "Hermann"); +i.addValue(TAuthor.LAST_NAME, "Hesse"); +i.execute();+
Note that especially MySQL (and some other RDBMS) has some + limitations regarding that syntax. You may not be able to + select from the same table you're inserting into
+ +In some occasions, you may prefer the INSERT SELECT syntax, for instance, when + you copy records from one table to another:
++Insert i = create.insertInto(T_AUTHOR_ARCHIVE, + create.selectFrom(T_AUTHOR).where(TAuthor.DECEASED.equal(1))); +i.execute();+ + +
UPDATE statements are only possible on single tables. Support for + multi-table updates will be implemented in the near future.
+ +| A typical UPDATE query looks like this | +...and how it's done with jOOQ | + +
++ +UPDATE T_AUTHOR + SET FIRST_NAME = 'Hermann', + LAST_NAME = 'Hesse' + WHERE ID = 3;+ + |
+
++create.update(T_AUTHOR) + .set(TAuthor.FIRST_NAME, "Hermann") + .set(TAuthor.LAST_NAME, "Hesse") + .where(TAuthor.ID.equal(3)) + .execute();+ |
+
+
Using the org.jooq.UpdateQuery class, + this is how you could express an UPDATE statement:
++UpdateQuery<TAuthorRecord> u = create.updateQuery(T_AUTHOR); +u.addValue(TAuthor.FIRST_NAME, "Hermann"); +u.addValue(TAuthor.FIRST_NAME, "Hesse"); +u.addConditions(TAuthor.ID.equal(3)); +u.execute();+ + +
DELETE statements are only possible on single tables. Support for + multi-table deletes will be implemented in the near future.
+ +| A typical DELETE query looks like this | +...and how it's done with jOOQ | + +
++ +DELETE T_AUTHOR + WHERE ID = 100;+ + |
+
++create.delete(T_AUTHOR) + .where(TAuthor.ID.equal(100)) + .execute();+ |
+
+
Using the org.jooq.DeleteQuery class, + this is how you could express a DELETE statement:
++DeleteQuery<TAuthorRecord> d = create.deleteQuery(T_AUTHOR); +d.addConditions(TAuthor.ID.equal(100)); +d.execute();+ + +
+ The MERGE statement is one of the most advanced standardised SQL + constructs, which is supported by DB2, HSQLDB, Oracle, SQL Server and + Sybase (MySQL has the similar INSERT .. ON DUPLICATE KEY UPDATE + construct. H2's MERGE variant is currently not supported.) +
++ The point of the standard MERGE statement is to take a TARGET table, and + merge (INSERT, UPDATE) data from a SOURCE table into it. DB2, Oracle, + SQL Server and Sybase also allow for DELETING some data and for adding + many additional clauses. Those non-standard extensions are currently + not supported. Here is an example: +
+ +
+
+-- Check if there is already an author called 'Hitchcock'
+-- If there is, rename him to John. If there isn't add him.
+
+MERGE INTO T_AUTHOR
+USING (SELECT 1 FROM DUAL)
+ON (LAST_NAME = 'Hitchcock')
+WHEN MATCHED THEN UPDATE SET FIRST_NAME = 'John'
+WHEN NOT MATCHED THEN INSERT (LAST_NAME) VALUES ('Hitchcock')
+
+ |
+
+
+create.mergeInto(T_AUTHOR)
+ .using(create().selectOne())
+ .on(TAuthor.LAST_NAME.equal("Hitchcock"))
+ .whenMatchedThenUpdate()
+ .set(TAuthor.FIRST_NAME, "John")
+ .whenNotMatchedThenInsert(TAuthor.LAST_NAME)
+ .values("Hitchcock")
+ .execute();
+ |
+
+
+ The syntax is trivial: +
+
+TRUNCATE TABLE T_AUTHOR;+ + |
+
+create.truncate(T_AUTHOR).execute();+ |
+
+
This is not supported by Ingres and SQLite. jOOQ will execute a DELETE FROM + T_AUTHOR statement instead.
+ - diff --git a/jOOQ-website/manual/JOOQ/ResultQuery/index.php b/jOOQ-website/manual/JOOQ/ResultQuery/index.php index c5b33a7fb3..e33b62f17a 100644 --- a/jOOQ-website/manual/JOOQ/ResultQuery/index.php +++ b/jOOQ-website/manual/JOOQ/ResultQuery/index.php @@ -14,7 +14,7 @@ function printContent() { ?>See some details about how to create these queries in the - Query section of the manual + Query section of the manual
| The jOOQ User Manual : jOOQ classes and their usage : Updatable Records | previous : next | +The jOOQ User Manual : jOOQ classes and their usage : Updatable Records | previous : next |
As of jOOQ 1.5, the UpdatableRecord essentially contains three additional + methods CRUD + (Create Read Update Delete) operations:
++// Store any changes made to this record to the database. +// The record executes an INSERT if the PRIMARY KEY is NULL or has been changed. Otherwise, an UPDATE is performed. +int store(); + +// Deletes the record from the database. +int delete(); + +// Reflects changes made in the database to this Record +void refresh();+
An example lifecycle of a book can be implemented as such:
+
+// Create a new record and insert it into the database
+TBookRecord book = create.newRecord(T_BOOK);
+book.setTitle("My first book");
+book.store();
+
+// Update it with new values
+book.setPublishedIn(2010);
+book.store();
+
+// Delete it
+book.delete();
+ These operations are very simple utilities. They do not + reflect the functionality offered by Hibernate + or other persistence managers.
+ ++ If the jOOQ code-generator cannot detect any PRIMARY KEY, or UNIQUE KEY + on your tables, then the generated artefacts implement TableRecord, + instead of UpdatableRecord. A TableRecord can perform the same CRUD + operations as we have seen before, if you provide it with the necessary + key fields. The API looks like this: +
+ ++// INSERT or UPDATE the record using the provided keys +int storeUsing(TableField<R, ?>... keys) + +// DELETE a record using the provided keys +int deleteUsing(TableField<R, ?>... keys); + +// Reflects changes made in the database to this Record +void refreshUsing(TableField<R, ?>... keys);+ +
+ This is useful if your RDBMS does not support referential constraints (e.g. MySQL's + MyISAM), or if you want to + store records to an unconstrained view. An example lifecycle of a book without + any keys can then be implemented as such: +
+
+// Create a new record and insert it into the database
+TBookRecord book = create.newRecord(T_BOOK);
+book.setTitle("My first book");
+book.storeUsing(TBook.ID);
+
+// Update it with new values
+book.setPublishedIn(2010);
+book.storeUsing(TBook.ID);
+
+// Delete it
+book.deleteUsing(TBook.ID);
+
-
diff --git a/jOOQ-website/manual/JOOQ/index.php b/jOOQ-website/manual/JOOQ/index.php
index e731cf7987..33f36370be 100644
--- a/jOOQ-website/manual/JOOQ/index.php
+++ b/jOOQ-website/manual/JOOQ/index.php
@@ -39,7 +39,7 @@ function printContent() {
This section is about the main jOOQ classes and the global architecture. Most of the time, however, you will be using the - DSL or fluent API + DSL or fluent API. Where SQL meets Java in order to create queries the way you're used to in SQL
@@ -60,7 +60,7 @@ function printContent() { Updatable Records| The jOOQ User Manual : Meta model code generation : Sequences | previous : next | +The jOOQ User Manual : Meta model code generation : Sequences | previous : next |
See these chapters to learn about how to use jOOQ in every day's work. The @@ -99,7 +99,7 @@ function printContent() { Updatable Records
As of jOOQ 1.5, the UpdatableRecord essentially contains three additional + methods CRUD + (Create Read Update Delete) operations:
++// Store any changes made to this record to the database. +// The record executes an INSERT if the PRIMARY KEY is NULL or has been changed. Otherwise, an UPDATE is performed. +int store(); + +// Deletes the record from the database. +int delete(); + +// Reflects changes made in the database to this Record +void refresh();+
An example lifecycle of a book can be implemented as such:
+
+// Create a new record and insert it into the database
+TBookRecord book = create.newRecord(T_BOOK);
+book.setTitle("My first book");
+book.store();
+
+// Update it with new values
+book.setPublishedIn(2010);
+book.store();
+
+// Delete it
+book.delete();
+ These operations are very simple utilities. They do not + reflect the functionality offered by Hibernate + or other persistence managers.
+ ++ If the jOOQ code-generator cannot detect any PRIMARY KEY, or UNIQUE KEY + on your tables, then the generated artefacts implement TableRecord, + instead of UpdatableRecord. A TableRecord can perform the same CRUD + operations as we have seen before, if you provide it with the necessary + key fields. The API looks like this: +
+ ++// INSERT or UPDATE the record using the provided keys +int storeUsing(TableField<R, ?>... keys) + +// DELETE a record using the provided keys +int deleteUsing(TableField<R, ?>... keys); + +// Reflects changes made in the database to this Record +void refreshUsing(TableField<R, ?>... keys);+ +
+ This is useful if your RDBMS does not support referential constraints (e.g. MySQL's + MyISAM), or if you want to + store records to an unconstrained view. An example lifecycle of a book without + any keys can then be implemented as such: +
+
+// Create a new record and insert it into the database
+TBookRecord book = create.newRecord(T_BOOK);
+book.setTitle("My first book");
+book.storeUsing(TBook.ID);
+
+// Update it with new values
+book.setPublishedIn(2010);
+book.storeUsing(TBook.ID);
+
+// Delete it
+book.deleteUsing(TBook.ID);
+
+ There are essentially two ways of creating SELECT statements in jOOQ.
+ For historical reasons, you can create
+
Use the DSL API when:
+Use the regular API when:
+In any case, all API's will construct the same underlying + implementation object, and in many cases, you can combine the two + approaches. Let's check out the various SELECT statement types:
+ +| A sample SQL statement | +...and its equivalent in jOOQ's DSL API | +
+-- Select all books by authors born after 1920, named "Paulo" +-- from a catalogue consisting of authors and books: + + +SELECT * + FROM t_author a + JOIN t_book b + ON a.id = b.author_id + WHERE a.year_of_birth > 1920 + AND a.first_name = 'Paulo' + ORDER BY b.title |
+
+// Instanciate your factory using a JDBC connection.
+Factory create = new Factory(connection, SQLDialect.ORACLE);
+
+// Execute the query "on a single line"
+Result<Record> result = create.select()
+ .from(T_AUTHOR)
+ .join(T_BOOK)
+ .on(ID.equal(AUTHOR_ID))
+ .where(YEAR_OF_BIRTH.greaterThan(1920)
+ .and(FIRST_NAME.equal("Paulo")))
+ .orderBy(TITLE).fetch(); |
+
+ In the above example, some generated artefacts are used for querying.
+ In this case, T_AUTHOR and T_BOOK are instances of types
+
+ Apart from the singleton Table instances TAuthor.T_AUTHOR and + TBook.T_BOOK, these generated classes also contain one static member + for every physical field, such as TAuthor.ID or TBook.TAUTHOR_ID, etc. +
+ ++ If you choose not to use the DSL API (for instance, because you don't + want to add Query parts in the order SQL expects them), you can use + this syntax: +
+
+// Re-use the factory to create a SelectQuery. This example will not make use of static imports...
+SelectQuery q = create.selectQuery();
+q.addFrom(TAuthor.T_AUTHOR);
+
+// This example shows some "mixed" API usage, where the JOIN is added with the standard API, and the
+// Condition is created using the DSL API
+q.addJoin(TBook.T_BOOK, TAuthor.ID.equal(TBook.AUTHOR_ID));
+
+// The AND operator between Conditions is implicit here
+q.addConditions(TAuthor.YEAR_OF_BIRTH.greaterThan(1920));
+q.addConditions(TAuthor.FIRST_NAME.equal("Paulo"));
+q.addOrderBy(TBook.TITLE);
+
+
+ The
+ See the manual's
+
jOOQ supports two modes for INSERT statements. + The INSERT VALUES and the INSERT SELECT syntax
+ +| A typical INSERT query looks like this | +...and how it's done with jOOQ | +
+INSERT INTO T_AUTHOR + (ID, FIRST_NAME, LAST_NAME) +VALUES + (100, 'Hermann', 'Hesse'), + (101, 'Alfred', 'Döblin');+ |
+ +create.insertInto(T_AUTHOR, + TAuthor.ID, TAuthor.FIRST_NAME, TAuthor.LAST_NAME) + .values(100, "Hermann", "Hesse") + .values(101, "Alfred", "Döblin") + .execute(); |
+
The DSL syntax tries to stay close to actual SQL. In detail, + however, Java is limited in its possibilities. That's why the + .values() clause is repeated for every record. Some RDBMS support + inserting several records at the same time. This is also supported in + jOOQ, and simulated using INSERT INTO .. SELECT .. UNION ALL SELECT .. + clauses for those RDBMS that don't support this syntax. +
+Note: Just like in SQL itself, you can have syntax errors when you + don't have matching numbers of fields/values. Also, you can run into + runtime problems, if your field/value types don't match.
+ +MySQL (and some other RDBMS) allow for using an UPDATE-like syntax + for INSERT statements. This is also supported in jOOQ, should you + prefer that syntax. The above INSERT statement can also be expressed + as follows:
++create.insertInto(T_AUTHOR) + .set(TAuthor.ID, 100) + .set(TAuthor.FIRST_NAME, "Hermann") + .set(TAuthor.LAST_NAME, "Hesse") + .newRecord() + .set(TAuthor.ID, 101) + .set(TAuthor.FIRST_NAME, "Alfred") + .set(TAuthor.LAST_NAME, "Döblin") + .execute();+
As you can see, this syntax is a bit more verbose, but also more + type-safe, as every field can be matched with its value.
+ +The MySQL database supports a very convenient way to INSERT or + UPDATE a record. This is a non-standard extension to the SQL syntax, + which is supported by jOOQ and simulated in other RDBMS, where this is + possible. Here is an example how to use the ON DUPLICATE KEY UPDATE + clause:
++// Add a new author called "Koontz" with ID 3. +// If that ID is already present, update the author's name +create.insertInto(T_AUTHOR, TAuthor.ID, TAuthor.LAST_NAME) + .values(3, "Koontz") + .onDuplicateKeyUpdate() + .set(TAuthor.LAST_NAME, "Koontz") + .execute();+ +
The Postgres database has native support for an INSERT .. RETURNING
+ clause. This is a very powerful concept that is simulated for all
+ other dialects using JDBC's
+
+// Add another author, with a generated ID
+Record<?> record =
+create.insertInto(T_AUTHOR, TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
+ .values("Charlotte", "Roche")
+ .returning(TAuthor.ID)
+ .fetchOne();
+
+System.out.println(record.getValue(TAuthor.ID));
+
+// For some RDBMS, this also works when inserting several values
+Result<?> result =
+create.insertInto(T_AUTHOR, TAuthor.FIRST_NAME, TAuthor.LAST_NAME)
+ .values("Johann Wolfgang", "von Goethe")
+ .values("Friedrich", "Schiller")
+ // You can request any field. Also trigger-generated values
+ .returning(TAuthor.ID, TAuthor.CREATION_DATE)
+ .fetch();
+
+ You can always use the more verbose regular syntax of the InsertQuery, if you need more control:
++// Insert a new author into the T_AUTHOR table +InsertQuery<TAuthorRecord> i = create.insertQuery(T_AUTHOR); +i.addValue(TAuthor.ID, 100); +i.addValue(TAuthor.FIRST_NAME, "Hermann"); +i.addValue(TAuthor.LAST_NAME, "Hesse"); + +i.newRecord(); +i.addValue(TAuthor.ID, 101); +i.addValue(TAuthor.FIRST_NAME, "Alfred"); +i.addValue(TAuthor.LAST_NAME, "Döblin"); +i.execute();+ +
The InsertQuery.addValue() method is overloaded, such that you can + also provide a Field, potentially containing an expression:
++// Insert a new author into the T_AUTHOR table +InsertQuery<TAuthorRecord> i = create.insertQuery(T_AUTHOR); +i.addValue(TAuthor.ID, create.select(TAuthor.ID.max().add(1)).from(T_AUTHOR).asField()) +i.addValue(TAuthor.FIRST_NAME, "Hermann"); +i.addValue(TAuthor.LAST_NAME, "Hesse"); +i.execute();+
Note that especially MySQL (and some other RDBMS) has some + limitations regarding that syntax. You may not be able to + select from the same table you're inserting into
+ +In some occasions, you may prefer the INSERT SELECT syntax, for instance, when + you copy records from one table to another:
++Insert i = create.insertInto(T_AUTHOR_ARCHIVE, + create.selectFrom(T_AUTHOR).where(TAuthor.DECEASED.equal(1))); +i.execute();+ + +
UPDATE statements are only possible on single tables. Support for + multi-table updates will be implemented in the near future.
+ +| A typical UPDATE query looks like this | +...and how it's done with jOOQ | +
+ +UPDATE T_AUTHOR + SET FIRST_NAME = 'Hermann', + LAST_NAME = 'Hesse' + WHERE ID = 3;+ |
+ +create.update(T_AUTHOR) + .set(TAuthor.FIRST_NAME, "Hermann") + .set(TAuthor.LAST_NAME, "Hesse") + .where(TAuthor.ID.equal(3)) + .execute(); |
+
Using the
+UpdateQuery<TAuthorRecord> u = create.updateQuery(T_AUTHOR); +u.addValue(TAuthor.FIRST_NAME, "Hermann"); +u.addValue(TAuthor.FIRST_NAME, "Hesse"); +u.addConditions(TAuthor.ID.equal(3)); +u.execute();+ + +
DELETE statements are only possible on single tables. Support for + multi-table deletes will be implemented in the near future.
+ +| A typical DELETE query looks like this | +...and how it's done with jOOQ | +
+ +DELETE T_AUTHOR + WHERE ID = 100;+ |
+ +create.delete(T_AUTHOR) + .where(TAuthor.ID.equal(100)) + .execute(); |
+
Using the
+DeleteQuery<TAuthorRecord> d = create.deleteQuery(T_AUTHOR); +d.addConditions(TAuthor.ID.equal(100)); +d.execute();+ + +
+ The MERGE statement is one of the most advanced standardised SQL + constructs, which is supported by DB2, HSQLDB, Oracle, SQL Server and + Sybase (MySQL has the similar INSERT .. ON DUPLICATE KEY UPDATE + construct. H2's MERGE variant is currently not supported.) +
++ The point of the standard MERGE statement is to take a TARGET table, and + merge (INSERT, UPDATE) data from a SOURCE table into it. DB2, Oracle, + SQL Server and Sybase also allow for DELETING some data and for adding + many additional clauses. Those non-standard extensions are currently + not supported. Here is an example: +
+ +
+-- Check if there is already an author called 'Hitchcock'
+-- If there is, rename him to John. If there isn't add him.
+
+MERGE INTO T_AUTHOR
+USING (SELECT 1 FROM DUAL)
+ON (LAST_NAME = 'Hitchcock')
+WHEN MATCHED THEN UPDATE SET FIRST_NAME = 'John'
+WHEN NOT MATCHED THEN INSERT (LAST_NAME) VALUES ('Hitchcock')
+ |
+
+create.mergeInto(T_AUTHOR)
+ .using(create().selectOne())
+ .on(TAuthor.LAST_NAME.equal("Hitchcock"))
+ .whenMatchedThenUpdate()
+ .set(TAuthor.FIRST_NAME, "John")
+ .whenNotMatchedThenInsert(TAuthor.LAST_NAME)
+ .values("Hitchcock")
+ .execute(); |
+
+ The syntax is trivial: +
+TRUNCATE TABLE T_AUTHOR;+ |
+ create.truncate(T_AUTHOR).execute(); |
+
This is not supported by Ingres and SQLite. jOOQ will execute a DELETE FROM + T_AUTHOR statement instead.
+