Added some sections to the manual
This commit is contained in:
parent
441fd4c7a4
commit
9772af74f9
@ -49,7 +49,7 @@ h3 {
|
||||
}
|
||||
|
||||
pre {
|
||||
background: none repeat scroll 0 0 #ffeedd;
|
||||
background: none repeat scroll 0 0 #ffffff;
|
||||
border-radius: 10px 10px 10px 10px;
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
@ -166,7 +166,7 @@ a:hover {
|
||||
#navigation a:visited,
|
||||
#navigation a:hover,
|
||||
#navigation a:active {
|
||||
color: #ddcccc;
|
||||
color: #fadccb;
|
||||
text-decoration: none;
|
||||
text-shadow: 0 1px 1px #666666;
|
||||
}
|
||||
@ -189,3 +189,20 @@ div.tweet-item-left {
|
||||
padding-right: 2em;
|
||||
}
|
||||
|
||||
div.screenshot {
|
||||
background: none repeat scroll 0 0 #ffffff;
|
||||
border-radius: 10px 10px 10px 10px;
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
border-color: #882222;
|
||||
box-shadow: 5px 5px 20px #aa6633;
|
||||
color: #000000;
|
||||
display: block;
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
line-height: 1.5em;
|
||||
margin: 1.5em 0;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
text-align: center;
|
||||
}
|
||||
BIN
jOOQ-website/img/eclipse-example-01.png
Normal file
BIN
jOOQ-website/img/eclipse-example-01.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.5 KiB |
BIN
jOOQ-website/img/eclipse-example-02.png
Normal file
BIN
jOOQ-website/img/eclipse-example-02.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 56 KiB |
BIN
jOOQ-website/img/eclipse-example-03.png
Normal file
BIN
jOOQ-website/img/eclipse-example-03.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 60 KiB |
BIN
jOOQ-website/img/eclipse-example-04.png
Normal file
BIN
jOOQ-website/img/eclipse-example-04.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 72 KiB |
BIN
jOOQ-website/img/eclipse-example-05.png
Normal file
BIN
jOOQ-website/img/eclipse-example-05.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.2 KiB |
@ -4,20 +4,62 @@
|
||||
// Please do not edit this content manually
|
||||
require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Extend jOOQ types with custom implementations";
|
||||
print "Extend jOOQ with custom types";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
return "Maybe jOOQ is missing functionality that you would like to see,
|
||||
or you can't wait for the next release... In this case, you can extend
|
||||
any of the following open jOOQ implementation classes";
|
||||
}
|
||||
function printContent() {
|
||||
global $root;
|
||||
?>
|
||||
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/JOOQ/">jOOQ classes and their usage</a> : <a href="<?=$root?>/manual/JOOQ/Extend/">Extend jOOQ types with custom implementations</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/JOOQ/Serializability/" title="Previous section: Serializability of QueryParts and Results">previous</a> : <a href="<?=$root?>/manual/META/" title="Next section: Meta model code generation">next</a></td>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/JOOQ/">jOOQ classes and their usage</a> : <a href="<?=$root?>/manual/JOOQ/Extend/">Extend jOOQ with custom types</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/JOOQ/Serializability/" title="Previous section: Serializability of QueryParts and Results">previous</a> : <a href="<?=$root?>/manual/META/" title="Next section: Meta model code generation">next</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</table>
|
||||
<h2>Write your own QueryPart implementations</h2>
|
||||
<p>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:</p>
|
||||
<pre class="prettyprint lang-java">
|
||||
public abstract class CustomField<T> extends AbstractField<T> {
|
||||
// [...]
|
||||
}
|
||||
public abstract class CustomCondition extends AbstractCondition {
|
||||
// [...]
|
||||
}</pre>
|
||||
|
||||
<p>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 <a href="<?=$root?>/manual/JOOQ/QueryPart/" title="jOOQ Manual reference: QueryParts and the global architecture">QueryParts</a>'
|
||||
bind(<a href="https://github.com/lukaseder/jOOQ/blob/master/jOOQ/src/main/java/org/jooq/BindContext.java" title="Internal API reference: org.jooq.BindContext">BindContext</a>) and
|
||||
toSQL(<a href="https://github.com/lukaseder/jOOQ/blob/master/jOOQ/src/main/java/org/jooq/RenderContext.java" title="Internal API reference: org.jooq.RenderContext">RenderContext</a>) methods:</p>
|
||||
<pre class="prettyprint lang-java">
|
||||
// This method must produce valid SQL. If your QueryPart contains other QueryParts, you may delegate SQL code generation to them
|
||||
// in the correct order, passing the render context.
|
||||
//
|
||||
// If context.inline() is true, you must inline all bind variables
|
||||
// If context.inline() is false, you must generate ? for your bind variables
|
||||
public void toSQL(RenderContext context);
|
||||
|
||||
// This method must bind all bind variables to a PreparedStatement. If your QueryPart contains other QueryParts, you may delegate
|
||||
// variable binding to them in the correct order, passing the bind context.
|
||||
//
|
||||
// Every QueryPart must ensure, that it starts binding its variables at context.nextIndex().
|
||||
public void bind(BindContext context) throws SQLException;
|
||||
</pre>
|
||||
|
||||
<p>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.</p>
|
||||
<h2>Plain SQL as an alternative</h2>
|
||||
<p>If you don't need integration of rather complex QueryParts into
|
||||
jOOQ, then you might be safer using simple
|
||||
<a href="<?=$root?>/manual/DSL/SQL/" title="jOOQ Manual reference: When it's just much easier: Plain SQL">Plain SQL</a> functionality,
|
||||
where you can provide jOOQ with a simple String representation of your
|
||||
embedded SQL. </p>
|
||||
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
@ -7,7 +7,9 @@ function printH1() {
|
||||
print "QueryParts and the global architecture";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
return "When constructing Query objects in jOOQ, everything is
|
||||
considered a QueryPart. The purpose of this quickly becomes clear when
|
||||
checking out the QueryPart API essentials";
|
||||
}
|
||||
function printContent() {
|
||||
global $root;
|
||||
|
||||
@ -7,7 +7,11 @@ function printH1() {
|
||||
print "ResultQuery and various ways of fetching data";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
return "
|
||||
Various jOOQ query type extend the ResultQuery which provides many means of
|
||||
fetching data. In general, fetching means executing and returning some
|
||||
sort of result.
|
||||
";
|
||||
}
|
||||
function printContent() {
|
||||
global $root;
|
||||
@ -16,8 +20,84 @@ function printContent() {
|
||||
<tr>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/JOOQ/">jOOQ classes and their usage</a> : <a href="<?=$root?>/manual/JOOQ/ResultQuery/">ResultQuery and various ways of fetching data</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/JOOQ/Query/" title="Previous section: The Query and its various subtypes">previous</a> : <a href="<?=$root?>/manual/JOOQ/QueryPart/" title="Next section: QueryParts and the global architecture">next</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</table>
|
||||
<h2>The ResultQuery provides many convenience methods</h2>
|
||||
<pre class="prettyprint lang-java">
|
||||
public interface ResultQuery<R extends Record> {
|
||||
|
||||
// These methods allow for fetching a jOOQ Result
|
||||
// or parts of it.
|
||||
// ----------------------------------------------
|
||||
|
||||
// Fetch the whole result
|
||||
Result<R> fetch();
|
||||
|
||||
// Fetch a single field from the result
|
||||
<T> List<T> fetch(Field<T> field);
|
||||
List<?> fetch(int fieldIndex);
|
||||
List<?> fetch(String fieldName);
|
||||
|
||||
// Fetch the first Record
|
||||
R fetchAny();
|
||||
|
||||
// Fetch exactly one Record
|
||||
R fetchOne();
|
||||
|
||||
// Fetch a single field of exactly one Record
|
||||
<T> T fetchOne(Field<T> field);
|
||||
Object fetchOne(int fieldIndex);
|
||||
Object fetchOne(String fieldName);
|
||||
|
||||
// These methods transform the result into another
|
||||
// form, if org.jooq.Result is not optimal
|
||||
// -----------------------------------------------
|
||||
|
||||
// Fetch the resulting records as Maps
|
||||
List<Map<String, Object>> fetchMaps();
|
||||
Map<String, Object> fetchOneMap();
|
||||
|
||||
// Fetch the result as a Map
|
||||
<K> Map<K, R> fetchMap(Field<K> key);
|
||||
<K, V> Map<K, V> fetchMap(Field<K> key, Field<V> value);
|
||||
|
||||
// Fetch the resulting records as arrays
|
||||
Object[][] fetchArrays();
|
||||
Object[] fetchOneArray();
|
||||
|
||||
// Fetch a single field as an array
|
||||
<T> T[] fetchArray(Field<T> field);
|
||||
Object[] fetchArray(int fieldIndex);
|
||||
Object[] fetchArray(String fieldName);
|
||||
|
||||
// These methods transform the result into a user-
|
||||
// defined form, if org.jooq.Result is not optimal
|
||||
// -----------------------------------------------
|
||||
|
||||
// Fetch the resulting records into a custom POJO
|
||||
// type, which may or may not be JPA-annotated
|
||||
<E> List<E> fetchInto(Class<? extends E> type);
|
||||
|
||||
// Fetch the resulting records into a custom
|
||||
// record handler, similar to how Spring JdbcTemplate's
|
||||
// RowMapper or the Ollin Framework works.
|
||||
<H extends RecordHandler<R>> H fetchInto(H handler);
|
||||
|
||||
// These change the behaviour of fetching itself,
|
||||
// especially, when not all data should be
|
||||
// fetched at once
|
||||
// ----------------------------------------------
|
||||
|
||||
// Fetch a Cursor for lazy iteration
|
||||
Cursor<R> fetchLazy();
|
||||
|
||||
// Fetch data asynchronously and let client code
|
||||
// decide, when the data must be available.
|
||||
// This makes use of the java.util.concurrent API,
|
||||
// Similar to how Avajé Ebean works.
|
||||
FutureResult<R> fetchLater();
|
||||
FutureResult<R> fetchLater(ExecutorService executor);
|
||||
}</pre>
|
||||
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
@ -7,17 +7,68 @@ function printH1() {
|
||||
print "Serializability of QueryParts and Results";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
return "Most of the jOOQ API implements the Serializable interface.
|
||||
This helps storing queries and partial queries in files, transferring
|
||||
queries or result data over TCP/IP, etc. ";
|
||||
}
|
||||
function printContent() {
|
||||
global $root;
|
||||
?>
|
||||
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/JOOQ/">jOOQ classes and their usage</a> : <a href="<?=$root?>/manual/JOOQ/Serializability/">Serializability of QueryParts and Results</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/JOOQ/QueryPart/" title="Previous section: QueryParts and the global architecture">previous</a> : <a href="<?=$root?>/manual/JOOQ/Extend/" title="Next section: Extend jOOQ types with custom implementations">next</a></td>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/JOOQ/">jOOQ classes and their usage</a> : <a href="<?=$root?>/manual/JOOQ/Serializability/">Serializability of QueryParts and Results</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/JOOQ/QueryPart/" title="Previous section: QueryParts and the global architecture">previous</a> : <a href="<?=$root?>/manual/JOOQ/Extend/" title="Next section: Extend jOOQ with custom types">next</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</table>
|
||||
<h2>Attaching QueryParts</h2>
|
||||
<p>
|
||||
The only transient element in any jOOQ object is the
|
||||
<a href="<?=$root?>/manual/JOOQ/Factory/" title="jOOQ Manual reference: The Factory class">The Factory class</a>'s
|
||||
underlying
|
||||
<a href="http://download.oracle.com/javase/6/docs/api/java/sql/Connection.html" title="External API reference: java.sql.Connection">java.sql.Connection</a>. When you want to execute queries after
|
||||
de-serialisation, or when you want to store/refresh/delete
|
||||
<a href="<?=$root?>/manual/JOOQ/UpdatableRecord/" title="jOOQ Manual reference: Updatable Records">Updatable Records</a>,
|
||||
you will have to "import" or "re-attach" them to a Factory
|
||||
</p>
|
||||
<pre class="prettyprint lang-java">
|
||||
// Deserialise a SELECT statement
|
||||
ObjectInputStream in = new ObjectInputStream(...);
|
||||
Select<?> select = (Select<?>) in.readObject();
|
||||
|
||||
// This will throw a DetachedException:
|
||||
select.execute();
|
||||
|
||||
// In order to execute the above select, attach it first
|
||||
Factory create = new Factory(connection, SQLDialect.ORACLE);
|
||||
create.attach(select);</pre>
|
||||
|
||||
|
||||
<h2>Automatically attaching QueryParts</h2>
|
||||
<p>In simple cases, you can register a ConfigurationProvider in jOOQ's ConfigurationRegistry</p>
|
||||
<pre class="prettyprint lang-java">
|
||||
// Create your own custom ConfigurationProvider that will make
|
||||
// your default Factory available to jOOQ
|
||||
ConfigurationProvider provider = new CustomConfigurationProvider();
|
||||
|
||||
// Statically register the provider to jOOQ's ConfigurationRegistry
|
||||
ConfigurationRegistry.setProvider(provider);</pre>
|
||||
|
||||
<p>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 </p>
|
||||
<ul>
|
||||
|
||||
<li>transporting jOOQ QueryParts or Records via TCP/IP, RMI, etc (e.g.
|
||||
between client and server), before immediately executing queries,
|
||||
storing UpdatableRecords</li>
|
||||
|
||||
<li>
|
||||
Using automatic mechanisms as known in
|
||||
<a href="http://wicket.apache.org/">Wicket</a>
|
||||
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
@ -131,7 +131,7 @@ function printContent() {
|
||||
know each other. The physical aspect
|
||||
of their nature is represented in
|
||||
jOOQ by
|
||||
<a href="<?=$root?>/manual/META/TABLE/" title="jOOQ Manual reference: Tables and views and their corresponding records">meta model code generation</a>,
|
||||
<a href="<?=$root?>/manual/META/TABLE/" title="jOOQ Manual reference: Tables, views and their corresponding records">meta model code generation</a>,
|
||||
where every entity in your database
|
||||
schema will be generated into a
|
||||
corresponding Java class.
|
||||
|
||||
@ -9,7 +9,7 @@ function printH1() {
|
||||
function getSlogan() {
|
||||
return "
|
||||
In these sections, you will learn about how to use jOOQ object
|
||||
factories and the jOOQ object oriented query model, to express
|
||||
factories and the jOOQ query model, to express
|
||||
your SQL in jOOQ
|
||||
";
|
||||
}
|
||||
@ -72,7 +72,7 @@ function printContent() {
|
||||
<a href="<?=$root?>/manual/JOOQ/Serializability/" title="Serializability of QueryParts and Results">Serializability of QueryParts and Results</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?=$root?>/manual/JOOQ/Extend/" title="Extend jOOQ types with custom implementations">Extend jOOQ types with custom implementations</a>
|
||||
<a href="<?=$root?>/manual/JOOQ/Extend/" title="Extend jOOQ with custom types">Extend jOOQ with custom types</a>
|
||||
</li>
|
||||
</ol>
|
||||
<?php
|
||||
|
||||
@ -4,20 +4,217 @@
|
||||
// Please do not edit this content manually
|
||||
require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Configuration and setup";
|
||||
print "Configuration and setup of the generator";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
return "jOOQ uses a simple configuration file to configure source code generation.";
|
||||
}
|
||||
function printContent() {
|
||||
global $root;
|
||||
?>
|
||||
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/META/">Meta model code generation</a> : <a href="<?=$root?>/manual/META/Configuration/">Configuration and setup</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/META/" title="Previous section: Meta model code generation">previous</a> : <a href="<?=$root?>/manual/META/SCHEMA/" title="Next section: Schemata">next</a></td>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/META/">Meta model code generation</a> : <a href="<?=$root?>/manual/META/Configuration/">Configuration and setup of the generator</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/META/" title="Previous section: Meta model code generation">previous</a> : <a href="<?=$root?>/manual/META/SCHEMA/" title="Next section: The schema, top-level generated artefact">next</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</table>
|
||||
<h2>The deliverables</h2>
|
||||
<p>
|
||||
There are three binaries available with jOOQ, to be downloaded from
|
||||
<a href="https://sourceforge.net/projects/jooq/">SourceForge</a>
|
||||
or from Maven central:
|
||||
</p>
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
|
||||
<strong>jOOQ.jar</strong>
|
||||
|
||||
<br>
|
||||
The main library that you will include in your application to run jOOQ
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<strong>jOOQ-meta.jar</strong>
|
||||
|
||||
<br>
|
||||
The utility that you will include in your build to navigate your
|
||||
database schema for code generation. This can be used as a schema
|
||||
crawler as well.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
|
||||
<strong>jOOQ-codegen.jar</strong>
|
||||
|
||||
<br>
|
||||
The utility that you will include in your build to generate your
|
||||
database schema
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2>Dependencies</h2>
|
||||
<p>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.
|
||||
</p>
|
||||
|
||||
|
||||
<h2>Configure jOOQ</h2>
|
||||
<p>You need to tell jOOQ some things about your database connection.
|
||||
Here's an example of how to do it for a MySQL database </p>
|
||||
<pre class="prettyprint">
|
||||
#Configure the database connection here
|
||||
jdbc.Driver=com.mysql.jdbc.Driver
|
||||
jdbc.URL=jdbc:mysql://[your jdbc URL]
|
||||
jdbc.Schema=[your database schema]
|
||||
jdbc.User=[your database user]
|
||||
jdbc.Password=[your database password]
|
||||
|
||||
#The default code generator. You can override this one, to generate your own code style
|
||||
#Defaults to org.jooq.util.DefaultGenerator
|
||||
generator=org.jooq.util.DefaultGenerator
|
||||
|
||||
#The database type. The format here is:
|
||||
#generator.database=org.util.[database].[database]Database
|
||||
generator.database=org.jooq.util.mysql.MySQLDatabase
|
||||
|
||||
#All elements that are generated from your schema (several Java regular expressions, separated by comma)
|
||||
#Watch out for case-sensitivity. Depending on your database, this might be important!
|
||||
generator.database.includes=.*
|
||||
|
||||
#All elements that are excluded from your schema (several Java regular expressions, separated by comma). Excludes match before includes
|
||||
generator.database.excludes=
|
||||
|
||||
#Primary key / foreign key relations should be generated and used.
|
||||
#This will be a prerequisite for various advanced features
|
||||
#Defaults to false
|
||||
generator.generate.relations=true
|
||||
|
||||
#Generate deprecated code for backwards compatibility
|
||||
#Defaults to true
|
||||
generator.generate.deprecated=false
|
||||
|
||||
#The destination package of your generated classes (within the destination directory)
|
||||
generator.target.package=[org.jooq.your.package]
|
||||
|
||||
#The destination directory of your generated classes
|
||||
generator.target.directory=[/path/to/your/dir]</pre>
|
||||
|
||||
<p>And you can add some optional advanced configuration parameters: </p>
|
||||
<pre class="prettyprint">
|
||||
#Generate a master data table enum classes (several Java regular expressions, separated by comma)
|
||||
generator.generate.master-data-tables=[a list of tables]
|
||||
|
||||
#For every master data table, specify two special columns
|
||||
generator.generate.master-data-table-literal.[master data table]=[column used for enum literals]
|
||||
generator.generate.master-data-table-description.[master data table]=[column used for documentation]</pre>
|
||||
<p>Check out the manual's section about
|
||||
<a href="<?=$root?>/manual/ADVANCED/MasterData/" title="jOOQ Manual reference: Master data generation">master data</a>
|
||||
to find out more
|
||||
about those advanced configuration parameters. </p>
|
||||
|
||||
<h2>Run jOOQ code generation</h2>
|
||||
<p>Code generation works by calling this class with the above property file as argument.</p>
|
||||
<pre class="prettyprint">
|
||||
org.jooq.util.GenerationTool /jooq-config.properties</pre>
|
||||
<p>Be sure that these elements are located on the classpath: </p>
|
||||
<ul>
|
||||
|
||||
<li>The property file</li>
|
||||
|
||||
<li>jooq.jar, jooq-meta.jar, jooq-codegen.jar</li>
|
||||
|
||||
<li>The JDBC driver you configured</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h3>A command-line example (For Windows, unix/linux/etc will be similar)</h3>
|
||||
<ul>
|
||||
|
||||
<li>Put the property file, jooq*.jar and the JDBC driver into
|
||||
a directory, e.g. C:\temp\jooq</li>
|
||||
|
||||
<li>Go to C:\temp\jooq</li>
|
||||
|
||||
<li>Run java -cp jooq.jar;jooq-meta.jar;jooq-codegen.jar;[JDBC-driver].jar;. org.jooq.util.GenerationTool /[property file] </li>
|
||||
|
||||
</ul>
|
||||
<p>Note that the property file must be passed as a classpath resource</p>
|
||||
|
||||
<h3>Run code generation from Eclipse</h3>
|
||||
<p>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: </p>
|
||||
<div class="screenshot">
|
||||
|
||||
<img alt="Eclipse configuration" class="screenshot" src="<?=$root?>/img/eclipse-example-01.png">
|
||||
</div>
|
||||
|
||||
<p>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. </p>
|
||||
<div class="screenshot">
|
||||
|
||||
<img alt="Eclipse configuration" class="screenshot" src="<?=$root?>/img/eclipse-example-02.png">
|
||||
</div>
|
||||
|
||||
<p>With the properties file as an argument </p>
|
||||
<div class="screenshot">
|
||||
|
||||
<img alt="Eclipse configuration" class="screenshot" src="<?=$root?>/img/eclipse-example-03.png">
|
||||
</div>
|
||||
|
||||
<p>And the classpath set up correctly</p>
|
||||
<div class="screenshot">
|
||||
|
||||
<img alt="Eclipse configuration" class="screenshot" src="<?=$root?>/img/eclipse-example-04.png">
|
||||
</div>
|
||||
|
||||
<p>Finally, run the code generation and see your generated artefacts</p>
|
||||
<div class="screenshot">
|
||||
|
||||
<img alt="Eclipse configuration" class="screenshot" src="<?=$root?>/img/eclipse-example-05.png">
|
||||
</div>
|
||||
|
||||
<h3>Run generation with ant</h3>
|
||||
<p>You can also use an ant task to generate your classes: </p>
|
||||
<pre class="prettyprint lang-xml">
|
||||
<!-- Task definition -->
|
||||
<taskdef name="generate-classes" classname="org.jooq.util.GenerationTask">
|
||||
<classpath>
|
||||
<fileset dir="${path.to.jooq.distribution}">
|
||||
<include name="jOOQ.jar"/>
|
||||
<include name="jOOQ-meta.jar"/>
|
||||
<include name="jOOQ-codegen.jar"/>
|
||||
</fileset>
|
||||
<fileset dir="${path.to.mysql.driver}">
|
||||
<include name="${mysql.driver}.jar"/>
|
||||
</fileset>
|
||||
</classpath>
|
||||
</taskdef>
|
||||
|
||||
<!-- Run the code generation task -->
|
||||
<target name="generate-test-classes">
|
||||
<generate-classes
|
||||
jdbcurl="jdbc:mysql://localhost/test"
|
||||
jdbcschema="test"
|
||||
jdbcuser="root"
|
||||
jdbcpassword=""
|
||||
generatortargetpackage="org.jooq.test.generatedclasses"
|
||||
generatortargetdirectory="${basedir}/src"/>
|
||||
</target></pre>
|
||||
|
||||
<h3>Use jOOQ generated classes in your application</h3>
|
||||
<p>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.</p>
|
||||
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
@ -7,17 +7,199 @@ function printH1() {
|
||||
print "Procedures and packages";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
return "
|
||||
Procedure support is one of the most important reasons why you should consider
|
||||
jOOQ. jOOQ heavily facilitates the use of stored procedures and
|
||||
functions via its source code generation.
|
||||
";
|
||||
}
|
||||
function printContent() {
|
||||
global $root;
|
||||
?>
|
||||
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/META/">Meta model code generation</a> : <a href="<?=$root?>/manual/META/PROCEDURE/">Procedures and packages</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/META/TABLE/" title="Previous section: Tables and views and their corresponding records">previous</a> : <a href="<?=$root?>/manual/META/UDT/" title="Next section: UDT's including ARRAY and ENUM types">next</a></td>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/META/">Meta model code generation</a> : <a href="<?=$root?>/manual/META/PROCEDURE/">Procedures and packages</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/META/TABLE/" title="Previous section: Tables, views and their corresponding records">previous</a> : <a href="<?=$root?>/manual/META/UDT/" title="Next section: UDT's including ARRAY and ENUM types">next</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</table>
|
||||
<h2>Stored procedures in modern RDBMS</h2>
|
||||
<p>This is one of the most important reasons why you should consider
|
||||
jOOQ. Read also my
|
||||
<a href="http://java.dzone.com/articles/2011-great-year-stored" title="Article on stored procedures and how to use them with jOOQ">article on dzone</a>
|
||||
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
|
||||
<a href="<?=$root?>/manual/META/UDT/" title="jOOQ Manual reference: UDT's including ARRAY and ENUM types">UDT and ARRAY support</a> was
|
||||
introduced to major RDBMS, these procedures tend to have dozens of
|
||||
parameters, with IN, OUT, IN OUT parameters mixed in all variations.
|
||||
JDBC only knows very basic, low-level support for those constructs.
|
||||
jOOQ heavily facilitates the use of stored procedures and functions
|
||||
via its source code generation. Essentially, it comes down to this:
|
||||
</p>
|
||||
|
||||
<h3>"Standalone" stored procedures and functions</h3>
|
||||
<p>Let's say you have these stored procedures and functions in your Oracle database </p>
|
||||
<pre class="prettyprint lang-sql">
|
||||
-- Check whether there is an author in T_AUTHOR by that name
|
||||
CREATE OR REPLACE FUNCTION f_author_exists (author_name VARCHAR2) RETURN NUMBER;
|
||||
|
||||
-- Check whether there is an author in T_AUTHOR by that name
|
||||
CREATE OR REPLACE PROCEDURE p_author_exists (author_name VARCHAR2, result OUT NUMBER);
|
||||
|
||||
-- Check whether there is an author in T_AUTHOR by that name and get his ID
|
||||
CREATE OR REPLACE PROCEDURE p_author_exists_2 (author_name VARCHAR2, result OUT NUMBER, id OUT NUMBER);</pre>
|
||||
|
||||
<p>jOOQ will essentially generate two artefacts for every procedure/function: </p>
|
||||
<ul>
|
||||
|
||||
<li>A class holding a formal Java representation of the procedure/function</li>
|
||||
|
||||
<li>Some convenience methods to facilitate calling that procedure/function </li>
|
||||
|
||||
</ul>
|
||||
<p>Let's see what these things look like, in Java. The classes (simplified for the example): </p>
|
||||
|
||||
<pre class="prettyprint lang-java">
|
||||
// The function has a generic type parameter <T> bound to its return value
|
||||
public class FAuthorExists extends StoredFunctionImpl<BigDecimal> {
|
||||
|
||||
// Much like Tables, functions have static parameter definitions
|
||||
public static final Parameter<String> AUTHOR_NAME = // [...]
|
||||
|
||||
// And much like TableRecords, they have setters for their parameters
|
||||
public void setAuthorName(String value) { // [...]
|
||||
public void setAuthorName(Field<String> value) { // [...]
|
||||
}
|
||||
|
||||
public class PAuthorExists extends StoredProcedureImpl {
|
||||
|
||||
// In procedures, IN, OUT, IN OUT parameters are all represented
|
||||
// as static parameter definitions as well
|
||||
public static final Parameter<String> AUTHOR_NAME = // [...]
|
||||
public static final Parameter<BigDecimal> RESULT = // [...]
|
||||
|
||||
// IN and IN OUT parameters have generated setters
|
||||
public void setAuthorName(String value) { // [...]
|
||||
|
||||
// OUT and IN OUT parameters have generated getters
|
||||
public BigDecimal getResult() { // [...]
|
||||
}
|
||||
|
||||
public class PAuthorExists_2 extends StoredProcedureImpl {
|
||||
public static final Parameter<String> AUTHOR_NAME = // [...]
|
||||
public static final Parameter<BigDecimal> RESULT = // [...]
|
||||
public static final Parameter<BigDecimal> ID = // [...]
|
||||
|
||||
// the setters...
|
||||
public void setAuthorName(String value) { // [...]
|
||||
|
||||
// the getters...
|
||||
public BigDecimal getResult() { // [...]
|
||||
public BigDecimal getId() { // [...]
|
||||
}</pre>
|
||||
|
||||
<p>An example invocation of such a stored procedure might look like this: </p>
|
||||
|
||||
<pre class="prettyprint lang-java">
|
||||
PAuthorExists p = new PAuthorExists();
|
||||
p.setAuthorName("Paulo");
|
||||
p.execute(configuration);
|
||||
assertEquals(BigDecimal.ONE, p.getResult());</pre>
|
||||
|
||||
<p>If you use the generated convenience methods, however, things are much simpler, still: </p>
|
||||
<pre class="prettyprint lang-java">
|
||||
// Every schema has a single Functions class with convenience methods
|
||||
public final class Functions {
|
||||
|
||||
// Convenience method to directly call the stored function
|
||||
public static BigDecimal fAuthorExists(Configuration configuration, String authorName) { // [...]
|
||||
|
||||
// Convenience methods to transform the stored function into a
|
||||
// Field<BigDecimal>, such that it can be used in SQL
|
||||
public static Field<BigDecimal> fAuthorExists(Field<String> authorName) { // [...]
|
||||
public static Field<BigDecimal> fAuthorExists(String authorName) { // [...]
|
||||
}
|
||||
|
||||
// Every schema has a single Procedures class with convenience methods
|
||||
public final class Procedures {
|
||||
|
||||
// Procedures with 0 OUT parameters create void methods
|
||||
// Procedures with 1 OUT parameter create methods as such:
|
||||
public static BigDecimal pAuthorExists(Configuration configuration, String authorName) { // [...]
|
||||
|
||||
// Procedures with more than 1 OUT parameter return the procedure
|
||||
// object (see above example)
|
||||
public static PAuthorExists_2 pAuthorExists_2(Configuration configuration, String authorName) { // [...]
|
||||
}</pre>
|
||||
|
||||
<p>An sample invocation, equivalent to the previous example:</p>
|
||||
<pre class="prettyprint lang-java">
|
||||
assertEquals(BigDecimal.ONE, Procedures.pAuthorExists(configuration, "Paulo"));</pre>
|
||||
|
||||
|
||||
<h3>jOOQ's understanding of procedures vs functions</h3>
|
||||
<p>
|
||||
It might not be very clear, what defines a procedure and what
|
||||
defines a
|
||||
function in those RDBMS that support these objects. Most
|
||||
often, a function
|
||||
has a mandatory return value, whereas procedures can
|
||||
return OUT parameters.
|
||||
Oracle allows for mixing those concepts.
|
||||
Postgres omits the term procedure, etc.
|
||||
</p>
|
||||
<p>
|
||||
For jOOQ, the following applies:
|
||||
</p>
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
A procedure is an object that cannot be used in SQL (because it
|
||||
has no
|
||||
return value). A procedure is called internally by jOOQ using a
|
||||
<a href="http://download.oracle.com/javase/6/docs/api/java/sql/CallableStatement.html" title="External API reference: java.sql.CallableStatement">java.sql.CallableStatement</a>
|
||||
|
||||
</li>
|
||||
|
||||
<li>
|
||||
A function is an object that can be used in SQL. There is always
|
||||
the
|
||||
possibility to create a
|
||||
<a href="https://github.com/lukaseder/jOOQ/blob/master/jOOQ/src/main/java/org/jooq/Field.java" title="Internal API reference: org.jooq.Field">org.jooq.Field</a>
|
||||
to represent the function
|
||||
embedded in SQL.
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<h3>Packages in Oracle</h3>
|
||||
<p>
|
||||
Oracle uses the concept of a PACKAGE to group several
|
||||
procedures/functions into a sort of namespace. The
|
||||
<a href="http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt" title="SQL 92 standard">SQL standard</a>
|
||||
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
|
||||
</p>
|
||||
<ul>
|
||||
|
||||
<li>A Java package holding classes for formal Java representations of
|
||||
the procedure/function in that package
|
||||
</li>
|
||||
|
||||
<li>A Java class holding convenience methods to facilitate calling
|
||||
those procedures/functions
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
<p>
|
||||
Apart from this, the generated source code looks exactly like the
|
||||
one for
|
||||
standalone procedures/functions.
|
||||
</p>
|
||||
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
@ -4,20 +4,54 @@
|
||||
// Please do not edit this content manually
|
||||
require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Schemata";
|
||||
print "The schema, top-level generated artefact";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
return "The schema is the top-level generated object in jOOQ. In many
|
||||
RDBMS, the schema coincides with the owner of tables and other objects
|
||||
";
|
||||
}
|
||||
function printContent() {
|
||||
global $root;
|
||||
?>
|
||||
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/META/">Meta model code generation</a> : <a href="<?=$root?>/manual/META/SCHEMA/">Schemata</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/META/Configuration/" title="Previous section: Configuration and setup">previous</a> : <a href="<?=$root?>/manual/META/TABLE/" title="Next section: Tables and views and their corresponding records">next</a></td>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/META/">Meta model code generation</a> : <a href="<?=$root?>/manual/META/SCHEMA/">The schema, top-level generated artefact</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/META/Configuration/" title="Previous section: Configuration and setup of the generator">previous</a> : <a href="<?=$root?>/manual/META/TABLE/" title="Next section: Tables, views and their corresponding records">next</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</table>
|
||||
<h2>The Schema</h2>
|
||||
<p>
|
||||
As of jOOQ 1.5, the top-level generated object is the
|
||||
<a href="https://github.com/lukaseder/jOOQ/blob/master/jOOQ/src/main/java/org/jooq/Schema.java" title="Internal API reference: org.jooq.Schema">org.jooq.Schema</a>.
|
||||
The Schema itself has no relevant functionality, except for holding
|
||||
the schema name for all dependent generated artefacts. jOOQ queries try
|
||||
to always fully qualify an entity within the database using that Schema
|
||||
</p>
|
||||
|
||||
<p>
|
||||
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: <a href="https://sourceforge.net/apps/trac/jooq/ticket/282" title="Trac ticket: #282">#282</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
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
|
||||
<a href="<?=$root?>/manual/ADVANCED/SchemaMapping/" title="jOOQ Manual reference: Mapping generated schemata and tables to productive environments">multiple equivalent schemata</a>
|
||||
|
||||
</p>
|
||||
|
||||
<h3>Schema contents</h3>
|
||||
<p>The schema can be used to dynamically discover generate database
|
||||
artefacts. Tables, sequences, and other items are accessible from the
|
||||
schema. For example:</p>
|
||||
<pre class="prettyprint lang-java">
|
||||
public final java.util.List<org.jooq.Sequence> getSequences();
|
||||
public final java.util.List<org.jooq.Table<?>> getTables();</pre>
|
||||
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
@ -4,20 +4,84 @@
|
||||
// Please do not edit this content manually
|
||||
require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Tables and views and their corresponding records";
|
||||
print "Tables, views and their corresponding records";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
return "
|
||||
The most important generated artefacts are Tables and TableRecords.
|
||||
Every Table has a Record type associated with it that models a single tuple
|
||||
of that entity: Table<R extends Record>.
|
||||
";
|
||||
}
|
||||
function printContent() {
|
||||
global $root;
|
||||
?>
|
||||
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/META/">Meta model code generation</a> : <a href="<?=$root?>/manual/META/TABLE/">Tables and views and their corresponding records</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/META/SCHEMA/" title="Previous section: Schemata">previous</a> : <a href="<?=$root?>/manual/META/PROCEDURE/" title="Next section: Procedures and packages">next</a></td>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/META/">Meta model code generation</a> : <a href="<?=$root?>/manual/META/TABLE/">Tables, views and their corresponding records</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/META/SCHEMA/" title="Previous section: The schema, top-level generated artefact">previous</a> : <a href="<?=$root?>/manual/META/PROCEDURE/" title="Next section: Procedures and packages">next</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</table>
|
||||
<h2>Tables and TableRecords</h2>
|
||||
<p>
|
||||
The most important generated artefacts are
|
||||
<a href="https://github.com/lukaseder/jOOQ/blob/master/jOOQ/src/main/java/org/jooq/Table.java" title="Internal API reference: org.jooq.Table">Tables</a> and
|
||||
<a href="https://github.com/lukaseder/jOOQ/blob/master/jOOQ/src/main/java/org/jooq/TableRecord.java" title="Internal API reference: org.jooq.TableRecord">TableRecords</a>. As
|
||||
discussed in previous chapters about
|
||||
<a href="<?=$root?>/manual/JOOQ/Table/" title="jOOQ Manual reference: Tables and Fields">Tables</a> and
|
||||
<a href="<?=$root?>/manual/JOOQ/Result/" title="jOOQ Manual reference: Results and Records">Results</a>, jOOQ uses the
|
||||
Table class to model entities (both tables and views) in your database
|
||||
Schema. Every Table has a Record type associated with it that models a
|
||||
single tuple of that entity: Table<R extends Record>. This
|
||||
couple of Table<R> and R are generated as such:
|
||||
</p>
|
||||
<p>
|
||||
Suppose we have the tables as defined in the
|
||||
<a href="<?=$root?>/manual/JOOQ/ExampleDatabase/" title="jOOQ Manual reference: The example database">example database</a>.
|
||||
Then, using a
|
||||
default configuration, these (simplified for the example) classes will
|
||||
be generated:
|
||||
</p>
|
||||
|
||||
<h3>The Table as an entity meta model</h3>
|
||||
<pre class="prettyprint lang-java">
|
||||
public class TAuthor extends UpdatableTableImpl<TAuthorRecord> {
|
||||
|
||||
// The singleton instance of the Table
|
||||
public static final TAuthor T_AUTHOR = new TAuthor();
|
||||
|
||||
// The Table's fields
|
||||
public static final TableField<TAuthorRecord, Integer> ID = // [...]
|
||||
public static final TableField<TAuthorRecord, String> FIRST_NAME = // [...]
|
||||
public static final TableField<TAuthorRecord, String> LAST_NAME = // [...]
|
||||
public static final TableField<TAuthorRecord, Date> DATE_OF_BIRTH = // [...]
|
||||
public static final TableField<TAuthorRecord, Integer> YEAR_OF_BIRTH = // [...]
|
||||
}</pre>
|
||||
|
||||
<h3>The Table's associated TableRecord</h3>
|
||||
<p>If you use the
|
||||
<a href="<?=$root?>/manual/JOOQ/Query/" title="jOOQ Manual reference: The Query and its various subtypes">SimpleSelectQuery</a>
|
||||
syntax (both in standard and DSL
|
||||
mode), then your SELECT statement will return the single Table<R
|
||||
extends Record>'s associated Record type <R>. In the case of
|
||||
the above TAuthor Table, this will be a TAuthorRecord. </p>
|
||||
|
||||
<pre class="prettyprint lang-java">
|
||||
public class TAuthorRecord extends UpdatableRecordImpl<TAuthorRecord> {
|
||||
|
||||
// Getters and setters for the various fields
|
||||
public void setId(Integer value) { // [...]
|
||||
public Integer getId() { // [...]
|
||||
public void setFirstName(String value) { // [...]
|
||||
public String getFirstName() { // [...]
|
||||
public void setLastName(String value) { // [...]
|
||||
public String getLastName() { // [...]
|
||||
public void setDateOfBirth(Date value) { // [...]
|
||||
public Date getDateOfBirth() { // [...]
|
||||
|
||||
// Navigation methods for foreign keys
|
||||
public List<TBookRecord> getTBooks() throws SQLException { // [...]
|
||||
}</pre>
|
||||
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
@ -7,24 +7,47 @@ function printH1() {
|
||||
print "Meta model code generation";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
return "In these sections you will learn about how to configure and use
|
||||
jOOQ's source code generator";
|
||||
}
|
||||
function printContent() {
|
||||
global $root;
|
||||
?>
|
||||
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
||||
<tr>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/META/">Meta model code generation</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/JOOQ/Extend/" title="Previous section: Extend jOOQ types with custom implementations">previous</a> : <a href="<?=$root?>/manual/META/Configuration/" title="Next section: Configuration and setup">next</a></td>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/META/">Meta model code generation</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/JOOQ/Extend/" title="Previous section: Extend jOOQ with custom types">previous</a> : <a href="<?=$root?>/manual/META/Configuration/" title="Next section: Configuration and setup of the generator">next</a></td>
|
||||
</tr>
|
||||
</table><h3>Table of contents</h3><ol>
|
||||
</table>
|
||||
<h2>Overview</h2>
|
||||
<p>
|
||||
In the previous chapter, we have seen how to use the
|
||||
<a href="<?=$root?>/manual/JOOQ/Factory/" title="jOOQ Manual reference: The Factory class">Factory</a> in order to create
|
||||
<a href="<?=$root?>/manual/JOOQ/Query/" title="jOOQ Manual reference: The Query and its various subtypes">Queries</a> and fetch data in
|
||||
<a href="<?=$root?>/manual/JOOQ/Result/" title="jOOQ Manual reference: Results and Records">Results</a>. The strength of jOOQ not
|
||||
only lies in its object-oriented
|
||||
<a href="<?=$root?>/manual/JOOQ/QueryPart/" title="jOOQ Manual reference: QueryParts and the global architecture">Query model</a>,
|
||||
but also in the fact
|
||||
that Java source code is generated from your database schema into the
|
||||
META data model. jOOQ follows the paradigm, that your database comes
|
||||
first (see also <a href="<?=$root?>/">home page</a>).
|
||||
This means that you should not modify
|
||||
generated source code, but only adapt entities in your database. Every
|
||||
change in your database is reflected in a corresponding change in your
|
||||
generated meta-model.
|
||||
</p>
|
||||
<p>
|
||||
Artefacts, such as tables, views, user defined types, sequences, stored
|
||||
procedures, packages have a corresponding artefact in Java.
|
||||
</p>
|
||||
<h3>Table of contents</h3><ol>
|
||||
<li>
|
||||
<a href="<?=$root?>/manual/META/Configuration/" title="Configuration and setup">Configuration and setup</a>
|
||||
<a href="<?=$root?>/manual/META/Configuration/" title="Configuration and setup of the generator">Configuration and setup of the generator</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?=$root?>/manual/META/SCHEMA/" title="Schemata">Schemata</a>
|
||||
<a href="<?=$root?>/manual/META/SCHEMA/" title="The schema, top-level generated artefact">The schema, top-level generated artefact</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?=$root?>/manual/META/TABLE/" title="Tables and views and their corresponding records">Tables and views and their corresponding records</a>
|
||||
<a href="<?=$root?>/manual/META/TABLE/" title="Tables, views and their corresponding records">Tables, views and their corresponding records</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?=$root?>/manual/META/PROCEDURE/" title="Procedures and packages">Procedures and packages</a>
|
||||
|
||||
@ -111,7 +111,7 @@ function printContent() {
|
||||
<a href="<?=$root?>/manual/JOOQ/Serializability/" title="Serializability of QueryParts and Results">Serializability of QueryParts and Results</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?=$root?>/manual/JOOQ/Extend/" title="Extend jOOQ types with custom implementations">Extend jOOQ types with custom implementations</a>
|
||||
<a href="<?=$root?>/manual/JOOQ/Extend/" title="Extend jOOQ with custom types">Extend jOOQ with custom types</a>
|
||||
</li>
|
||||
</ol>
|
||||
</li>
|
||||
@ -119,13 +119,13 @@ function printContent() {
|
||||
<a href="<?=$root?>/manual/META/" title="Meta model code generation">Meta model code generation</a>
|
||||
<ol>
|
||||
<li>
|
||||
<a href="<?=$root?>/manual/META/Configuration/" title="Configuration and setup">Configuration and setup</a>
|
||||
<a href="<?=$root?>/manual/META/Configuration/" title="Configuration and setup of the generator">Configuration and setup of the generator</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?=$root?>/manual/META/SCHEMA/" title="Schemata">Schemata</a>
|
||||
<a href="<?=$root?>/manual/META/SCHEMA/" title="The schema, top-level generated artefact">The schema, top-level generated artefact</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?=$root?>/manual/META/TABLE/" title="Tables and views and their corresponding records">Tables and views and their corresponding records</a>
|
||||
<a href="<?=$root?>/manual/META/TABLE/" title="Tables, views and their corresponding records">Tables, views and their corresponding records</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?=$root?>/manual/META/PROCEDURE/" title="Procedures and packages">Procedures and packages</a>
|
||||
|
||||
@ -218,6 +218,12 @@ function printContent() {
|
||||
<xsl:value-of select="@anchor"/>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:when test="@ticket">
|
||||
<xsl:text>https://sourceforge.net/apps/trac/jooq/ticket/</xsl:text>
|
||||
<xsl:value-of select="@ticket"/>
|
||||
<xsl:value-of select="@anchor"/>
|
||||
</xsl:when>
|
||||
|
||||
<xsl:otherwise>
|
||||
<xsl:message>
|
||||
<xsl:text>Reference not supported</xsl:text>
|
||||
@ -240,6 +246,10 @@ function printContent() {
|
||||
<xsl:text>External API reference: </xsl:text>
|
||||
<xsl:value-of select="@class"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="@ticket">
|
||||
<xsl:text>Trac ticket: #</xsl:text>
|
||||
<xsl:value-of select="@ticket"/>
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
</xsl:attribute>
|
||||
|
||||
@ -253,6 +263,10 @@ function printContent() {
|
||||
<xsl:when test="@class">
|
||||
<xsl:value-of select="@class"/>
|
||||
</xsl:when>
|
||||
<xsl:when test="@ticket">
|
||||
<xsl:text>#</xsl:text>
|
||||
<xsl:value-of select="@ticket"/>
|
||||
</xsl:when>
|
||||
</xsl:choose>
|
||||
</a>
|
||||
</xsl:when>
|
||||
|
||||
@ -54,7 +54,7 @@
|
||||
<title>jOOQ classes and their usage</title>
|
||||
<slogan>
|
||||
In these sections, you will learn about how to use jOOQ object
|
||||
factories and the jOOQ object oriented query model, to express
|
||||
factories and the jOOQ query model, to express
|
||||
your SQL in jOOQ
|
||||
</slogan>
|
||||
<content>
|
||||
@ -969,33 +969,715 @@ create.mergeInto(T_AUTHOR)
|
||||
|
||||
<section id="ResultQuery">
|
||||
<title>ResultQuery and various ways of fetching data</title>
|
||||
<slogan>
|
||||
Various jOOQ query type extend the ResultQuery which provides many means of
|
||||
fetching data. In general, fetching means executing and returning some
|
||||
sort of result.
|
||||
</slogan>
|
||||
<content>
|
||||
<h2>The ResultQuery provides many convenience methods</h2>
|
||||
<pre class="prettyprint lang-java">
|
||||
public interface ResultQuery<R extends Record> {
|
||||
|
||||
// These methods allow for fetching a jOOQ Result
|
||||
// or parts of it.
|
||||
// ----------------------------------------------
|
||||
|
||||
// Fetch the whole result
|
||||
Result<R> fetch();
|
||||
|
||||
// Fetch a single field from the result
|
||||
<T> List<T> fetch(Field<T> field);
|
||||
List<?> fetch(int fieldIndex);
|
||||
List<?> fetch(String fieldName);
|
||||
|
||||
// Fetch the first Record
|
||||
R fetchAny();
|
||||
|
||||
// Fetch exactly one Record
|
||||
R fetchOne();
|
||||
|
||||
// Fetch a single field of exactly one Record
|
||||
<T> T fetchOne(Field<T> field);
|
||||
Object fetchOne(int fieldIndex);
|
||||
Object fetchOne(String fieldName);
|
||||
|
||||
// These methods transform the result into another
|
||||
// form, if org.jooq.Result is not optimal
|
||||
// -----------------------------------------------
|
||||
|
||||
// Fetch the resulting records as Maps
|
||||
List<Map<String, Object>> fetchMaps();
|
||||
Map<String, Object> fetchOneMap();
|
||||
|
||||
// Fetch the result as a Map
|
||||
<K> Map<K, R> fetchMap(Field<K> key);
|
||||
<K, V> Map<K, V> fetchMap(Field<K> key, Field<V> value);
|
||||
|
||||
// Fetch the resulting records as arrays
|
||||
Object[][] fetchArrays();
|
||||
Object[] fetchOneArray();
|
||||
|
||||
// Fetch a single field as an array
|
||||
<T> T[] fetchArray(Field<T> field);
|
||||
Object[] fetchArray(int fieldIndex);
|
||||
Object[] fetchArray(String fieldName);
|
||||
|
||||
// These methods transform the result into a user-
|
||||
// defined form, if org.jooq.Result is not optimal
|
||||
// -----------------------------------------------
|
||||
|
||||
// Fetch the resulting records into a custom POJO
|
||||
// type, which may or may not be JPA-annotated
|
||||
<E> List<E> fetchInto(Class<? extends E> type);
|
||||
|
||||
// Fetch the resulting records into a custom
|
||||
// record handler, similar to how Spring JdbcTemplate's
|
||||
// RowMapper or the Ollin Framework works.
|
||||
<H extends RecordHandler<R>> H fetchInto(H handler);
|
||||
|
||||
// These change the behaviour of fetching itself,
|
||||
// especially, when not all data should be
|
||||
// fetched at once
|
||||
// ----------------------------------------------
|
||||
|
||||
// Fetch a Cursor for lazy iteration
|
||||
Cursor<R> fetchLazy();
|
||||
|
||||
// Fetch data asynchronously and let client code
|
||||
// decide, when the data must be available.
|
||||
// This makes use of the java.util.concurrent API,
|
||||
// Similar to how Avajé Ebean works.
|
||||
FutureResult<R> fetchLater();
|
||||
FutureResult<R> fetchLater(ExecutorService executor);
|
||||
}</pre>
|
||||
</content>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="QueryPart">
|
||||
<title>QueryParts and the global architecture</title>
|
||||
<slogan>When constructing Query objects in jOOQ, everything is
|
||||
considered a QueryPart. The purpose of this quickly becomes clear when
|
||||
checking out the QueryPart API essentials</slogan>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="Serializability">
|
||||
<title>Serializability of QueryParts and Results</title>
|
||||
<slogan>Most of the jOOQ API implements the Serializable interface.
|
||||
This helps storing queries and partial queries in files, transferring
|
||||
queries or result data over TCP/IP, etc. </slogan>
|
||||
<content>
|
||||
<h2>Attaching QueryParts</h2>
|
||||
<p>
|
||||
The only transient element in any jOOQ object is the
|
||||
<reference id="Factory"/>'s
|
||||
underlying
|
||||
<reference class="java.sql.Connection"/>. When you want to execute queries after
|
||||
de-serialisation, or when you want to store/refresh/delete
|
||||
<reference id="UpdatableRecord" title="Updatable Records"/>,
|
||||
you will have to "import" or "re-attach" them to a Factory
|
||||
</p>
|
||||
<pre class="prettyprint lang-java">
|
||||
// Deserialise a SELECT statement
|
||||
ObjectInputStream in = new ObjectInputStream(...);
|
||||
Select<?> select = (Select<?>) in.readObject();
|
||||
|
||||
// This will throw a DetachedException:
|
||||
select.execute();
|
||||
|
||||
// In order to execute the above select, attach it first
|
||||
Factory create = new Factory(connection, SQLDialect.ORACLE);
|
||||
create.attach(select);</pre>
|
||||
|
||||
|
||||
<h2>Automatically attaching QueryParts</h2>
|
||||
<p>In simple cases, you can register a ConfigurationProvider in jOOQ's ConfigurationRegistry</p>
|
||||
<pre class="prettyprint lang-java">
|
||||
// Create your own custom ConfigurationProvider that will make
|
||||
// your default Factory available to jOOQ
|
||||
ConfigurationProvider provider = new CustomConfigurationProvider();
|
||||
|
||||
// Statically register the provider to jOOQ's ConfigurationRegistry
|
||||
ConfigurationRegistry.setProvider(provider);</pre>
|
||||
|
||||
<p>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 </p>
|
||||
<ul>
|
||||
<li>transporting jOOQ QueryParts or Records via TCP/IP, RMI, etc (e.g.
|
||||
between client and server), before immediately executing queries,
|
||||
storing UpdatableRecords</li>
|
||||
<li>
|
||||
Using automatic mechanisms as known in
|
||||
<a href="http://wicket.apache.org/">Wicket</a>
|
||||
</li>
|
||||
</ul>
|
||||
</content>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="Extend">
|
||||
<title>Extend jOOQ types with custom implementations</title>
|
||||
<title>Extend jOOQ with custom types</title>
|
||||
<slogan>Maybe jOOQ is missing functionality that you would like to see,
|
||||
or you can't wait for the next release... In this case, you can extend
|
||||
any of the following open jOOQ implementation classes</slogan>
|
||||
<content>
|
||||
<h2>Write your own QueryPart implementations</h2>
|
||||
<p>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:</p>
|
||||
<pre class="prettyprint lang-java">
|
||||
public abstract class CustomField<T> extends AbstractField<T> {
|
||||
// [...]
|
||||
}
|
||||
public abstract class CustomCondition extends AbstractCondition {
|
||||
// [...]
|
||||
}</pre>
|
||||
|
||||
<p>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 <reference id="QueryPart" title="QueryParts"/>'
|
||||
bind(<reference class="org.jooq.BindContext" title="BindContext"/>) and
|
||||
toSQL(<reference class="org.jooq.RenderContext" title="RenderContext"/>) methods:</p>
|
||||
<pre class="prettyprint lang-java">
|
||||
// This method must produce valid SQL. If your QueryPart contains other QueryParts, you may delegate SQL code generation to them
|
||||
// in the correct order, passing the render context.
|
||||
//
|
||||
// If context.inline() is true, you must inline all bind variables
|
||||
// If context.inline() is false, you must generate ? for your bind variables
|
||||
public void toSQL(RenderContext context);
|
||||
|
||||
// This method must bind all bind variables to a PreparedStatement. If your QueryPart contains other QueryParts, you may delegate
|
||||
// variable binding to them in the correct order, passing the bind context.
|
||||
//
|
||||
// Every QueryPart must ensure, that it starts binding its variables at context.nextIndex().
|
||||
public void bind(BindContext context) throws SQLException;
|
||||
</pre>
|
||||
|
||||
<p>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.</p>
|
||||
<h2>Plain SQL as an alternative</h2>
|
||||
<p>If you don't need integration of rather complex QueryParts into
|
||||
jOOQ, then you might be safer using simple
|
||||
<reference id="SQL" title="Plain SQL"/> functionality,
|
||||
where you can provide jOOQ with a simple String representation of your
|
||||
embedded SQL. </p>
|
||||
</content>
|
||||
</section>
|
||||
</sections>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<section id="META">
|
||||
<title>Meta model code generation</title>
|
||||
<slogan>In these sections you will learn about how to configure and use
|
||||
jOOQ's source code generator</slogan>
|
||||
<content>
|
||||
<h2>Overview</h2>
|
||||
<p>
|
||||
In the previous chapter, we have seen how to use the
|
||||
<reference id="Factory" title="Factory"/> in order to create
|
||||
<reference id="Query" title="Queries"/> and fetch data in
|
||||
<reference id="Result" title="Results"/>. The strength of jOOQ not
|
||||
only lies in its object-oriented
|
||||
<reference id="QueryPart" title="Query model"/>,
|
||||
but also in the fact
|
||||
that Java source code is generated from your database schema into the
|
||||
META data model. jOOQ follows the paradigm, that your database comes
|
||||
first (see also <a href="<?=$root?>/">home page</a>).
|
||||
This means that you should not modify
|
||||
generated source code, but only adapt entities in your database. Every
|
||||
change in your database is reflected in a corresponding change in your
|
||||
generated meta-model.
|
||||
</p>
|
||||
<p>
|
||||
Artefacts, such as tables, views, user defined types, sequences, stored
|
||||
procedures, packages have a corresponding artefact in Java.
|
||||
</p>
|
||||
</content>
|
||||
|
||||
|
||||
<sections>
|
||||
<section id="Configuration">
|
||||
<title>Configuration and setup</title>
|
||||
<title>Configuration and setup of the generator</title>
|
||||
<slogan>jOOQ uses a simple configuration file to configure source code generation.</slogan>
|
||||
<content>
|
||||
<h2>The deliverables</h2>
|
||||
<p>
|
||||
There are three binaries available with jOOQ, to be downloaded from
|
||||
<a href="https://sourceforge.net/projects/jooq/">SourceForge</a>
|
||||
or from Maven central:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<strong>jOOQ.jar</strong>
|
||||
<br />
|
||||
The main library that you will include in your application to run jOOQ
|
||||
</li>
|
||||
<li>
|
||||
<strong>jOOQ-meta.jar</strong>
|
||||
<br />
|
||||
The utility that you will include in your build to navigate your
|
||||
database schema for code generation. This can be used as a schema
|
||||
crawler as well.
|
||||
</li>
|
||||
<li>
|
||||
<strong>jOOQ-codegen.jar</strong>
|
||||
<br />
|
||||
The utility that you will include in your build to generate your
|
||||
database schema
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>Dependencies</h2>
|
||||
<p>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.
|
||||
</p>
|
||||
|
||||
|
||||
<h2>Configure jOOQ</h2>
|
||||
<p>You need to tell jOOQ some things about your database connection.
|
||||
Here's an example of how to do it for a MySQL database </p>
|
||||
<pre class="prettyprint">
|
||||
#Configure the database connection here
|
||||
jdbc.Driver=com.mysql.jdbc.Driver
|
||||
jdbc.URL=jdbc:mysql://[your jdbc URL]
|
||||
jdbc.Schema=[your database schema]
|
||||
jdbc.User=[your database user]
|
||||
jdbc.Password=[your database password]
|
||||
|
||||
#The default code generator. You can override this one, to generate your own code style
|
||||
#Defaults to org.jooq.util.DefaultGenerator
|
||||
generator=org.jooq.util.DefaultGenerator
|
||||
|
||||
#The database type. The format here is:
|
||||
#generator.database=org.util.[database].[database]Database
|
||||
generator.database=org.jooq.util.mysql.MySQLDatabase
|
||||
|
||||
#All elements that are generated from your schema (several Java regular expressions, separated by comma)
|
||||
#Watch out for case-sensitivity. Depending on your database, this might be important!
|
||||
generator.database.includes=.*
|
||||
|
||||
#All elements that are excluded from your schema (several Java regular expressions, separated by comma). Excludes match before includes
|
||||
generator.database.excludes=
|
||||
|
||||
#Primary key / foreign key relations should be generated and used.
|
||||
#This will be a prerequisite for various advanced features
|
||||
#Defaults to false
|
||||
generator.generate.relations=true
|
||||
|
||||
#Generate deprecated code for backwards compatibility
|
||||
#Defaults to true
|
||||
generator.generate.deprecated=false
|
||||
|
||||
#The destination package of your generated classes (within the destination directory)
|
||||
generator.target.package=[org.jooq.your.package]
|
||||
|
||||
#The destination directory of your generated classes
|
||||
generator.target.directory=[/path/to/your/dir]</pre>
|
||||
|
||||
<p>And you can add some optional advanced configuration parameters: </p>
|
||||
<pre class="prettyprint">
|
||||
#Generate a master data table enum classes (several Java regular expressions, separated by comma)
|
||||
generator.generate.master-data-tables=[a list of tables]
|
||||
|
||||
#For every master data table, specify two special columns
|
||||
generator.generate.master-data-table-literal.[master data table]=[column used for enum literals]
|
||||
generator.generate.master-data-table-description.[master data table]=[column used for documentation]</pre>
|
||||
<p>Check out the manual's section about
|
||||
<reference id="MasterData" title="master data"/>
|
||||
to find out more
|
||||
about those advanced configuration parameters. </p>
|
||||
|
||||
<h2>Run jOOQ code generation</h2>
|
||||
<p>Code generation works by calling this class with the above property file as argument.</p>
|
||||
<pre class="prettyprint">
|
||||
org.jooq.util.GenerationTool /jooq-config.properties</pre>
|
||||
<p>Be sure that these elements are located on the classpath: </p>
|
||||
<ul>
|
||||
<li>The property file</li>
|
||||
<li>jooq.jar, jooq-meta.jar, jooq-codegen.jar</li>
|
||||
<li>The JDBC driver you configured</li>
|
||||
</ul>
|
||||
|
||||
<h3>A command-line example (For Windows, unix/linux/etc will be similar)</h3>
|
||||
<ul>
|
||||
<li>Put the property file, jooq*.jar and the JDBC driver into
|
||||
a directory, e.g. C:\temp\jooq</li>
|
||||
<li>Go to C:\temp\jooq</li>
|
||||
<li>Run java -cp jooq.jar;jooq-meta.jar;jooq-codegen.jar;[JDBC-driver].jar;. org.jooq.util.GenerationTool /[property file] </li>
|
||||
</ul>
|
||||
<p>Note that the property file must be passed as a classpath resource</p>
|
||||
|
||||
<h3>Run code generation from Eclipse</h3>
|
||||
<p>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: </p>
|
||||
<div class="screenshot">
|
||||
<img class="screenshot" src="<?=$root?>/img/eclipse-example-01.png" alt="Eclipse configuration"/>
|
||||
</div>
|
||||
|
||||
<p>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. </p>
|
||||
<div class="screenshot">
|
||||
<img class="screenshot" src="<?=$root?>/img/eclipse-example-02.png" alt="Eclipse configuration"/>
|
||||
</div>
|
||||
|
||||
<p>With the properties file as an argument </p>
|
||||
<div class="screenshot">
|
||||
<img class="screenshot" src="<?=$root?>/img/eclipse-example-03.png" alt="Eclipse configuration"/>
|
||||
</div>
|
||||
|
||||
<p>And the classpath set up correctly</p>
|
||||
<div class="screenshot">
|
||||
<img class="screenshot" src="<?=$root?>/img/eclipse-example-04.png" alt="Eclipse configuration"/>
|
||||
</div>
|
||||
|
||||
<p>Finally, run the code generation and see your generated artefacts</p>
|
||||
<div class="screenshot">
|
||||
<img class="screenshot" src="<?=$root?>/img/eclipse-example-05.png" alt="Eclipse configuration"/>
|
||||
</div>
|
||||
|
||||
<h3>Run generation with ant</h3>
|
||||
<p>You can also use an ant task to generate your classes: </p>
|
||||
<pre class="prettyprint lang-xml">
|
||||
<!-- Task definition -->
|
||||
<taskdef name="generate-classes" classname="org.jooq.util.GenerationTask">
|
||||
<classpath>
|
||||
<fileset dir="${path.to.jooq.distribution}">
|
||||
<include name="jOOQ.jar"/>
|
||||
<include name="jOOQ-meta.jar"/>
|
||||
<include name="jOOQ-codegen.jar"/>
|
||||
</fileset>
|
||||
<fileset dir="${path.to.mysql.driver}">
|
||||
<include name="${mysql.driver}.jar"/>
|
||||
</fileset>
|
||||
</classpath>
|
||||
</taskdef>
|
||||
|
||||
<!-- Run the code generation task -->
|
||||
<target name="generate-test-classes">
|
||||
<generate-classes
|
||||
jdbcurl="jdbc:mysql://localhost/test"
|
||||
jdbcschema="test"
|
||||
jdbcuser="root"
|
||||
jdbcpassword=""
|
||||
generatortargetpackage="org.jooq.test.generatedclasses"
|
||||
generatortargetdirectory="${basedir}/src"/>
|
||||
</target></pre>
|
||||
|
||||
<h3>Use jOOQ generated classes in your application</h3>
|
||||
<p>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.</p>
|
||||
</content>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="SCHEMA">
|
||||
<title>Schemata</title>
|
||||
<title>The schema, top-level generated artefact</title>
|
||||
<slogan>The schema is the top-level generated object in jOOQ. In many
|
||||
RDBMS, the schema coincides with the owner of tables and other objects
|
||||
</slogan>
|
||||
<content>
|
||||
<h2>The Schema</h2>
|
||||
<p>
|
||||
As of jOOQ 1.5, the top-level generated object is the
|
||||
<reference class="org.jooq.Schema" />.
|
||||
The Schema itself has no relevant functionality, except for holding
|
||||
the schema name for all dependent generated artefacts. jOOQ queries try
|
||||
to always fully qualify an entity within the database using that Schema
|
||||
</p>
|
||||
|
||||
<p>
|
||||
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: <reference ticket="282"/>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
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
|
||||
<reference id="SchemaMapping" title="multiple equivalent schemata"/>
|
||||
</p>
|
||||
|
||||
<h3>Schema contents</h3>
|
||||
<p>The schema can be used to dynamically discover generate database
|
||||
artefacts. Tables, sequences, and other items are accessible from the
|
||||
schema. For example:</p>
|
||||
<pre class="prettyprint lang-java">
|
||||
public final java.util.List<org.jooq.Sequence> getSequences();
|
||||
public final java.util.List<org.jooq.Table<?>> getTables();</pre>
|
||||
</content>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="TABLE">
|
||||
<title>Tables and views and their corresponding records</title>
|
||||
<title>Tables, views and their corresponding records</title>
|
||||
<slogan>
|
||||
The most important generated artefacts are Tables and TableRecords.
|
||||
Every Table has a Record type associated with it that models a single tuple
|
||||
of that entity: Table<R extends Record>.
|
||||
</slogan>
|
||||
<content>
|
||||
<h2>Tables and TableRecords</h2>
|
||||
<p>
|
||||
The most important generated artefacts are
|
||||
<reference class="org.jooq.Table" title="Tables"/> and
|
||||
<reference class="org.jooq.TableRecord" title="TableRecords"/>. As
|
||||
discussed in previous chapters about
|
||||
<reference id="Table" title="Tables"/> and
|
||||
<reference id="Result" title="Results"/>, jOOQ uses the
|
||||
Table class to model entities (both tables and views) in your database
|
||||
Schema. Every Table has a Record type associated with it that models a
|
||||
single tuple of that entity: Table<R extends Record>. This
|
||||
couple of Table<R> and R are generated as such:
|
||||
</p>
|
||||
<p>
|
||||
Suppose we have the tables as defined in the
|
||||
<reference id="ExampleDatabase" title="example database"/>.
|
||||
Then, using a
|
||||
default configuration, these (simplified for the example) classes will
|
||||
be generated:
|
||||
</p>
|
||||
|
||||
<h3>The Table as an entity meta model</h3>
|
||||
<pre class="prettyprint lang-java">
|
||||
public class TAuthor extends UpdatableTableImpl<TAuthorRecord> {
|
||||
|
||||
// The singleton instance of the Table
|
||||
public static final TAuthor T_AUTHOR = new TAuthor();
|
||||
|
||||
// The Table's fields
|
||||
public static final TableField<TAuthorRecord, Integer> ID = // [...]
|
||||
public static final TableField<TAuthorRecord, String> FIRST_NAME = // [...]
|
||||
public static final TableField<TAuthorRecord, String> LAST_NAME = // [...]
|
||||
public static final TableField<TAuthorRecord, Date> DATE_OF_BIRTH = // [...]
|
||||
public static final TableField<TAuthorRecord, Integer> YEAR_OF_BIRTH = // [...]
|
||||
}</pre>
|
||||
|
||||
<h3>The Table's associated TableRecord</h3>
|
||||
<p>If you use the
|
||||
<reference id="Query" title="SimpleSelectQuery"/>
|
||||
syntax (both in standard and DSL
|
||||
mode), then your SELECT statement will return the single Table<R
|
||||
extends Record>'s associated Record type <R>. In the case of
|
||||
the above TAuthor Table, this will be a TAuthorRecord. </p>
|
||||
|
||||
<pre class="prettyprint lang-java">
|
||||
public class TAuthorRecord extends UpdatableRecordImpl<TAuthorRecord> {
|
||||
|
||||
// Getters and setters for the various fields
|
||||
public void setId(Integer value) { // [...]
|
||||
public Integer getId() { // [...]
|
||||
public void setFirstName(String value) { // [...]
|
||||
public String getFirstName() { // [...]
|
||||
public void setLastName(String value) { // [...]
|
||||
public String getLastName() { // [...]
|
||||
public void setDateOfBirth(Date value) { // [...]
|
||||
public Date getDateOfBirth() { // [...]
|
||||
|
||||
// Navigation methods for foreign keys
|
||||
public List<TBookRecord> getTBooks() throws SQLException { // [...]
|
||||
}</pre>
|
||||
</content>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="PROCEDURE">
|
||||
<title>Procedures and packages</title>
|
||||
<slogan>
|
||||
Procedure support is one of the most important reasons why you should consider
|
||||
jOOQ. jOOQ heavily facilitates the use of stored procedures and
|
||||
functions via its source code generation.
|
||||
</slogan>
|
||||
<content>
|
||||
<h2>Stored procedures in modern RDBMS</h2>
|
||||
<p>This is one of the most important reasons why you should consider
|
||||
jOOQ. Read also my
|
||||
<a href="http://java.dzone.com/articles/2011-great-year-stored" title="Article on stored procedures and how to use them with jOOQ">article on dzone</a>
|
||||
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
|
||||
<reference id="UDT" title="UDT and ARRAY support"/> was
|
||||
introduced to major RDBMS, these procedures tend to have dozens of
|
||||
parameters, with IN, OUT, IN OUT parameters mixed in all variations.
|
||||
JDBC only knows very basic, low-level support for those constructs.
|
||||
jOOQ heavily facilitates the use of stored procedures and functions
|
||||
via its source code generation. Essentially, it comes down to this:
|
||||
</p>
|
||||
|
||||
<h3>"Standalone" stored procedures and functions</h3>
|
||||
<p>Let's say you have these stored procedures and functions in your Oracle database </p>
|
||||
<pre class="prettyprint lang-sql">
|
||||
-- Check whether there is an author in T_AUTHOR by that name
|
||||
CREATE OR REPLACE FUNCTION f_author_exists (author_name VARCHAR2) RETURN NUMBER;
|
||||
|
||||
-- Check whether there is an author in T_AUTHOR by that name
|
||||
CREATE OR REPLACE PROCEDURE p_author_exists (author_name VARCHAR2, result OUT NUMBER);
|
||||
|
||||
-- Check whether there is an author in T_AUTHOR by that name and get his ID
|
||||
CREATE OR REPLACE PROCEDURE p_author_exists_2 (author_name VARCHAR2, result OUT NUMBER, id OUT NUMBER);</pre>
|
||||
|
||||
<p>jOOQ will essentially generate two artefacts for every procedure/function: </p>
|
||||
<ul>
|
||||
<li>A class holding a formal Java representation of the procedure/function</li>
|
||||
<li>Some convenience methods to facilitate calling that procedure/function </li>
|
||||
</ul>
|
||||
<p>Let's see what these things look like, in Java. The classes (simplified for the example): </p>
|
||||
|
||||
<pre class="prettyprint lang-java">
|
||||
// The function has a generic type parameter <T> bound to its return value
|
||||
public class FAuthorExists extends StoredFunctionImpl<BigDecimal> {
|
||||
|
||||
// Much like Tables, functions have static parameter definitions
|
||||
public static final Parameter<String> AUTHOR_NAME = // [...]
|
||||
|
||||
// And much like TableRecords, they have setters for their parameters
|
||||
public void setAuthorName(String value) { // [...]
|
||||
public void setAuthorName(Field<String> value) { // [...]
|
||||
}
|
||||
|
||||
public class PAuthorExists extends StoredProcedureImpl {
|
||||
|
||||
// In procedures, IN, OUT, IN OUT parameters are all represented
|
||||
// as static parameter definitions as well
|
||||
public static final Parameter<String> AUTHOR_NAME = // [...]
|
||||
public static final Parameter<BigDecimal> RESULT = // [...]
|
||||
|
||||
// IN and IN OUT parameters have generated setters
|
||||
public void setAuthorName(String value) { // [...]
|
||||
|
||||
// OUT and IN OUT parameters have generated getters
|
||||
public BigDecimal getResult() { // [...]
|
||||
}
|
||||
|
||||
public class PAuthorExists_2 extends StoredProcedureImpl {
|
||||
public static final Parameter<String> AUTHOR_NAME = // [...]
|
||||
public static final Parameter<BigDecimal> RESULT = // [...]
|
||||
public static final Parameter<BigDecimal> ID = // [...]
|
||||
|
||||
// the setters...
|
||||
public void setAuthorName(String value) { // [...]
|
||||
|
||||
// the getters...
|
||||
public BigDecimal getResult() { // [...]
|
||||
public BigDecimal getId() { // [...]
|
||||
}</pre>
|
||||
|
||||
<p>An example invocation of such a stored procedure might look like this: </p>
|
||||
|
||||
<pre class="prettyprint lang-java">
|
||||
PAuthorExists p = new PAuthorExists();
|
||||
p.setAuthorName("Paulo");
|
||||
p.execute(configuration);
|
||||
assertEquals(BigDecimal.ONE, p.getResult());</pre>
|
||||
|
||||
<p>If you use the generated convenience methods, however, things are much simpler, still: </p>
|
||||
<pre class="prettyprint lang-java">
|
||||
// Every schema has a single Functions class with convenience methods
|
||||
public final class Functions {
|
||||
|
||||
// Convenience method to directly call the stored function
|
||||
public static BigDecimal fAuthorExists(Configuration configuration, String authorName) { // [...]
|
||||
|
||||
// Convenience methods to transform the stored function into a
|
||||
// Field<BigDecimal>, such that it can be used in SQL
|
||||
public static Field<BigDecimal> fAuthorExists(Field<String> authorName) { // [...]
|
||||
public static Field<BigDecimal> fAuthorExists(String authorName) { // [...]
|
||||
}
|
||||
|
||||
// Every schema has a single Procedures class with convenience methods
|
||||
public final class Procedures {
|
||||
|
||||
// Procedures with 0 OUT parameters create void methods
|
||||
// Procedures with 1 OUT parameter create methods as such:
|
||||
public static BigDecimal pAuthorExists(Configuration configuration, String authorName) { // [...]
|
||||
|
||||
// Procedures with more than 1 OUT parameter return the procedure
|
||||
// object (see above example)
|
||||
public static PAuthorExists_2 pAuthorExists_2(Configuration configuration, String authorName) { // [...]
|
||||
}</pre>
|
||||
|
||||
<p>An sample invocation, equivalent to the previous example:</p>
|
||||
<pre class="prettyprint lang-java">
|
||||
assertEquals(BigDecimal.ONE, Procedures.pAuthorExists(configuration, "Paulo"));</pre>
|
||||
|
||||
|
||||
<h3>jOOQ's understanding of procedures vs functions</h3>
|
||||
<p>
|
||||
It might not be very clear, what defines a procedure and what
|
||||
defines a
|
||||
function in those RDBMS that support these objects. Most
|
||||
often, a function
|
||||
has a mandatory return value, whereas procedures can
|
||||
return OUT parameters.
|
||||
Oracle allows for mixing those concepts.
|
||||
Postgres omits the term procedure, etc.
|
||||
</p>
|
||||
<p>
|
||||
For jOOQ, the following applies:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
A procedure is an object that cannot be used in SQL (because it
|
||||
has no
|
||||
return value). A procedure is called internally by jOOQ using a
|
||||
<reference class="java.sql.CallableStatement" />
|
||||
</li>
|
||||
<li>
|
||||
A function is an object that can be used in SQL. There is always
|
||||
the
|
||||
possibility to create a
|
||||
<reference class="org.jooq.Field" />
|
||||
to represent the function
|
||||
embedded in SQL.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3>Packages in Oracle</h3>
|
||||
<p>
|
||||
Oracle uses the concept of a PACKAGE to group several
|
||||
procedures/functions into a sort of namespace. The
|
||||
<a href="http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt"
|
||||
title="SQL 92 standard">SQL standard</a>
|
||||
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
|
||||
</p>
|
||||
<ul>
|
||||
<li>A Java package holding classes for formal Java representations of
|
||||
the procedure/function in that package
|
||||
</li>
|
||||
<li>A Java class holding convenience methods to facilitate calling
|
||||
those procedures/functions
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Apart from this, the generated source code looks exactly like the
|
||||
one for
|
||||
standalone procedures/functions.
|
||||
</p>
|
||||
</content>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="UDT">
|
||||
<title>UDT's including ARRAY and ENUM types</title>
|
||||
</section>
|
||||
@ -1004,6 +1686,10 @@ create.mergeInto(T_AUTHOR)
|
||||
</section>
|
||||
</sections>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
<section id="DSL">
|
||||
<title>DSL or fluent API. Where SQL meets Java</title>
|
||||
<sections>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user