diff --git a/jOOQ-website/css/jooq.css b/jOOQ-website/css/jooq.css index 01a1989e84..92cab93cb8 100644 --- a/jOOQ-website/css/jooq.css +++ b/jOOQ-website/css/jooq.css @@ -120,7 +120,7 @@ a:hover { } #wrapper { - background: url("../img/bodytile.jpg") repeat scroll left top #FFFFFF; + background: url("../img/bg.jpg") repeat scroll left top #FFFFFF; height: auto; min-height: 101%; } @@ -146,7 +146,6 @@ a:hover { 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 { diff --git a/jOOQ-website/frame.php b/jOOQ-website/frame.php index e2f2d725a9..e09c9193cf 100644 --- a/jOOQ-website/frame.php +++ b/jOOQ-website/frame.php @@ -77,7 +77,6 @@ if ($slogan != '') { print '

' . $slogan . '

'; } - printContent(); ?> diff --git a/jOOQ-website/img/bg.jpg b/jOOQ-website/img/bg.jpg new file mode 100644 index 0000000000..4847ebea0a Binary files /dev/null and b/jOOQ-website/img/bg.jpg differ diff --git a/jOOQ-website/img/bodytile.jpg b/jOOQ-website/img/bodytile.jpg index 7c0ef3d09c..fb794a468e 100644 Binary files a/jOOQ-website/img/bodytile.jpg and b/jOOQ-website/img/bodytile.jpg differ diff --git a/jOOQ-website/manual/ADVANCED/CONNECTBY/index.php b/jOOQ-website/manual/ADVANCED/CONNECTBY/index.php index 274265e102..ffa6793038 100644 --- a/jOOQ-website/manual/ADVANCED/CONNECTBY/index.php +++ b/jOOQ-website/manual/ADVANCED/CONNECTBY/index.php @@ -16,6 +16,10 @@ function printContent() { The jOOQ User Manual : Advanced topics : The Oracle CONNECT BY clause for hierarchical queriesprevious : next +
+ + +
The jOOQ User Manual : Advanced topics : The Oracle CONNECT BY clause for hierarchical queriesprevious : next
The jOOQ User Manual : Advanced topics : Exporting data to XML, CSV, JSON, HTML, Textprevious : next +
+ + +
The jOOQ User Manual : Advanced topics : Exporting data to XML, CSV, JSON, HTML, Textprevious : next
The jOOQ User Manual : Advanced topics : Importing data from XML, CSVprevious +
+ + +
The jOOQ User Manual : Advanced topics : Importing data from XML, CSVprevious
The jOOQ User Manual : Advanced topics : Master data generationprevious : next +
+ + +
The jOOQ User Manual : Advanced topics : Master data generationprevious : next
The jOOQ User Manual : Advanced topics : Adding Oracle hints to queriesprevious : next +
+ + +
The jOOQ User Manual : Advanced topics : Adding Oracle hints to queriesprevious : next
The jOOQ User Manual : Advanced topics : Mapping generated schemata and tables to productive environmentsprevious : next +
+ + +
The jOOQ User Manual : Advanced topics : Mapping generated schemata and tables to productive environmentsprevious : next
Importing data from XML, CSV - +
+ + + +
The jOOQ User Manual : Advanced topicsprevious : next
diff --git a/jOOQ-website/manual/DSL/ALIAS/index.php b/jOOQ-website/manual/DSL/ALIAS/index.php index aafb3d88e4..b9878c635f 100644 --- a/jOOQ-website/manual/DSL/ALIAS/index.php +++ b/jOOQ-website/manual/DSL/ALIAS/index.php @@ -16,6 +16,10 @@ function printContent() { The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Aliased tables and fieldsprevious : next +
+ + +
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Aliased tables and fieldsprevious : next
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Arithmetic operationsprevious : next +
+ + +
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Arithmetic operationsprevious : next
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : The CASE clauseprevious : next +
+ + +
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : The CASE clauseprevious : next
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Type castingprevious : next +
+ + +
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Type castingprevious : next
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Conditionsprevious : next +
+ + +
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Conditionsprevious : next
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Nested select statements using the EXISTS operatorprevious : next +
+ + +
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Nested select statements using the EXISTS operatorprevious : next
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Functions, aggregate operators, and window functionsprevious : next +
+ + +
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Functions, aggregate operators, and window functionsprevious : next
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Nested select statements using the IN operatorprevious : next +
+ + +
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Nested select statements using the IN operatorprevious : next
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Other types of nested selectsprevious : next +
+ + +
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Other types of nested selectsprevious : next
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Stored procedures and functionsprevious : next +
+ + +
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Stored procedures and functionsprevious : next
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Complete SELECT syntaxprevious : next +
+ + +
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : Complete SELECT syntaxprevious : next
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : When it's just much easier: Plain SQLprevious : next +
+ + +
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : When it's just much easier: Plain SQLprevious : next
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : UNION and other set operationsprevious : next +
+ + +
The jOOQ User Manual : DSL or fluent API. Where SQL meets Java : UNION and other set operationsprevious : next
When it's just much easier: Plain SQL - +
+ + + +
The jOOQ User Manual : DSL or fluent API. Where SQL meets Javaprevious : next
diff --git a/jOOQ-website/manual/JOOQ/ExampleDatabase/index.php b/jOOQ-website/manual/JOOQ/ExampleDatabase/index.php index 7f133c9b49..0515053eb0 100644 --- a/jOOQ-website/manual/JOOQ/ExampleDatabase/index.php +++ b/jOOQ-website/manual/JOOQ/ExampleDatabase/index.php @@ -70,7 +70,12 @@ CREATE TABLE t_book_to_book_store ( More entities, types (e.g. UDT's, ARRAY types, ENUM types, etc), stored procedures and packages are introduced for specific examples

- +
+ + + +
The jOOQ User Manual : jOOQ classes and their usage : The example databaseprevious : next
+ diff --git a/jOOQ-website/manual/JOOQ/Extend/index.php b/jOOQ-website/manual/JOOQ/Extend/index.php index 3eabc1e3f6..1ec767c00b 100644 --- a/jOOQ-website/manual/JOOQ/Extend/index.php +++ b/jOOQ-website/manual/JOOQ/Extend/index.php @@ -59,7 +59,12 @@ public void bind(BindContext context) throws SQLException; Plain SQL functionality, where you can provide jOOQ with a simple String representation of your embedded SQL.

- +
+ + + +
The jOOQ User Manual : jOOQ classes and their usage : Extend jOOQ with custom typesprevious : next
+ diff --git a/jOOQ-website/manual/JOOQ/Factory/index.php b/jOOQ-website/manual/JOOQ/Factory/index.php index 17af71aec5..af7d3ad9ce 100644 --- a/jOOQ-website/manual/JOOQ/Factory/index.php +++ b/jOOQ-website/manual/JOOQ/Factory/index.php @@ -148,7 +148,12 @@ MySQLFactory create = new MySQLFactory(connection); that can perform CRUD operations on the Factory's underlying Connection.

- +
+ + + +
The jOOQ User Manual : jOOQ classes and their usage : The Factory classprevious : next
+ diff --git a/jOOQ-website/manual/JOOQ/Query/index.php b/jOOQ-website/manual/JOOQ/Query/index.php index 442efb6f52..beaf0a1f80 100644 --- a/jOOQ-website/manual/JOOQ/Query/index.php +++ b/jOOQ-website/manual/JOOQ/Query/index.php @@ -496,7 +496,12 @@ create.mergeInto(T_AUTHOR)

This is not supported by Ingres and SQLite. jOOQ will execute a DELETE FROM T_AUTHOR statement instead.

- +
+ + + +
The jOOQ User Manual : jOOQ classes and their usage : The Query and its various subtypesprevious : next
+ diff --git a/jOOQ-website/manual/JOOQ/QueryPart/index.php b/jOOQ-website/manual/JOOQ/QueryPart/index.php index e3f9fb10d9..badb74a4b6 100644 --- a/jOOQ-website/manual/JOOQ/QueryPart/index.php +++ b/jOOQ-website/manual/JOOQ/QueryPart/index.php @@ -18,6 +18,10 @@ function printContent() { The jOOQ User Manual : jOOQ classes and their usage : QueryParts and the global architectureprevious : next +
+ + +
The jOOQ User Manual : jOOQ classes and their usage : QueryParts and the global architectureprevious : next
- +
+ + + +
The jOOQ User Manual : jOOQ classes and their usage : Results and Recordsprevious : next
+ diff --git a/jOOQ-website/manual/JOOQ/ResultQuery/index.php b/jOOQ-website/manual/JOOQ/ResultQuery/index.php index 58cb256fbe..4b876f1eb5 100644 --- a/jOOQ-website/manual/JOOQ/ResultQuery/index.php +++ b/jOOQ-website/manual/JOOQ/ResultQuery/index.php @@ -97,7 +97,12 @@ public interface ResultQuery<R extends Record> { FutureResult<R> fetchLater(); FutureResult<R> fetchLater(ExecutorService executor); } - +
+ + + +
The jOOQ User Manual : jOOQ classes and their usage : ResultQuery and various ways of fetching dataprevious : next
+ diff --git a/jOOQ-website/manual/JOOQ/Serializability/index.php b/jOOQ-website/manual/JOOQ/Serializability/index.php index 3eb0a9a7a6..e91b521555 100644 --- a/jOOQ-website/manual/JOOQ/Serializability/index.php +++ b/jOOQ-website/manual/JOOQ/Serializability/index.php @@ -68,7 +68,12 @@ ConfigurationRegistry.setProvider(provider); - +
+ + + +
The jOOQ User Manual : jOOQ classes and their usage : Serializability of QueryParts and Resultsprevious : next
+ diff --git a/jOOQ-website/manual/JOOQ/Table/index.php b/jOOQ-website/manual/JOOQ/Table/index.php index a43469aa58..c7d8cbef0b 100644 --- a/jOOQ-website/manual/JOOQ/Table/index.php +++ b/jOOQ-website/manual/JOOQ/Table/index.php @@ -143,7 +143,12 @@ function printContent() {

This can be used for additional type safety in the future, or by client code.

- +
+ + + +
The jOOQ User Manual : jOOQ classes and their usage : Tables and Fieldsprevious : next
+ diff --git a/jOOQ-website/manual/JOOQ/UpdatableRecord/index.php b/jOOQ-website/manual/JOOQ/UpdatableRecord/index.php index 64383fc944..e4b9e21193 100644 --- a/jOOQ-website/manual/JOOQ/UpdatableRecord/index.php +++ b/jOOQ-website/manual/JOOQ/UpdatableRecord/index.php @@ -88,7 +88,12 @@ book.storeUsing(TBook.ID); // Delete it book.deleteUsing(TBook.ID); - +
+ + + +
The jOOQ User Manual : jOOQ classes and their usage : Updatable Recordsprevious : next
+ diff --git a/jOOQ-website/manual/JOOQ/index.php b/jOOQ-website/manual/JOOQ/index.php index 459015cc6b..127e3325ae 100644 --- a/jOOQ-website/manual/JOOQ/index.php +++ b/jOOQ-website/manual/JOOQ/index.php @@ -74,7 +74,11 @@ function printContent() {
  • Extend jOOQ with custom types
  • - +
    + + + +
    The jOOQ User Manual : jOOQ classes and their usageprevious : next
    diff --git a/jOOQ-website/manual/META/Configuration/index.php b/jOOQ-website/manual/META/Configuration/index.php index a2f202f12a..e57524b7a5 100644 --- a/jOOQ-website/manual/META/Configuration/index.php +++ b/jOOQ-website/manual/META/Configuration/index.php @@ -214,7 +214,12 @@ org.jooq.util.GenerationTool /jooq-config.properties

    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.

    - +
    + + + +
    The jOOQ User Manual : Meta model code generation : Configuration and setup of the generatorprevious : next
    + diff --git a/jOOQ-website/manual/META/PROCEDURE/index.php b/jOOQ-website/manual/META/PROCEDURE/index.php index 3ee8972256..3fe3ff810e 100644 --- a/jOOQ-website/manual/META/PROCEDURE/index.php +++ b/jOOQ-website/manual/META/PROCEDURE/index.php @@ -199,7 +199,12 @@ assertEquals(BigDecimal.ONE, Procedures.pAuthorExists(configuration, "Paulo"));< one for standalone procedures/functions.

    - +
    + + + +
    The jOOQ User Manual : Meta model code generation : Procedures and packagesprevious : next
    + diff --git a/jOOQ-website/manual/META/SCHEMA/index.php b/jOOQ-website/manual/META/SCHEMA/index.php index 3ba31f9c90..528505f499 100644 --- a/jOOQ-website/manual/META/SCHEMA/index.php +++ b/jOOQ-website/manual/META/SCHEMA/index.php @@ -51,7 +51,12 @@ function printContent() {
     public final java.util.List<org.jooq.Sequence> getSequences();
     public final java.util.List<org.jooq.Table<?>> getTables();
    - +
    + + + +
    The jOOQ User Manual : Meta model code generation : The schema, top-level generated artefactprevious : next
    + diff --git a/jOOQ-website/manual/META/SEQUENCE/index.php b/jOOQ-website/manual/META/SEQUENCE/index.php index 86d8a08f78..5fe074af5c 100644 --- a/jOOQ-website/manual/META/SEQUENCE/index.php +++ b/jOOQ-website/manual/META/SEQUENCE/index.php @@ -16,6 +16,10 @@ function printContent() { The jOOQ User Manual : Meta model code generation : Sequencesprevious : next +
    + + +
    The jOOQ User Manual : Meta model code generation : Sequencesprevious : next
    - +
    + + + +
    The jOOQ User Manual : Meta model code generation : Tables, views and their corresponding recordsprevious : next
    + diff --git a/jOOQ-website/manual/META/UDT/index.php b/jOOQ-website/manual/META/UDT/index.php index 76eca7c6d5..2f71548304 100644 --- a/jOOQ-website/manual/META/UDT/index.php +++ b/jOOQ-website/manual/META/UDT/index.php @@ -7,7 +7,11 @@ function printH1() { print "UDT's including ARRAY and ENUM types"; } function getSlogan() { - return ""; + return " + Databases become more powerful when you can structure your data in user + defined types. It's time for Java developers to give some credit to + that. + "; } function printContent() { global $root; @@ -16,6 +20,317 @@ function printContent() { The jOOQ User Manual : Meta model code generation : UDT's including ARRAY and ENUM typesprevious : next + +

    Increased RDBMS support for UDT's

    +

    + 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 + stored procedures, of course) across all + RDBMS, where these types are supported.

    + +

    UDT types

    +

    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:

    +
    +CREATE TYPE u_street_type AS OBJECT (
    +  street VARCHAR2(100),
    +  no VARCHAR2(30)
    +)
    +
    +CREATE TYPE u_address_type AS OBJECT (
    +  street u_street_type,
    +  zip VARCHAR2(50),
    +  city VARCHAR2(50),
    +  country VARCHAR2(50),
    +  since DATE,
    +  code NUMBER(7)
    +)
    + +

    These types could then be used in tables and/or stored procedures like such:

    +
    +CREATE TABLE t_author (
    +  id NUMBER(7) NOT NULL PRIMARY KEY,
    +  -- [...]
    +  address u_address_type
    +)
    +
    +CREATE OR REPLACE PROCEDURE p_check_address (address IN OUT u_address_type);
    + +

    + Standard JDBC UDT support encourages JDBC-driver developers to implement + interfaces such as + java.sql.SQLData, + java.sql.SQLInput and + java.sql.SQLOutput. + Those interfaces are non-trivial to implement, or + to hook into. Also access to + java.sql.Struct + is not really simple. Due + to the lack of a well-defined JDBC standard, Oracle's JDBC driver + rolls their own proprietary methods of dealing with these types. jOOQ + goes a different way, it hides those facts from you entirely. With + jOOQ, the above UDT's will be generated in simple + UDT meta-model classes and + UDT record classes as such: +

    +
    +// There is an analogy between UDT/Table and UDTRecord/TableRecord...
    +public class UAddressType extends UDTImpl<UAddressTypeRecord> {
    +
    +    // The UDT meta-model singleton instance
    +    public static final UAddressType U_ADDRESS_TYPE = new UAddressType();
    +
    +    // UDT attributes are modeled as static members. Nested UDT's
    +    // behave similarly
    +    public static final UDTField<UAddressTypeRecord, UStreetTypeRecord> STREET = // [...]
    +    public static final UDTField<UAddressTypeRecord, String> ZIP =               // [...]
    +    public static final UDTField<UAddressTypeRecord, String> CITY =              // [...]
    +    public static final UDTField<UAddressTypeRecord, String> COUNTRY =           // [...]
    +    public static final UDTField<UAddressTypeRecord, Date> SINCE =               // [...]
    +    public static final UDTField<UAddressTypeRecord, Integer> CODE =             // [...]
    +}
    + +

    Now, when you interact with entities or procedures that hold UDT's, that's very simple as well. Here is an example:

    +
    +// Fetch any author from the T_AUTHOR table
    +TAuthorRecord author = create.selectFrom(T_AUTHOR).fetchAny();
    +
    +// Print out the author's address's house number
    +System.out.println(author.getAddress().getStreet().getNo());
    + +

    A similar thing can be achieved when interacting with the example stored procedure:

    +
    +// Create a new UDTRecord of type U_ADDRESS_TYPE
    +UAddressTypeRecord address = new UAddressTypeRecord();
    +address.setCountry("Switzerland");
    +
    +// Call the stored procedure with IN OUT parameter of type U_ADDRESS_TYPE
    +address = Procedures.pCheckAddress(connection, address);
    + + +

    ARRAY types

    +

    + 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. +

    + +

    Example: General ARRAY types

    +

    An example usage of ARRAYs is given here for the Postgres dialect

    + +
    +CREATE TABLE t_arrays (
    +  id integer not null primary key,
    +  string_array VARCHAR(20)[],
    +  number_array INTEGER[]
    +)
    +
    +CREATE FUNCTION f_arrays(in_array IN text[]) RETURNS text[]
    + +

    When generating source code from the above entities, these artefacts will be created in Java:

    +
    +public class TArrays extends UpdatableTableImpl<TArraysRecord> {
    +
    +    // The generic type parameter <T> is bound to an array of a matching type
    +    public static final TableField<TArraysRecord, String[]> STRING_ARRAY =  // [...]
    +    public static final TableField<TArraysRecord, Integer[]> NUMBER_ARRAY = // [...]
    +}
    +
    +// The convenience class is enhanced with these methods
    +public final class Functions {
    +    public static String[] fArrays(Connection connection, String[] inArray) throws SQLException { // [...]
    +    public static Field<String[]> fArrays(String[] inArray) {                                     // [...]
    +    public static Field<String[]> fArrays(Field<String[]> inArray) {                              // [...]
    +}
    + +

    Example: Oracle VARRAY types

    +

    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:

    + +
    +CREATE TYPE u_string_array AS VARRAY(4) OF VARCHAR2(20)
    +CREATE TYPE u_number_array AS VARRAY(4) OF NUMBER(7)
    +
    +CREATE TABLE t_arrays (
    +  id NUMBER(7) not null primary key,
    +  string_array u_string_array,
    +  number_array u_number_array
    +)
    +
    +CREATE OR REPLACE FUNCTION f_arrays (in_array u_string_array)
    +RETURN u_string_array
    + +

    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 + org.jooq.ArrayRecord and other + artefacts in Oracle:

    + +
    +public class UStringArrayRecord extends ArrayRecordImpl<String> {  // [...]
    +public class UNumberArrayRecord extends ArrayRecordImpl<Integer> { // [...]
    +
    +public class TArrays extends UpdatableTableImpl<TArraysRecord> {
    +    public static final TableField<TArraysRecord, UStringArrayRecord> STRING_ARRAY = // [...]
    +    public static final TableField<TArraysRecord, UNumberArrayRecord> NUMBER_ARRAY = // [...]
    +}
    +
    +public final class Functions {
    +    public static UStringArrayRecord fArrays3(Connection connection, UStringArrayRecord inArray) { // [...]
    +    public static Field<UStringArrayRecord> fArrays3(UStringArrayRecord inArray) {                 // [...]
    +    public static Field<UStringArrayRecord> fArrays3(Field<UStringArrayRecord> inArray) {          // [...]
    +}
    + + +

    ENUM types

    +

    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:

    +
    +-- An example enum type
    +CREATE TYPE u_book_status AS ENUM ('SOLD OUT', 'ON STOCK', 'ORDERED')
    +
    +-- An example useage of that enum type
    +CREATE TABLE t_book (
    +  id INTEGER NOT NULL PRIMARY KEY,
    +
    +  -- [...]
    +  status u_book_status
    +)
    + +

    The above Postgres ENUM type will be generated as

    +
    +public enum UBookStatus implements EnumType {
    +    ORDERED("ORDERED"),
    +    ON_STOCK("ON STOCK"),
    +    SOLD_OUT("SOLD OUT");
    +
    +    // [...]
    +}
    +

    Intuitively, the generated classes for the T_BOOK table in Postgres would look like this:

    +
    +// The meta-model class
    +public class TBook extends UpdatableTableImpl<TBookRecord> {
    +
    +    // The TableField STATUS binds <T> to UBookStatus
    +    public static final TableField<TBookRecord, UBookStatus> STATUS = // [...]
    +
    +    // [...]
    +}
    +
    +// The record class
    +public class TBookRecord extends UpdatableRecordImpl<TBookRecord> {
    +
    +    // Corresponding to the Table meta-model, also setters and getters
    +    // deal with the generated UBookStatus
    +    public void setStatus(UBookStatus value) { // [...]
    +    public UBookStatus getStatus() {           // [...]
    +}
    + +

    Note that jOOQ allows you to simulate ENUM types where this makes + sense in your data model. See the section on + master data for more + details.

    +
    + + +
    The jOOQ User Manual : Meta model code generation : UDT's including ARRAY and ENUM typesprevious : next
    Sequences - +
    + + + +
    The jOOQ User Manual : Meta model code generationprevious : next
    diff --git a/jOOQ-website/manual/index.php b/jOOQ-website/manual/index.php index c511d727ba..4c07716db8 100644 --- a/jOOQ-website/manual/index.php +++ b/jOOQ-website/manual/index.php @@ -205,7 +205,11 @@ function printContent() { - +
    + + + +
    The jOOQ User Manualnext
    diff --git a/jOOQ-website/src/main/resources/html-pages.xsl b/jOOQ-website/src/main/resources/html-pages.xsl index 589a7835ae..de19a8c3a4 100644 --- a/jOOQ-website/src/main/resources/html-pages.xsl +++ b/jOOQ-website/src/main/resources/html-pages.xsl @@ -44,6 +44,19 @@ function printContent() { + + + + +

    Table of contents

    +
    + + +
    + +
    + +
    @@ -54,14 +67,6 @@ function printContent() {
    - - - - - -

    Table of contents

    -
    -
    diff --git a/jOOQ-website/src/main/resources/manual.xml b/jOOQ-website/src/main/resources/manual.xml index 5b5e9048e8..3f770b6968 100644 --- a/jOOQ-website/src/main/resources/manual.xml +++ b/jOOQ-website/src/main/resources/manual.xml @@ -1680,7 +1680,297 @@ assertEquals(BigDecimal.ONE, Procedures.pAuthorExists(configuration, "Paulo"));<
    UDT's including ARRAY and ENUM types + + Databases become more powerful when you can structure your data in user + defined types. It's time for Java developers to give some credit to + that. + + +

    Increased RDBMS support for UDT's

    +

    + 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: +

    +
      +
    • They are usually orthogonal to relational concepts. It is not easy + to modify a UDT once it is referenced by a table column.
    • +
    • There is little standard support of accessing them from JDBC (and + probably other database connectivity standards).
    • +
    +

    + 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 + , of course) across all + RDBMS, where these types are supported.

    + +

    UDT types

    +

    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:

    +
      +
    • Oracle
    • +
    • Postgres
    • +
    +

    Apart from that,

    +
      +
    • + DB2 UDT's are not supported as they are very tough to + serialise/deserialise. We don't think that this is a big enough + requirement to put more effort in those, right now (see also the + developers' discussion on + ) +
    • +
    + +

    In Oracle, you would define UDTs like this:

    +
    +CREATE TYPE u_street_type AS OBJECT (
    +  street VARCHAR2(100),
    +  no VARCHAR2(30)
    +)
    +
    +CREATE TYPE u_address_type AS OBJECT (
    +  street u_street_type,
    +  zip VARCHAR2(50),
    +  city VARCHAR2(50),
    +  country VARCHAR2(50),
    +  since DATE,
    +  code NUMBER(7)
    +)
    + +

    These types could then be used in tables and/or stored procedures like such:

    +
    +CREATE TABLE t_author (
    +  id NUMBER(7) NOT NULL PRIMARY KEY,
    +  -- [...]
    +  address u_address_type
    +)
    +
    +CREATE OR REPLACE PROCEDURE p_check_address (address IN OUT u_address_type);
    + +

    + Standard JDBC UDT support encourages JDBC-driver developers to implement + interfaces such as + , + and + . + Those interfaces are non-trivial to implement, or + to hook into. Also access to + + is not really simple. Due + to the lack of a well-defined JDBC standard, Oracle's JDBC driver + rolls their own proprietary methods of dealing with these types. jOOQ + goes a different way, it hides those facts from you entirely. With + jOOQ, the above UDT's will be generated in simple + and + as such: +

    +
    +// There is an analogy between UDT/Table and UDTRecord/TableRecord...
    +public class UAddressType extends UDTImpl<UAddressTypeRecord> {
    +
    +    // The UDT meta-model singleton instance
    +    public static final UAddressType U_ADDRESS_TYPE = new UAddressType();
    +
    +    // UDT attributes are modeled as static members. Nested UDT's
    +    // behave similarly
    +    public static final UDTField<UAddressTypeRecord, UStreetTypeRecord> STREET = // [...]
    +    public static final UDTField<UAddressTypeRecord, String> ZIP =               // [...]
    +    public static final UDTField<UAddressTypeRecord, String> CITY =              // [...]
    +    public static final UDTField<UAddressTypeRecord, String> COUNTRY =           // [...]
    +    public static final UDTField<UAddressTypeRecord, Date> SINCE =               // [...]
    +    public static final UDTField<UAddressTypeRecord, Integer> CODE =             // [...]
    +}
    + +

    Now, when you interact with entities or procedures that hold UDT's, that's very simple as well. Here is an example:

    +
    +// Fetch any author from the T_AUTHOR table
    +TAuthorRecord author = create.selectFrom(T_AUTHOR).fetchAny();
    +
    +// Print out the author's address's house number
    +System.out.println(author.getAddress().getStreet().getNo());
    + +

    A similar thing can be achieved when interacting with the example stored procedure:

    +
    +// Create a new UDTRecord of type U_ADDRESS_TYPE
    +UAddressTypeRecord address = new UAddressTypeRecord();
    +address.setCountry("Switzerland");
    +
    +// Call the stored procedure with IN OUT parameter of type U_ADDRESS_TYPE
    +address = Procedures.pCheckAddress(connection, address);
    + + +

    ARRAY types

    +

    + 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: +

    +
      +
    • Oracle: VARRAY OF VARCHAR2. A strongly typed object encapsulating an ARRAY of a given type. See the documentation.
    • +
    • Postgres: text[]. Any data type can be turned into an array by suffixing it with []. See the documentation
    • +
    • HSQLDB: VARCHAR ARRAY. Any data type can be turned into an array by suffixing it with ARRAY. See the documentation
    • +
    • H2: ARRAY. H2 does not know of typed arrays. All ARRAYs are mapped to Object[]. See the documentation
    • +
    +

    Soon to be supported:

    +
      +
    • DB2: Knows a similar strongly-typed ARRAY type, like Oracle
    • +
    +

    + 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. +

    + +

    Example: General ARRAY types

    +

    An example usage of ARRAYs is given here for the Postgres dialect

    + +
    +CREATE TABLE t_arrays (
    +  id integer not null primary key,
    +  string_array VARCHAR(20)[],
    +  number_array INTEGER[]
    +)
    +
    +CREATE FUNCTION f_arrays(in_array IN text[]) RETURNS text[]
    + +

    When generating source code from the above entities, these artefacts will be created in Java:

    +
    +public class TArrays extends UpdatableTableImpl<TArraysRecord> {
    +
    +    // The generic type parameter <T> is bound to an array of a matching type
    +    public static final TableField<TArraysRecord, String[]> STRING_ARRAY =  // [...]
    +    public static final TableField<TArraysRecord, Integer[]> NUMBER_ARRAY = // [...]
    +}
    +
    +// The convenience class is enhanced with these methods
    +public final class Functions {
    +    public static String[] fArrays(Connection connection, String[] inArray) throws SQLException { // [...]
    +    public static Field<String[]> fArrays(String[] inArray) {                                     // [...]
    +    public static Field<String[]> fArrays(Field<String[]> inArray) {                              // [...]
    +}
    + +

    Example: Oracle VARRAY types

    +

    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:

    + +
    +CREATE TYPE u_string_array AS VARRAY(4) OF VARCHAR2(20)
    +CREATE TYPE u_number_array AS VARRAY(4) OF NUMBER(7)
    +
    +CREATE TABLE t_arrays (
    +  id NUMBER(7) not null primary key,
    +  string_array u_string_array,
    +  number_array u_number_array
    +)
    +
    +CREATE OR REPLACE FUNCTION f_arrays (in_array u_string_array)
    +RETURN u_string_array
    + +

    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 + and other + artefacts in Oracle:

    + +
    +public class UStringArrayRecord extends ArrayRecordImpl<String> {  // [...]
    +public class UNumberArrayRecord extends ArrayRecordImpl<Integer> { // [...]
    +
    +public class TArrays extends UpdatableTableImpl<TArraysRecord> {
    +    public static final TableField<TArraysRecord, UStringArrayRecord> STRING_ARRAY = // [...]
    +    public static final TableField<TArraysRecord, UNumberArrayRecord> NUMBER_ARRAY = // [...]
    +}
    +
    +public final class Functions {
    +    public static UStringArrayRecord fArrays3(Connection connection, UStringArrayRecord inArray) { // [...]
    +    public static Field<UStringArrayRecord> fArrays3(UStringArrayRecord inArray) {                 // [...]
    +    public static Field<UStringArrayRecord> fArrays3(Field<UStringArrayRecord> inArray) {          // [...]
    +}
    + + +

    ENUM types

    +

    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.

    + +
      +
    • In MySQL, an ENUM type is declared directly upon a column. It cannot be reused as a type. See the documentation.
    • +
    • In Postgres, the ENUM type is declared independently and can be reused among tables, functions, etc. See the documentation.
    • +
    • Other RDMBS know about "ENUM constraints", such as the Oracle CHECK constraint. These are not true ENUMS, however. jOOQ refrains from using their information for source code generation
    • +
    + +

    Some examples:

    +
    +-- An example enum type
    +CREATE TYPE u_book_status AS ENUM ('SOLD OUT', 'ON STOCK', 'ORDERED')
    +
    +-- An example useage of that enum type
    +CREATE TABLE t_book (
    +  id INTEGER NOT NULL PRIMARY KEY,
    +
    +  -- [...]
    +  status u_book_status
    +)
    + +

    The above Postgres ENUM type will be generated as

    +
    +public enum UBookStatus implements EnumType {
    +    ORDERED("ORDERED"),
    +    ON_STOCK("ON STOCK"),
    +    SOLD_OUT("SOLD OUT");
    +
    +    // [...]
    +}
    +

    Intuitively, the generated classes for the T_BOOK table in Postgres would look like this:

    +
    +// The meta-model class
    +public class TBook extends UpdatableTableImpl<TBookRecord> {
    +
    +    // The TableField STATUS binds <T> to UBookStatus
    +    public static final TableField<TBookRecord, UBookStatus> STATUS = // [...]
    +
    +    // [...]
    +}
    +
    +// The record class
    +public class TBookRecord extends UpdatableRecordImpl<TBookRecord> {
    +
    +    // Corresponding to the Table meta-model, also setters and getters
    +    // deal with the generated UBookStatus
    +    public void setStatus(UBookStatus value) { // [...]
    +    public UBookStatus getStatus() {           // [...]
    +}
    + +

    Note that jOOQ allows you to simulate ENUM types where this makes + sense in your data model. See the section on + for more + details.

    +
    + +
    Sequences