This manual is divided into four main sections:
++ See these chapters for an overview of the jOOQ internal architecture + and all types that are involved with jOOQ's query creation and + execution. This is the important part for you, also, if you wish to + extend jOOQ +
++ See these chapters to understand how you can use jOOQ as a source code + generator, and what type of artefacts are generated by jOOQ +
++ See these chapters to learn about how to use jOOQ in every day's work. The + jOOQ DSL is the main way to create and execute jOOQ queries almost as + if SQL was embedded in Java directly +
++ Some advanced topics including not-everyday functionality +
+jOOQ essentially has two packages:
+
+ This section is about the main jOOQ classes and the global
+ architecture. Most of the time, however, you will be using the
+
+ 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 +
++ More entities, types (e.g. UDT's, ARRAY types, ENUM types, etc), + stored procedures and packages are introduced for specific examples +
++ jOOQ exposes a lot of interfaces and hides most implementation facts + from client code. The reasons for this are: +
+
+ The
If you are planning on using several RDBMS (= SQLDialects) or + several distinct JDBC Connections in your software, this will mean + that you have to create a new Factory every time.
+ +
+ The jOOQ Factory allows for some optional configuration elements to be used by advanced users.
+ The
+ Subsequent sections of the manual contain some more in-depth explanations about these settings: +
+
+ Please refer to the jOOQ runtime configuration XSD for more details:
+ http://www.jooq.org/xsd/jooq-runtime-2.1.0.xsd
+
+ There are a couple of subclasses for the general Factory. Each SQL + dialect has its own dialect-specific factory. For instance, if you're + only using the MySQL dialect, you can choose to create a new Factory + using any of the following types: +
++ The advantage of using a dialect-specific Factory lies in the fact, + that you have access to more proprietary RDMBS functionality. This may + include: +
++ Another type of Factory subclasses are each generated schema's + factories. If you generate your schema TEST, then you will have access + to a TestFactory. This will be useful in the future, when access to + schema artefacts will be unified. Currently, this has no use. +
+ ++ With jOOQ 2.0, static factory methods have been introduced in order to + make your code look more like SQL. Ideally, when working with jOOQ, you + will simply static import all methods from the Factory class: +
++ This will allow to access functions even more fluently: +
+ +
+ Objects created statically from the Factory do not need a reference to
+ any factory, as they can be constructed independently from your Configuration
+ (connection, dialect, schema mapping). They will access that information at
+ render / bind time. See
+
+ The jOOQ Factory expects its underlying
+
+ So if you want your queries to run in separate transactions, if you + want to roll back a transaction, if you want to close a Connection and + return it to your container, you will have to take care of that + yourself. jOOQ's Factory will always expect its Connection to be in a + ready state for creating new PreparedStatements. If it is not, you have + to create a new Factory. +
+
+ Please keep in mind that many jOOQ objects will reference your Factory
+ for their whole lifecycle. This is especially interesting, when dealing
+ with
Tables represent any entity in your underlying RDBMS, that holds + data for selection, insertion, updates, and deletion. In other + words, views are also considered tables by jOOQ.
+The formal definition of a
+ This means that every table is associated with a subtype of the
+
+ Unlike in the
+ JPA CriteriaQuery API,
+ this generic type
+ <R>
+ is not given so much importance as far as
+ type-safety is concerned.
+ SQL itself is highly typesafe. You have
+ incredible flexibility of creating anonymous or ad-hoc
+ types and
+ reusing them from
+
The formal definition of a Field starts with
+
+ Fields are generically parameterised with a Java type
+ <T>
+ that reflects the closest match to the RDMBS's underlying datatype for that
+ field. For instance, if you have a VARCHAR2 type Field in Oracle,
+ <T>
+ would bind to
+
The Field itself is a very broad concept. Other tools, or databases + refer to it as expression or column. When you just want to
+ +
+ Then 1 is considered a Field or more explicitly, a
+
+ More advanced uses become clear quickly, when you do things like +
+
+ Where 1 + 1 itself is a Field or more explicitly, an
+
+ See some details about how to create these queries in the
+
+ A specific type of field is the
+
+ TableFields join both <R> and <T> generic parameters into their specification: +
++ This can be used for additional type safety in the future, or by client code. +
+
+ The
+
+ A similar object is the
+
+ The Record itself holds all the data from your selected tuple. If it is
+ a
+ In some cases, you will not be able to reference the selected Fields + both when you create the SELECT statement and when you fetch data from + Records. Then you might use field names or indexes, as with JDBC. + However, of course, the type information will then be lost as well. If + you know what type you want to get, you can always use the Record's + convenience methods for type conversion, however. Some examples: +
+
+ For more information about the type conversions that are supported by
+ jOOQ, read the Javadoc on
+
+ UpdatableRecords are a specific subtype of TableRecord that have + primary key information associated with them. +
+As of jOOQ 1.5, the UpdatableRecord essentially contains three additional + methods CRUD + (Create Read Update Delete) operations:
+An example lifecycle of a book can be implemented as such:
+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: +
+ ++ 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: +
+
+ 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:
+ +
+ 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 member + for every physical field, such as TAuthor.ID or TBook.TAUTHOR_ID, etc. + Depending on your configuration, those members can be static members + (better for static imports) or instance members (better for aliasing) +
+ ++ 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: +
+
+ The
+ See the manual's
+
jOOQ supports two modes for INSERT statements. + The INSERT VALUES and the INSERT SELECT syntax
+ +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 in multi-record inserts.
+ Some RDBMS support
+ inserting several records at the same time. This is also supported in
+ jOOQ, and simulated using UNION 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:
+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:
+The MySQL database also supports an INSERT IGNORE INTO clause. + This is supported by jOOQ using the more convenient SQL + syntax variant of ON DUPLICATE KEY IGNORE, which can be equally + simulated in other databases using a MERGE statement:
+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
+
+ Be aware though, that this can lead to race-conditions + in those databases that cannot properly return generated + ID values. +
+ +You can always use the more verbose regular syntax of the InsertQuery, if you need more control:
+The InsertQuery.addValue() method is overloaded, such that you can + also provide a Field, potentially containing an expression:
+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:
+UPDATE statements are only possible on single tables. Support for + multi-table updates will be implemented in the near future.
+ +Using the
DELETE statements are only possible on single tables. Support for + multi-table deletes will be implemented in the near future.
+ +Using the
+ 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) +
++ 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. With jOOQ 2.0.1, only Oracle's MERGE extensions are supported. + Here is an example: +
+ ++ The H2 database ships with a somewhat less powerful + but a little more intuitive syntax for its own version of the MERGE statement. + An example more or less equivalent to the previous one + can be seen here: +
+
+ This syntax can be fully simulated by jOOQ for all other
+ databases that support the SQL standard. For more information
+ about the H2 MERGE syntax, see the documentation here:
+
+
+ http://www.h2database.com/html/grammar.html#merge
+
+ The syntax is trivial: +
+ +This is not supported by Ingres and SQLite. jOOQ will execute a DELETE FROM + T_AUTHOR statement instead.
++ Data fetching is one of the great hassles in JDBC and JPA. + With jOOQ, you will be able to specify exactly, what kind of + data you want to fetch from any given query, as well as how + you want to fetch that data. This doesn't just mean distinguishing + between fetching one record at a time, or the whole resultset, + between fetching one column at a time, or the whole resultset. + This also means transforming your result (a list) into a map, + into arrays, into custom types, into JPA-annotated types, into + a call-back, or simply fetching it asynchronously +
+These methods allow for fetching a jOOQ Result or parts of it.
+ +These methods transform the result into another form, if org.jooq.Result is not optimal
+ +These methods transform the result into a user-defined form, if org.jooq.Result is not optimal
+ ++ Bind values are used in SQL / JDBC for various reasons. Among the most + obvious ones are: +
++ Bind values are omni-present in jOOQ. Whenever you create a condition, + you're actually also adding a bind value: +
++ The above notation is actually convenient way to explicitly create + a bind value for "Poe". You could also write this, instead: +
+
+ Once created, bind values are part of the query's syntax tree (see
+
+ The
+ The
+ NOTE: Should you wish to use jOOQ only as a query builder and execute + queries with another tool, such as Spring Data instead, you can also + use the Factory's renderNamedParams() method, to actually render named + parameter names in generated SQL: +
+ ++ Sometimes, you may wish to avoid rendering bind + variables while still using custom values in SQL. + jOOQ refers to that as "inlined" bind values. + When bind values are inlined, they render the + actual value in SQL rather than a JDBC question mark. + Bind value inlining can be achieved in two ways: +
+ ++ In both cases, your inlined bind values will be + properly escaped to avoid SQL syntax errors and + SQL injection. + Some examples: +
+ +
+ A
+
Both of these methods are contained in jOOQ's internal API's
+
A simple example can be provided by checking out jOOQ's internal
+ representation of a
+
This is how jOOQ implements such a condition:
+ +For more complex examples, please refer to the codebase, directly
+
+ The only transient element in any jOOQ object is the
+
+ Note, this functionality is deprecated with jOOQ 2.1.0.
+ Please use the
In simple cases, you can register a ConfigurationProvider in jOOQ's ConfigurationRegistry
+Once you have executed these steps, all subsequent deserialisations + will try to access a Configuration (containing a JDBC Connection) from + your ConfigurationProvider. This may be useful when
+If a SQL clause is too complex to express with jOOQ, you can extend + either one of the following types for use directly in a jOOQ query:
+These two classes are declared public and covered by integration
+ tests. When you extend these classes, you will have to provide your
+ own implementations for the
The above contract may be a bit tricky to understand at first. The + best thing is to check out jOOQ source code and have a look at a + couple of QueryParts, to see how it's done.
+If you don't need integration of rather complex QueryParts into
+ jOOQ, then you might be safer using simple
+
+ In the previous chapter, we have seen how to use the
+
+ Artefacts, such as tables, views, user defined types, sequences, stored + procedures, packages have a corresponding artefact in Java. +
++ There are three binaries available with jOOQ, to be downloaded from + SourceForge + or from Maven central: +
+All of jOOQ's dependencies are "optional", i.e. you can run + jOOQ without any of those libraries. + For instance, jOOQ maintains an "optional" dependency on log4j and slf4j. + This means, that jOOQ tries to find log4j (and /log4j.xml) or slf4j on the + classpath. If they are not present, then java.util.logging.Logger is + used instead. +
++ Other optional dependencies are the JPA API, and the Oracle JDBC driver, + which is needed for Oracle's advanced data types, only +
+ + +You need to tell jOOQ some things about your database connection. + Here's an example of how to do it for an Oracle database
+
+ There are also lots of advanced configuration parameters, which will be
+ treated in the
Code generation works by calling this class with the above property file as argument.
+Be sure that these elements are located on the classpath:
+Note that the property file must be passed as a classpath resource
+ +Of course, you can also run code generation from your IDE. In + Eclipse, set up a project like this. Note that this example uses + jOOQ's log4j support by adding log4j.xml and log4j.jar to the project + classpath:
+
+ Once the project is set up correctly with all required artefacts on + the classpath, you can configure an Eclipse Run Configuration for + org.jooq.util.GenerationTool.
+
+ With the properties file as an argument
+
+ And the classpath set up correctly
+
+ Finally, run the code generation and see your generated artefacts
+
+ + You can also use an ant task to generate your classes. As a rule of thumb, + remove the dots "." and dashes "-" from the .properties file's property names to get the + ant task's arguments: +
++ Note that when running code generation with ant's <java/> task, + you may have to set fork="true": +
+ +Using the official jOOQ-codegen-maven plugin, you can integrate + source code generation in your Maven build process:
+ +See the full example of a pom.xml including the jOOQ-codegen artefact here: + https://github.com/jOOQ/jOOQ/blob/master/jOOQ-codegen-maven-example/pom.xml
+ ++ Before jOOQ 2.0.4, the code generator was configured using properties files + These files are still supported for source code generation, but their syntax + won't be maintained any longer. If you wish to migrate to XML, you can + migrate the file using this command on the command line +
++ Using the migrate flag, jOOQ will read the properties file and output + a corresponding XML file on system out +
+ +Be sure, both jOOQ.jar and your generated package (see + configuration) are located on your classpath. Once this is done, you + can execute SQL statements with your generated classes.
+
+ In the
+ The following example shows how you can override the + DefaultGeneratorStrategy to render table and column names the way + they are defined in the database, rather than switching them to + camel case: +
+ ++ Within the <generator/> element, there are other configuration elements: +
+ ++ Check out the some of the manual's "advanced" sections + to find out more about the advanced configuration parameters. +
+Also, you can add some optional advanced configuration parameters for the generator:
+ +
+ As of jOOQ 1.5, the top-level generated object is the
+
+ Currently, it is not possible to link generated artefacts from various
+ schemata. If you have a stored function from Schema A, which returns a
+ UDT from Schema B, the types cannot be linked. This enhancement is on
+ the roadmap, though:
+ When you have several schemata that are logically equivalent (i.e. they
+ contain identical entities, but the schemata stand for different
+ users/customers/clients, etc), there is a solution for that. Check out
+ the manual's section on support for
+
The schema can be used to dynamically discover generate database + artefacts. Tables, sequences, and other items are accessible from the + schema. For example:
+
+ The most important generated artefacts are
+
+ Suppose we have the tables as defined in the
+
If you use the
+
+ If you're using jOOQ along with Hibernate / JPA, or if you + want to use your own, custom domain-model instead of jOOQ's + Record type-hierarchy, you can choose to select values into + POJOs. Let's say you defined a POJO for authors: +
+ +
+ The above could be your custom POJO or a POJO generated
+ by jooq-codegen (see
+
+ Read the javadoc for + Record.into() + for more details. +
+This is one of the most important reasons why you should consider
+ jOOQ. Read also my
+ article on dzone
+ about why stored procedures become
+ more and more important in future versions of RDMBS. In this section
+ of the manual, we will learn how jOOQ handles stored procedures in
+ code generation. Especially before
+
Let's say you have these stored procedures and functions in your Oracle database
+jOOQ will essentially generate two artefacts for every procedure/function:
+Let's see what these things look like, in Java. The classes (simplified for the example):
+ +An example invocation of such a stored procedure might look like this:
+ +
+ The above configuration is a
+
An sample invocation, equivalent to the previous example:
++ jOOQ does not formally distinguish procedures from functions. + jOOQ only knows about routines, which can have return values + and/or OUT parameters. This is the best option to handle the + variety of stored procedure / function support across the + various supported RDBMS. For more details, read on about this + topic, here: +
++ blog.jooq.org/2011/10/17/what-are-procedures-and-functions-after-all/ +
+ ++ Oracle uses the concept of a PACKAGE to group several + procedures/functions into a sort of namespace. The + SQL standard + talks about "modules", to represent this concept, even if this is + rarely implemented. This is reflected in jOOQ by the use of Java + sub-packages in the source code generation destination package. Every + Oracle package will be reflected by +
++ Apart from this, the generated source code looks exactly like the + one for + standalone procedures/functions. +
+ ++ Oracle UDT's can have object-oriented structures including member functions + and procedures. With Oracle, you can do things like this: +
++ These member functions and procedures can simply be mapped to Java + methods: +
+ +For more details about UDT's see the Manual's section on
+
+ In recent years, most RDBMS have started to implement some support for + advanced data types. This support has not been adopted very well by + database users in the Java world, for several reasons: +
++ On the other hand, especially with stored procedures, these data types + are likely to become more and more useful in the future. If you have a + look at Postgres' capabilities of dealing with advanced data types + (ENUMs, + ARRAYs, + UDT's), + this becomes more and more obvious. +
+It is a central strategy for jOOQ, to standardise access to these
+ kinds of types (as well as to
+
User Defined Types (UDT) are helpful in major RDMBS with lots + of proprietary functionality. The biggest player is clearly Oracle. + Currently, jOOQ provides UDT support for only two databases:
+Apart from that,
+In Oracle, you would define UDTs like this:
+These types could then be used in tables and/or stored procedures like such:
+
+ Standard JDBC UDT support encourages JDBC-driver developers to implement
+ interfaces such as
+
Now, when you interact with entities or procedures that hold UDT's, that's very simple as well. Here is an example:
+A similar thing can be achieved when interacting with the example stored procedure:
++ The notion of ARRAY types in RDBMS is not standardised at all. Very + modern databases (especially the Java-based ones) have implemented + ARRAY types exactly as what they are. "ARRAYs of something". In other + words, an ARRAY OF VARCHAR would be something very similar to Java's + notion of String[]. An ARRAY OF ARRAY OF VARCHAR would then be a + String[][] in Java. Some RDMBS, however, enforce stronger typing and + need the explicit creation of types for every ARRAY as well. These are + example String[] ARRAY types in various SQL dialects supported by jOOQ + 1.5.4: +
+Soon to be supported:
++ From jOOQ's perspective, the ARRAY types fit in just like any other + type wherever the + <T> generic type parameter is existent. It integrates well with tables + and stored procedures. +
+ +An example usage of ARRAYs is given here for the Postgres dialect
+ +When generating source code from the above entities, these artefacts will be created in Java:
+In Oracle, a VARRAY type is something slightly different than in + other RDMBS. It is a type that encapsules the actual ARRAY and creates + a new type from it. While all text[] types are equal and thus + compatible in Postgres, this does not apply for all VARRAY OF VARCHAR2 + types. Hence, it is important to provide access to VARRAY types and + generated objects from those types as well. The example above would + read like this in Oracle:
+ +Note that it becomes clear immediately, that a mapping from
+ U_STRING_ARRAY to String[] is obvious. But a mapping from String[] to
+ U_STRING_ARRAY is not. These are the generated
+
True ENUM types are a rare species in the RDBMS world. Currently, + MySQL and Postgres are the only RDMBS supported by jOOQ, that provide + ENUM types.
+ +Some examples:
+The above Postgres ENUM type will be generated as
+Intuitively, the generated classes for the T_BOOK table in Postgres would look like this:
+Note that jOOQ allows you to simulate ENUM types where this makes
+ sense in your data model. See the section on
+
Sequences implement the
+
So if you have a sequence like this in Oracle:
+This is what jOOQ will generate:
+Which you can use in a select statement as such:
+Or directly fetch currval() and nextval() from the sequence using the Factory:
+jOOQ ships with its own DSL (or + Domain Specific Language) that + simulates SQL as good as possible in Java. This means, that you can + write SQL statements almost as if Java natively supported that syntax + just like .NET's C# does with LINQ to SQL.
+ +Here is an example to show you what that means. When you want to write a query like this in SQL:
+
+ You couldn't come much closer to SQL itself in Java, without re-writing the compiler.
+ We'll see how the aliasing works later in the section about
+
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: +
+ +So that's daily business. How to do it with jOOQ: When you first create a SELECT statement using the Factory's select() methods
+
+ jOOQ will return an "intermediary" type to you, representing the
+ SELECT statement about to be created (by the way, check out the
+ section on
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
+
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
+
+ See the section about
+
+ 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
+
Now the returned type
+
Let's assume we have that method parseDate() creating a
+
and the HAVING clause:
+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.
+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 ... (or TOP ... START AT ..., or FETCH FIRST ... ROWS ONLY, etc) + 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):
+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):
+
+ Now the most relevant super-type of the object we have just created is
+
A very similar, but limited 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
+
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:
+
+ In the relational data model,
+ there are many operations performed on entities, i.e. tables in order to join them together
+ before applying predicates, renaming operations and projections. Apart from the convenience
+ methods for joining table sources in the
+
+ The
In your average application, you will typically have 3-4 SQL queries + that have quite a long list of predicates (and possibly JOINs), such + that you start to lose track over the overall boolean expression that + you're trying to apply.
+In jOOQ, most Conditions can be created and combined almost as
+ easily as in SQL itself. The two main participants for creating
+ Conditions are the
The above example describes the essence of boolean logic in jOOQ. As + soon as you have a Condition object, you can connect that to other + Conditions, which will then give you a combined condition with exactly + the same properties. There are also convenience methods to create an + EXISTS clause and connect it to an existing condition. In order to + create a new Condition you are going to depart from a Field in most + cases. Here are some important API elements in the Field interface: +
+ +As you see in the partially displayed API above, you can compare a
+ Field either with other Fields, with constant values (which is a
+ shortcut for calling Factory.val(T value)), or with a nested SELECT
+ statement. See some more
+
Combining the API of Field and Condition you can express complex predicates like this:
+ +Just write:
+A typical example of what you might want to do in SQL is this:
+
+ In this example, we are aliasing Tables, calling them a and b.
+ The way aliasing works depends on how you generate your meta model
+ using jooq-codegen (see the manual's section about
+
Now, if you want to reference any fields from those Tables, you may + not use the original T_BOOK or T_AUTHOR meta-model objects anymore. + Instead, you have to get the fields from the new book and author Table + aliases:
+ ++ So this is how the above SQL statement would read in jOOQ: +
+There is an interesting, more advanced example of how you can select
+ from an aliased nested select in the manual's section about
+
Fields can also be aliased independently from Tables. Most often, + this is done when using functions or aggregate operators. Here is an + example:
+Here is how it's done with jOOQ:
+When you alias Fields like above, you can access those Fields' values using the alias name:
+
+ In addition to a list of constant values, the IN operator in
+
Let's say you want to select books by authors born in 1920. Of + course, this is possible with a plain JOIN as well, but let's say we + want to use the IN operator. Then you have two possibilities:
+ +The EXISTS operator is rather independent and can stand any place + where there may be a new condition:
+This is reflected by the fact that an EXISTS clause is usually + created directly from the Factory:
+ +When you create such a Condition, it can then be connected to any
+ other condition using AND, OR operators (see also the manual's section
+ on
+
Or in the
Or in the
An example of how to use it is quickly given. Get all authors that haven't written any books:
+If you can ensure that a nested SELECT will only return one Record + with one Field, then you can test for equality. This is how it is done + in SQL:
+ +More examples like the above can be guessed from the
+
Often, you need to nest a SELECT statement simply because SQL is + limited in power. For instance, if you want to find out which author + has written the most books, then you cannot do this:
+ +Instead, you have to do this (or something similar). For jOOQ, this + is an excellent example, combining various SQL features into a single + statement. Here's how to do it:
+ +You'll notice how some verbosity seems inevitable when you combine nested SELECT statements with aliasing.
+ +Now SQL is even more powerful than that. You can also have SELECT + statements, wherever you can have Fields. It get's harder and harder + to find good examples, because there is always an easier way to + express the same thing. But why not just count the number of books the + really hard way? :-) But then again, maybe you want to take advantage + of Oracle Scalar Subquery Caching
+ +The
+
Hence, this is how you can write a simple UNION with jOOQ:
+In some SQL dialects, you can arbitrarily nest UNIONs to several + levels. Be aware, though, that SQLite, Derby and MySQL have serious + syntax limitations. jOOQ tries to render correct UNION SQL statements, + but unfortunately, you can create situations that will cause syntax + errors in the aforementioned dialects.
+ +An example of advanced UNION usage is the following statement in jOOQ:
+This example does not seem surprising, when you have read the
+ previous chapters about
+
You can see that jOOQ takes care of many syntax pitfalls, when + you're not used to the various dialects' unique requirements. The + above automatic aliasing was added in order to be compliant with + MySQL's requirements about aliasing nested selects.
+ +It is no problem either for you to create SQL statements with several unions. Just write:
++ Strictly speaking, in SQL, you cannot order a subselect that is part + of a UNION operation. You can only order the whole set. In set theory, + or relational algebra, it wouldn't make sense to order subselects + anyway, as a set operation cannot guarantee order correctness. Often, + you still want to do it, because you apply a LIMIT to every subselect. + Let's say, you want to find the employees with the highest salary in + every department in Postgres syntax: +
+There is a subtle difference between the above two queries.
+ In SQL, every UNION subselect is in fact a
+
jOOQ allows you to access native functions from your RDBMS. jOOQ + follows two strategies:
+These are just a few functions in the Factory, so you get the idea:
+ +Aggregate functions work just like functions, even if they have a + slightly different semantics. Here are some examples from + Factory:
+ +A typical example of how to use an aggregate operator is when + generating the next key on insertion of an ID. When you want to + achieve something like this
+ +See also the section about
+
Oracle and some other databases support ordered + aggregate functions. This means you can provide + an ORDER BY clause to an aggregate function, which will + be taken into consideration when aggregating. The best example + for this is LISTAGG() (also known as GROUP_CONCAT in other dialects). + The following query groups by authors and concatenates + their books' titles
+Most major RDBMS support the concept of window functions. jOOQ knows + of implementations in DB2, Oracle, Postgres, SQL Server, and Sybase + SQL Anywhere, + and supports most of their specific syntaxes. Window functions can be + used for things like calculating a "running total". The following example + fetches transactions and the running total for every transaction going + back to the beginning of the transaction table (ordered by booked_at). + + They are accessible from the previously seen AggregateFunction type using + the over() method: +
+ ++ The full power of your database's vendor-specific extensions can hardly + be obtained outside of the + database itself. Most modern RDBMS support + their own procedural language. With jOOQ, stored procedures are + integrated easily +
+ +The main way to interact with your RDBMS's stored procedures and
+ functions is by using the generated artefacts. See the manual's
+ section about
+
When it comes to DSL, stored functions can be very handy in SQL + statements as well. Every stored function (this also applies to + FUNCTIONS in Oracle PACKAGES) can generate a Field representing a call + to that function. Typically, if you have this type of function in your + database:
+ +Then convenience methods like these are generated:
+Let's say, you have a T_PERSON table with persons' names in it, and + you want to know whether there exists an author with precisely that + name, you can reuse the above stored function in a SQL query:
+ +The notion of a stored procedure is implemented in most RDBMS by the + fact, that the procedure has no RETURN VALUE (like void in Java), but + it may well have OUT parameters. Since there is not a standard way how + to embed stored procedures in SQL, they cannot be integrated in jOOQ's + DSL either.
++ Your database can do the math for you. Most arithmetic operations are + supported, but also string concatenation can be very efficient if done + already in the database. +
+Arithmetic operations are implemented just like
+
In order to express a SQL query like this one:
+You can write something like this in jOOQ:
+jOOQ also supports the Oracle-style syntax for adding days to a Field<? extends java.util.Date>
++ For more advanced datetime arithmetic, use the Factory's timestampDiff() and dateDiff() functions, + as well as jOOQ's built-in SQL standard INTERVAL data type support: +
+This is not really an arithmetic expression, but it's still an + expression with operators: The string concatenation. jOOQ + provides you with the Field's concat() method:
+The CASE clause is part of the standard SQL syntax. While some RDBMS + also offer an IF clause, or a DECODE function, you can always rely on + the two types of CASE syntax:
+ ++ In jOOQ, both syntaxes are supported (although, Derby only knows the + first one, which is more general). Unfortunately, both case and else + are reserved words in Java. jOOQ chose to use decode() from the Oracle + DECODE function, and otherwise(), which means the same as else. Please + note that in the above examples, all values were always constants. You + can of course also use Field instead of the various constants. +
+A CASE clause can be used anywhere where you can place a Field. For + instance, you can SELECT the above expression, if you're selecting + from T_AUTHOR:
+Sort indirection is often implemented with a CASE clause of a + SELECT's ORDER BY clause. In SQL, this reads:
+ +This will order your authors such that all 'Paulo' come first, then + all 'George' and everyone else last (depending on your RDBMS' handling + of NULL values in sorting). This is a very common task, such that jOOQ + simplifies its use:
+jOOQ's source code generator tries to find the most accurate type + mapping between your vendor-specific data types and a matching Java + type. For instance, most VARCHAR, CHAR, CLOB types will map to String. + Most BINARY, BYTEA, BLOB types will map to byte[]. NUMERIC types will + default to java.math.BigDecimal, but can also be any of + java.math.BigInteger, Long, Integer, Short, Byte, Double, Float.
+Sometimes, this automatic mapping might not be what you needed, or
+ jOOQ cannot know the type of a field (because you created it from a
+
in jOOQ, you can write something like that:
+The same thing can be achieved by casting a Field directly to + String.class, as TEXT is the default data type in Postgres to map to + Java's String
+The complete CAST API in Field consists of these three methods:
+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 another language (Java in this case), which was + not made for exactly that 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. We have seen many functionalities + where the DSL becomes verbose. This can be especially true for:
+You'll probably find other examples. If verbosity scares you off, + don't worry. The verbose use-cases for jOOQ are rather rare, and when + they come up, you do have an option. Just write SQL the way you're + used to!
+jOOQ allows you to embed SQL as a String in these contexts:
+To construct artefacts wrapping plain SQL, you should use any of + these methods from the Factory class:
+ +Apart from the general factory methods, plain SQL is useful also in + various other contexts. For instance, when adding a .where("a = b") + clause to a query. Hence, there exist several convenience methods + where plain SQL can be inserted usefully. This is an example + displaying all various use-cases in one single query:
+There are some important things to keep in mind when using plain + SQL:
+This section covers some advanced topics and features that don't fit into any other section.
+Only MySQL and Postgres databases support true ENUM types natively. + Some other RDBMS allow you to map the concept of an ENUM data type to + a CHECK constraint, but those constraints can contain arbitrary SQL. + With jOOQ, you + can "simulate" ENUM types by declaring a table as a "master data + table" in the configuration. At code-generation time, this table will + be treated specially, and a Java enum type is generated from its data. +
+ +As previously discussed in the
+
The results of this will be a Java enum that looks similar to this:
+In the above example, you can see how the configured primary key is + mapped to the id member, the configured literal column is mapped to + the cd member and the configured description member is mapped to the + description member and output as Javadoc. In other words, T_LANGUAGE + is a table with 4 rows and at least three columns.
+The general contract (with jOOQ 1.6.2+) is that there must be
+The point of MasterDataTypes in jOOQ is that they behave exactly + like true ENUM types. When the above T_LANGUAGE table is referenced by + T_BOOK, instead of generating foreign key navigation methods and a + LANGUAGE_ID Field<Integer>, a Field<TLanguage> is + generated:
+ +Which can then be used in the TBookRecord directly:
+You can use master data types when you're actually mapping master + data to a Java enum. When the underlying table changes frequently, + those updates will not be reflected by the statically generated code. + Also, be aware that it will be difficult to perform actual JOIN + operations on the underlying table with jOOQ, once the master data + type is generated.
+
+ When using a custom type in jOOQ, you need to let jOOQ know about
+ its associated
+ The above conversion implies that you may want to use a GregorianCalendar for + SQL timestamps, rather than the timestamp type itself. You could then write + a Converter like this: +
+ ++ Such a Converter can now be used in various places of the jOOQ + API, especially when reading data from the database: +
+ ++ A more common use-case, however, is to let jOOQ know about custom + types at code generation time. Use the following configuration elements + to specify, that you'd like to use GregorianCalendar for all database + fields that start with DATE_OF_ +
+ ++ The above configuration will lead to T_AUTHOR.DATE_OF_BIRTH + being generated like this: +
+ +
+ This means that the bound of <T> will be GregorianCalendar,
+ wherever you reference DATE_OF_BIRTH. jOOQ will use your custom
+ converter when binding variables and when fetching data from
+
+ Read more about advanced code generation configuration in
+
+ Java's Enum types can be very useful in SQL too.
+ Some databases support enumeration types natively (MySQL, Postgres).
+ In other cases, you can use the above custom type configuration
+ also to provide jOOQ with Converters for your custom Enum types.
+ Instead of implementing
You may wish to design your database in a way that you have several + instances of your schema. This is useful when you want to cleanly + separate data belonging to several customers / organisation units / + branches / users and put each of those entities' data in a separate + database or schema.
+In our T_AUTHOR example this would mean that you provide a book + reference database to several companies, such as My Book World and + Books R Us. In that case, you'll probably have a schema setup like + this:
+When a user from My Book World logs in, you want them to access the
+ MY_BOOK_WORLD schema using classes generated from DEV. This can be
+ achieved with the
+
The query executed with a Factory equipped with the above mapping + will in fact produce this SQL statement:
+Even if T_AUTHOR was generated from DEV.
+ +Your development database may not be restricted to hold only one DEV + schema. You may also have a LOG schema and a MASTER schema. Let's say + the MASTER schema is shared among all customers, but each customer has + their own LOG schema instance. Then you can enhance your RenderMapping + like this (e.g. using an XML configuration file):
+ +Note, you can load the above XML file like this:
+ +This will map generated classes from DEV to MY_BOOK_WORLD, from LOG + to MY_BOOK_WORLD_LOG, but leave the MASTER schema alone. Whenever you + want to change your mapping configuration, you will have to create a + new Factory
+ + +Another option to switch schema names is to use a default schema for + the Factory's underlying Connection. Many RDBMS support a USE or SET + SCHEMA command, which you can call like this:
+ +Queries generated from the above Factory will produce this kind of SQL statement:
+ +If you wish not to render any schema name at all, use the + following Settings property for this:
+ + +Not only schemata can be mapped, but also tables. If you are not the + owner of the database your application connects to, you might need to + install your schema with some sort of prefix to every table. In our + examples, this might mean that you will have to map DEV.T_AUTHOR to + something MY_BOOK_WORLD.MY_APP__T_AUTHOR, where MY_APP__ is a prefix + applied to all of your tables. This can be achieved by creating the + following mapping:
+ +The query executed with a Factory equipped with the above mapping will in fact produce this SQL statement:
++ Table mapping and schema mapping can be applied independently, by specifying several MappedSchema entries + in the above configuration. jOOQ will process them in order of appearance and map at first match. Note that + you can always omit a MappedSchema's output value, in case of which, only the table mapping is applied. + If you omit a MappedSchema's input value, the table mapping is applied to all schemata! +
+ ++ Note that you can also hard-wire schema mapping in generated artefacts + at code generation time, e.g. when you have 5 developers with their own + dedicated developer databases, and a common integration database. In the + code generation configuration, you would then write. +
+
+ See the manual's section about
+
+ The
+ Here is a sample implementation of an ExecuteListener, that is simply counting + the number of queries per type that are being executed using jOOQ: +
+ ++ Now, configure jOOQ's runtime to load your listener +
+ ++ And log results any time with a snippet like this: +
+ ++ This may result in the following log output: +
+ ++ Please read the + ExecuteListener Javadoc + for more details +
+ ++ The ExecuteListener API was driven by a feature request by Christopher Deckers, who has + had the courtesy to contribute the jOOQ Console, a sample application interfacing + with jOOQ's ExecuteListeners. The jOOQ Console logs all queries executed by jOOQ and + displays them nicely in a Swing application. With the jOOQ Console's logger, you can: +
++ A short overview of such a debugging session can be seen here: +
+
+ + Please note that the jOOQ Console is still experimental. + Any feedback is very welcome on + the jooq-user group +
++ The jOOQ Console can be run in two different modes: +
+
+ Both modes will require that you set the
+
+ Or when using programmatic settings: +
++ The in-process mode is useful for Swing applications or other, + locally run Java programs accessing the database via jOOQ. + In order to launch the jOOQ Console "in-process", specify the + previously documented settings and launch the Console as follows: +
+ ++ Only in the in-process mode, you can execute ad-hoc queries directly + from the console, if you provide it with proper DatabaseDescriptor. + These queries are executed from the Editor pane which features: +
+
+ + In J2EE or other server/client environments, you may not be able + to run the console in the same process as your application. You + can then run the jOOQ Console in "headless" mode. In addition to + the previously documented settings, you'll have to start a + debugger server in your application process, that the console can + connect to: +
+ ++ Now start your application along with the debugger server + and launch the console with this command: +
+ ++ Depending on your distribution, you may have to manually add + rsyntaxtextarea-1.5.0.jar and jOOQ artefacts on your classpath. +
+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:
+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
+If you are closely coupling your application to an Oracle (or CUBRID) database, + you can take advantage of some Oracle-specific features, such as the + CONNECT BY clause, used for hierarchical queries. The formal syntax + definition is as follows:
+ +This can be done in jOOQ using the .connectBy(Condition) clauses in your SELECT statement:
+Here's a more complex example where you can recursively fetch + directories in your database, and concatenate them to a path:
+The output might then look like this
+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:
+
+ The PIVOT clause is available from the
+
+ There is one operation in relational algebra that is not given + a lot of attention, because it is rarely used in real-world + applications. It is the relational division, the opposite operation + of the cross product (or, relational multiplication). + The following is an approximate definition of a relational division: +
+ ++ With jOOQ, you can simplify using relational divisions + by using the following syntax: +
+ +The above roughly translates to
+ ++ Or in plain text: Find those TEXT values in C + whose ID's correspond to all ID's in B. Note + that from the above SQL statement, it is immediately + clear that proper indexing is of the essence. + Be sure to have indexes on all columns referenced + from the on(...) and returning(...) clauses. +
+ ++ For more information about relational division + and some nice, real-life examples, see +
+ + +If you are using jOOQ for scripting purposes or in a slim, unlayered + application server, you might be interested in using jOOQ's exporting + functionality (see also importing functionality). You can export any + Result<Record> into any of these formats:
+ +Export your results as XML:
+The above query will result in an XML document looking like the following one:
+Export your results as CSV:
+The above query will result in a CSV document looking like the following one:
+Export your results as JSON:
+ +The above query will result in a JSON document looking like the following one:
+Export your results as HTML:
+The above query will result in an HTML document looking like the following one:
+Export your results as text:
+The above query will result in a text document looking like the following one:
+If you are using jOOQ for scripting purposes or in a slim, unlayered + application server, you might be interested in using jOOQ's importing + functionality (see also exporting functionality). You can import data + directly into a table from any of these formats:
+ +The below CSV data represents two author records that may have been + exported previously, by jOOQ's exporting functionality, and then + modified in Microsoft Excel or any other spreadsheet tool:
+ +With jOOQ, you can load this data using various parameters from the + loader API. A simple load may look like this:
+ +Here are various other examples:
+Any of the above configuration methods can be combined to achieve + the type of load you need. Please refer to the API's Javadoc to learn + about more details. Errors that occur during the load are reported by + the execute method's result:
+ +This will be implemented soon...
+With JDBC, you can easily execute several statements at once using + the addBatch() method. Essentially, there are two modes in JDBC
+ +In code, this looks like the following snippet:
+jOOQ supports executing queries in batch + mode as follows:
+