Added some sections to the manual

This commit is contained in:
Lukas Eder 2011-09-21 22:10:40 +00:00
parent cece9b55e8
commit a4416b4545
16 changed files with 1014 additions and 46 deletions

View File

@ -1,6 +1,7 @@
<?php
$root = "";
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>jOOQ</title>

View File

@ -4,24 +4,78 @@
// Please do not edit this content manually
require '../../../frame.php';
function printH1() {
print "The Oracle CONNECT BY clause for hierarchical queries";
print "The Oracle CONNECT BY clause";
}
function getActiveMenu() {
return "manual";
}
function getSlogan() {
return "";
return "
Hierarchical queries are supported by many RDBMS using the WITH clause.
Oracle has a very neat and much less verbose syntax for hierarchical
queries: CONNECT BY .. STARTS WITH
";
}
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/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/CONNECTBY/">The Oracle CONNECT BY clause for hierarchical queries</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/OracleHints/" title="Previous section: Adding Oracle hints to queries">previous</a> : <a href="<?=$root?>/manual/ADVANCED/Export/" title="Next section: Exporting data to XML, CSV, JSON, HTML, Text">next</a></td>
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/CONNECTBY/">The Oracle CONNECT BY clause</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/OracleHints/" title="Previous section: Adding Oracle hints to queries">previous</a> : <a href="<?=$root?>/manual/ADVANCED/Export/" title="Next section: Exporting to XML, CSV, JSON, HTML, Text">next</a></td>
</tr>
</table><br><table cellpadding="0" cellspacing="0" border="0" width="100%">
</table>
<h2>CONNECT BY .. STARTS WITH</h2>
<p>If you are closely coupling your application to an Oracle database,
you can take advantage of some Oracle-specific features, such as the
CONNECT BY clause, used for hierarchical queries. The formal syntax
definition is as follows: </p>
<pre class="prettyprint lang-sql">
-- SELECT ..
-- FROM ..
-- WHERE ..
CONNECT BY [NOCYCLE] condition [AND condition, ...] [START WITH condition]
-- GROUP BY ..</pre>
<p>This can be done in jOOQ using the .connectBy(Condition) clauses in your SELECT statement: </p>
<pre class="prettyprint lang-java">
// Some Oracle-specific features are only available
// from the OracleFactory
OracleFactory create = new OracleFactory(connection);
// Get a table with elements 1, 2, 3, 4, 5
create.select(create.rownum())
.connectBy(create.level().lessOrEqual(5))
.fetch();</pre>
<p>Here's a more complex example where you can recursively fetch
directories in your database, and concatenate them to a path:</p>
<pre class="prettyprint lang-java">
OracleFactory ora = new OracleFactory(connection);
List&lt;?&gt; paths =
ora.select(ora.sysConnectByPath(Directory.NAME, "/").substring(2))
.from(Directory)
.connectBy(ora.prior(Directory.ID).equal(Directory.PARENT_ID))
.startWith(Directory.PARENT_ID.isNull())
.orderBy(ora.literal(1))
.fetch(0);</pre>
<p>The output might then look like this</p>
<pre>
+------------------------------------------------+
|substring |
+------------------------------------------------+
|C: |
|C:/eclipse |
|C:/eclipse/configuration |
|C:/eclipse/dropins |
|C:/eclipse/eclipse.exe |
+------------------------------------------------+
|...21 record(s) truncated...
</pre>
<br><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/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/CONNECTBY/">The Oracle CONNECT BY clause for hierarchical queries</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/OracleHints/" title="Previous section: Adding Oracle hints to queries">previous</a> : <a href="<?=$root?>/manual/ADVANCED/Export/" title="Next section: Exporting data to XML, CSV, JSON, HTML, Text">next</a></td>
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/CONNECTBY/">The Oracle CONNECT BY clause</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/OracleHints/" title="Previous section: Adding Oracle hints to queries">previous</a> : <a href="<?=$root?>/manual/ADVANCED/Export/" title="Next section: Exporting to XML, CSV, JSON, HTML, Text">next</a></td>
</tr>
</table>
<?php

View File

@ -4,24 +4,129 @@
// Please do not edit this content manually
require '../../../frame.php';
function printH1() {
print "Exporting data to XML, CSV, JSON, HTML, Text";
print "Exporting to XML, CSV, JSON, HTML, Text";
}
function getActiveMenu() {
return "manual";
}
function getSlogan() {
return "";
return "
Get your data out of the Java world. Stream your data using any of the supported, wide-spread formats
";
}
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/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/Export/">Exporting data to XML, CSV, JSON, HTML, Text</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/CONNECTBY/" title="Previous section: The Oracle CONNECT BY clause for hierarchical queries">previous</a> : <a href="<?=$root?>/manual/ADVANCED/Import/" title="Next section: Importing data from XML, CSV">next</a></td>
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/Export/">Exporting to XML, CSV, JSON, HTML, Text</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/CONNECTBY/" title="Previous section: The Oracle CONNECT BY clause">previous</a> : <a href="<?=$root?>/manual/ADVANCED/Import/" title="Next section: Importing data from XML, CSV">next</a></td>
</tr>
</table><br><table cellpadding="0" cellspacing="0" border="0" width="100%">
</table>
<h2>Exporting with jOOQ</h2>
<p>If you are using jOOQ for scripting purposes or in a slim, unlayered
application server, you might be interested in using jOOQ's exporting
functionality (see also importing functionality). You can export any
Result&lt;Record&gt; into any of these formats: </p>
<h3>XML</h3>
<p>Export your results as XML: </p>
<pre class="prettyprint lang-java">
// Fetch books and format them as XML
String xml = create.selectFrom(T_BOOK).fetch().formatXML();</pre>
<p>The above query will result in an XML document looking like the following one: </p>
<pre class="prettyprint lang-xml">
&lt;!-- Find the XSD definition on www.jooq.org: --&gt;
&lt;jooq-export:result xmlns:jooq-export="http://www.jooq.org/xsd/jooq-export-1.6.2.xsd"&gt;
&lt;fields&gt;
&lt;field name="ID"/&gt;
&lt;field name="AUTHOR_ID"/&gt;
&lt;field name="TITLE"/&gt;
&lt;/fields&gt;
&lt;records&gt;
&lt;record&gt;
&lt;value field="ID"&gt;1&lt;/value&gt;
&lt;value field="AUTHOR_ID"&gt;1&lt;/value&gt;
&lt;value field="TITLE"&gt;1984&lt;/value&gt;
&lt;/record&gt;
&lt;record&gt;
&lt;value field="ID"&gt;2&lt;/value&gt;
&lt;value field="AUTHOR_ID"&gt;1&lt;/value&gt;
&lt;value field="TITLE"&gt;Animal Farm&lt;/value&gt;
&lt;/record&gt;
&lt;/records&gt;
&lt;/jooq-export:result&gt;</pre>
<h3>CSV</h3>
<p>Export your results as CSV: </p>
<pre class="prettyprint lang-java">
// Fetch books and format them as CSV
String csv = create.selectFrom(T_BOOK).fetch().formatCSV();</pre>
<p>The above query will result in a CSV document looking like the following one: </p>
<pre>
ID;AUTHOR_ID;TITLE
1;1;1984
2;1;Animal Farm</pre>
<h3>JSON</h3>
<p>Export your results as JSON: </p>
<pre class="prettyprint lang-java">
// Fetch books and format them as JSON
String json = create.selectFrom(T_BOOK).fetch().formatJSON();</pre>
<p>The above query will result in a JSON document looking like the following one: </p>
<pre>
{fields:["ID","AUTHOR_ID","TITLE"],
records:[[1,1,"1984"],[2,1,"Animal Farm"]]}</pre>
<h3>HTML </h3>
<p>Export your results as HTML: </p>
<pre class="prettyprint lang-java">
// Fetch books and format them as HTML
String html = create.selectFrom(T_BOOK).fetch().formatHTML();</pre>
<p>The above query will result in an HTML document looking like the following one: </p>
<pre class="prettyprint lang-xml">
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ID&lt;/th&gt;
&lt;th&gt;AUTHOR_ID&lt;/th&gt;
&lt;th&gt;TITLE&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1984&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Animal Farm&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</pre>
<h3>Text</h3>
<p>Export your results as text: </p>
<pre class="prettyprint lang-java">
// Fetch books and format them as text
String text = create.selectFrom(T_BOOK).fetch().format();</pre>
<p>The above query will result in a text document looking like the following one: </p>
<pre>
+---+---------+-----------+
| ID|AUTHOR_ID|TITLE |
+---+---------+-----------+
| 1| 1|1984 |
| 2| 1|Animal Farm|
+---+---------+-----------+</pre>
<br><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/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/Export/">Exporting data to XML, CSV, JSON, HTML, Text</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/CONNECTBY/" title="Previous section: The Oracle CONNECT BY clause for hierarchical queries">previous</a> : <a href="<?=$root?>/manual/ADVANCED/Import/" title="Next section: Importing data from XML, CSV">next</a></td>
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/Export/">Exporting to XML, CSV, JSON, HTML, Text</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/CONNECTBY/" title="Previous section: The Oracle CONNECT BY clause">previous</a> : <a href="<?=$root?>/manual/ADVANCED/Import/" title="Next section: Importing data from XML, CSV">next</a></td>
</tr>
</table>
<?php

View File

@ -10,18 +10,128 @@ function getActiveMenu() {
return "manual";
}
function getSlogan() {
return "";
return "
Use jOOQ to easily merge imported data into your database.
";
}
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/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/Import/">Importing data from XML, CSV</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/Export/" title="Previous section: Exporting data to XML, CSV, JSON, HTML, Text">previous</a></td>
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/Import/">Importing data from XML, CSV</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/Export/" title="Previous section: Exporting to XML, CSV, JSON, HTML, Text">previous</a></td>
</tr>
</table><br><table cellpadding="0" cellspacing="0" border="0" width="100%">
</table>
<h2>Importing with jOOQ</h2>
<p>If you are using jOOQ for scripting purposes or in a slim, unlayered
application server, you might be interested in using jOOQ's importing
functionality (see also exporting functionality). You can import data
directly into a table from any of these formats: </p>
<h3>CSV</h3>
<p>The below CSV data represents two author records that may have been
exported previously, by jOOQ's exporting functionality, and then
modified in Microsoft Excel or any other spreadsheet tool: </p>
<pre>
ID;AUTHOR_ID;TITLE
1;1;1984
2;1;Animal Farm</pre>
<p>With jOOQ, you can load this data using various parameters from the
loader API. A simple load may look like this: </p>
<pre class="prettyprint lang-java">
Factory create = new Factory(connection, SQLDialect.ORACLE);
// Load data into the T_AUTHOR table from an input stream
// holding the CSV data.
create.loadInto(T_AUTHOR)
.loadCSV(inputstream)
.fields(ID, AUTHOR_ID, TITLE)
.execute();</pre>
<p>Here are various other examples: </p>
<pre class="prettyprint lang-java">
// Ignore the AUTHOR_ID column from the CSV file when inserting
create.loadInto(T_AUTHOR)
.loadCSV(inputstream)
.fields(ID, null, TITLE)
.execute();
// Specify behaviour for duplicate records.
create.loadInto(T_AUTHOR)
// choose any of these methods
.onDuplicateKeyUpdate()
.onDuplicateKeyIgnore()
.onDuplicateKeyError() // the default
.loadCSV(inputstream)
.fields(ID, null, TITLE)
.execute();
// Specify behaviour when errors occur.
create.loadInto(T_AUTHOR)
// choose any of these methods
.onErrorIgnore()
.onErrorAbort() // the default
.loadCSV(inputstream)
.fields(ID, null, TITLE)
.execute();
// Specify transactional behaviour where this is possible
// (e.g. not in container-managed transactions)
create.loadInto(T_AUTHOR)
// choose any of these methods
.commitEach()
.commitAfter(10)
.commitAll()
.commitNone() // the default
.loadCSV(inputstream)
.fields(ID, null, TITLE)
.execute();</pre>
<p>Any of the above configuration methods can be combined to achieve
the type of load you need. Please refer to the API's Javadoc to learn
about more details. Errors that occur during the load are reported by
the execute method's result: </p>
<pre class="prettyprint lang-java">
Loader&lt;TAuthor&gt; loader = /* .. */ .execute();
// The number of processed rows
int processed = loader.processed();
// The number of stored rows (INSERT or UPDATE)
int stored = loader.stored();
// The number of ignored rows (due to errors, or duplicate rule)
int ignored = loader.ignored();
// The errors that may have occurred during loading
List&lt;LoaderError&gt; errors = loader.errors();
LoaderError error = errors.get(0);
// The exception that caused the error
SQLException exception = error.exception();
// The row that caused the error
int rowIndex = error.rowIndex();
String[] row = error.row();
// The query that caused the error
Query query = error.query();</pre>
<h3>XML </h3>
<p>This will be implemented soon... </p>
<br><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/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/Import/">Importing data from XML, CSV</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/Export/" title="Previous section: Exporting data to XML, CSV, JSON, HTML, Text">previous</a></td>
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/Import/">Importing data from XML, CSV</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/Export/" title="Previous section: Exporting to XML, CSV, JSON, HTML, Text">previous</a></td>
</tr>
</table>
<?php

View File

@ -4,7 +4,7 @@
// Please do not edit this content manually
require '../../../frame.php';
function printH1() {
print "Master data generation";
print "Master data generation. Enumeration tables";
}
function getActiveMenu() {
return "manual";
@ -19,7 +19,7 @@ function printContent() {
?>
<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/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/MasterData/">Master data generation</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/" title="Previous section: Advanced topics">previous</a> : <a href="<?=$root?>/manual/ADVANCED/SchemaMapping/" title="Next section: Mapping generated schemata and tables to productive environments">next</a></td>
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/MasterData/">Master data generation. Enumeration tables</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/" title="Previous section: Advanced topics">previous</a> : <a href="<?=$root?>/manual/ADVANCED/SchemaMapping/" title="Next section: Mapping generated schemata and tables">next</a></td>
</tr>
</table>
<h2>Enumeration tables</h2>
@ -127,7 +127,7 @@ public class TBookRecord extends UpdatableRecordImpl&lt;TBookRecord&gt; {
type is generated. </p>
<br><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/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/MasterData/">Master data generation</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/" title="Previous section: Advanced topics">previous</a> : <a href="<?=$root?>/manual/ADVANCED/SchemaMapping/" title="Next section: Mapping generated schemata and tables to productive environments">next</a></td>
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/MasterData/">Master data generation. Enumeration tables</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/" title="Previous section: Advanced topics">previous</a> : <a href="<?=$root?>/manual/ADVANCED/SchemaMapping/" title="Next section: Mapping generated schemata and tables">next</a></td>
</tr>
</table>
<?php

View File

@ -10,18 +10,38 @@ function getActiveMenu() {
return "manual";
}
function getSlogan() {
return "";
return "
Oracle has a powerful syntax to add hints as comments directly in your SQL
";
}
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/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/OracleHints/">Adding Oracle hints to queries</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/SchemaMapping/" title="Previous section: Mapping generated schemata and tables to productive environments">previous</a> : <a href="<?=$root?>/manual/ADVANCED/CONNECTBY/" title="Next section: The Oracle CONNECT BY clause for hierarchical queries">next</a></td>
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/OracleHints/">Adding Oracle hints to queries</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/SchemaMapping/" title="Previous section: Mapping generated schemata and tables">previous</a> : <a href="<?=$root?>/manual/ADVANCED/CONNECTBY/" title="Next section: The Oracle CONNECT BY clause">next</a></td>
</tr>
</table><br><table cellpadding="0" cellspacing="0" border="0" width="100%">
</table>
<h2>How to embed Oracle hints in SELECT</h2>
<p>If you are closely coupling your application to an Oracle database,
you might need to be able to pass hints of the form /*+HINT*/ with
your SQL statements to the Oracle database. For example: </p>
<pre class="prettyprint lang-sql">
SELECT /*+ALL_ROWS*/ FIRST_NAME, LAST_NAME
FROM T_AUTHOR</pre>
<p>This can be done in jOOQ using the .hint() clause in your SELECT statement: </p>
<pre class="prettyprint lang-java">
create.select(FIRST_NAME, LAST_NAME)
.hint("/*+ALL_ROWS*/")
.from(T_AUTHOR);</pre>
<p>Note that you can pass any string in the .hint() clause. If you use
that clause, the passed string will always be put in between the
SELECT [DISTINCT] keywords and the actual projection list </p>
<br><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/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/OracleHints/">Adding Oracle hints to queries</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/SchemaMapping/" title="Previous section: Mapping generated schemata and tables to productive environments">previous</a> : <a href="<?=$root?>/manual/ADVANCED/CONNECTBY/" title="Next section: The Oracle CONNECT BY clause for hierarchical queries">next</a></td>
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/OracleHints/">Adding Oracle hints to queries</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/SchemaMapping/" title="Previous section: Mapping generated schemata and tables">previous</a> : <a href="<?=$root?>/manual/ADVANCED/CONNECTBY/" title="Next section: The Oracle CONNECT BY clause">next</a></td>
</tr>
</table>
<?php

View File

@ -4,24 +4,134 @@
// Please do not edit this content manually
require '../../../frame.php';
function printH1() {
print "Mapping generated schemata and tables to productive environments";
print "Mapping generated schemata and tables";
}
function getActiveMenu() {
return "manual";
}
function getSlogan() {
return "";
return "
Sometimes, you cannot control productive schema names, because your
application is deployed on a shared host, and you only get one schema
to work with.
";
}
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/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/SchemaMapping/">Mapping generated schemata and tables to productive environments</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/MasterData/" title="Previous section: Master data generation">previous</a> : <a href="<?=$root?>/manual/ADVANCED/OracleHints/" title="Next section: Adding Oracle hints to queries">next</a></td>
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/SchemaMapping/">Mapping generated schemata and tables</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/MasterData/" title="Previous section: Master data generation. Enumeration tables">previous</a> : <a href="<?=$root?>/manual/ADVANCED/OracleHints/" title="Next section: Adding Oracle hints to queries">next</a></td>
</tr>
</table><br><table cellpadding="0" cellspacing="0" border="0" width="100%">
</table>
<h2>Mapping your DEV schema to a productive environment</h2>
<p>You may wish to design your database in a way that you have several
instances of your schema. This is useful when you want to cleanly
separate data belonging to several customers / organisation units /
branches / users and put each of those entities' data in a separate
database or schema. </p>
<p>In our T_AUTHOR example this would mean that you provide a book
reference database to several companies, such as My Book World and
Books R Us. In that case, you'll probably have a schema setup like
this: </p>
<ul>
<li>DEV: Your development schema. This will be the schema that you
base code generation upon, with jOOQ </li>
<li>MY_BOOK_WORLD: The schema instance for My Book World </li>
<li>BOOKS_R_US: The schema instance for Books R Us </li>
</ul>
<h2>Mapping DEV to MY_BOOK_WORLD with jOOQ</h2>
<p>When a user from My Book World logs in, you want them to access the
MY_BOOK_WORLD schema using classes generated from DEV. This can be
achieved with the
<a href="https://github.com/lukaseder/jOOQ/blob/master/jOOQ/src/main/java/org/jooq/SchemaMapping.java" title="Internal API reference: org.jooq.SchemaMapping">org.jooq.SchemaMapping</a>
class, that you can equip your Factory
with. Take the following example: </p>
<pre class="prettyprint lang-java">
SchemaMapping mapping = new SchemaMapping();
mapping.add(DEV, "MY_BOOK_WORLD");
// Add the mapping to the factory
Factory create = new Factory(connection, SQLDialect.ORACLE, mapping);
// Run queries with the "mapped" factory
create.selectFrom(T_AUTHOR).fetch();</pre>
<p>The query executed with a Factory equipped with the above mapping
will in fact produce this SQL statement: </p>
<pre class="prettyprint lang-sql">SELECT * FROM MY_BOOK_WORLD.T_AUTHOR</pre>
<p>Even if T_AUTHOR was generated from DEV. </p>
<h2>Mapping several schemata</h2>
<p>Your development database may not be restricted to hold only one DEV
schema. You may also have a LOG schema and a MASTER schema. Let's say
the MASTER schema is shared among all customers, but each customer has
their own LOG schema instance. Then you can enhance your SchemaMapping
like this: </p>
<pre class="prettyprint lang-java">
SchemaMapping mapping = new SchemaMapping();
mapping.add(DEV, "MY_BOOK_WORLD");
mapping.add(LOG, "MY_BOOK_WORLD_LOG");</pre>
<p>This will map generated classes from DEV to MY_BOOK_WORLD, from LOG
to MY_BOOK_WORLD_LOG, but leave the MASTER schema alone. Whenever you
want to change your mapping configuration, you will have to create a
new Factory</p>
<h2>Using a default schema</h2>
<p>Another option to switch schema names is to use a default schema for
the Factory's underlying Connection. Many RDBMS support a USE or SET
SCHEMA command, which you can call like this: </p>
<pre class="prettyprint lang-java">
// Set the default schema
Schema MY_BOOK_WORLD = ...
create.use(MY_BOOK_WORLD);
// Run queries with factory having a default schema
create.selectFrom(T_AUTHOR).fetch();</pre>
<p>Queries generated from the above Factory will produce this kind of SQL statement: </p>
<pre class="prettyprint lang-sql">
-- the schema name is omitted from all SQL constructs.
SELECT * FROM T_AUTHOR</pre>
<h2>Mapping of tables</h2>
<p>Not only schemata can be mapped, but also tables. If you are not the
owner of the database your application connects to, you might need to
install your schema with some sort of prefix to every table. In our
examples, this might mean that you will have to map DEV.T_AUTHOR to
something MY_BOOK_WORLD.MY_APP__T_AUTHOR, where MY_APP__ is a prefix
applied to all of your tables. This can be achieved by creating the
following mapping: </p>
<pre class="prettyprint lang-java">
SchemaMapping mapping = new SchemaMapping();
mapping.add(DEV, "MY_BOOK_WORLD");
mapping.add(T_AUTHOR, "MY_APP__T_AUTHOR");
// Add the mapping to the factory
Factory create = new Factory(connection, SQLDialect.ORACLE, mapping);
// Run queries with the "mapped" factory
create.selectFrom(T_AUTHOR).fetch();</pre>
<p>The query executed with a Factory equipped with the above mapping will in fact produce this SQL statement: </p>
<pre class="prettyprint lang-sql">
SELECT * FROM MY_BOOK_WORLD.MY_APP__T_AUTHOR</pre>
<br><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/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/SchemaMapping/">Mapping generated schemata and tables to productive environments</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/MasterData/" title="Previous section: Master data generation">previous</a> : <a href="<?=$root?>/manual/ADVANCED/OracleHints/" title="Next section: Adding Oracle hints to queries">next</a></td>
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/ADVANCED/">Advanced topics</a> : <a href="<?=$root?>/manual/ADVANCED/SchemaMapping/">Mapping generated schemata and tables</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/ADVANCED/MasterData/" title="Previous section: Master data generation. Enumeration tables">previous</a> : <a href="<?=$root?>/manual/ADVANCED/OracleHints/" title="Next section: Adding Oracle hints to queries">next</a></td>
</tr>
</table>
<?php

View File

@ -18,33 +18,33 @@ function printContent() {
?>
<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/ADVANCED/">Advanced topics</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/DSL/SQL/" title="Previous section: When it's just easier: Plain SQL">previous</a> : <a href="<?=$root?>/manual/ADVANCED/MasterData/" title="Next section: Master data generation">next</a></td>
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/ADVANCED/">Advanced topics</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/DSL/SQL/" title="Previous section: When it's just easier: Plain SQL">previous</a> : <a href="<?=$root?>/manual/ADVANCED/MasterData/" title="Next section: Master data generation. Enumeration tables">next</a></td>
</tr>
</table>
<h2>Overview</h2>
<p>This section covers some advanced topics and features that don't fit into any other section. </p>
<h3>Table of contents</h3><ol>
<li>
<a href="<?=$root?>/manual/ADVANCED/MasterData/" title="Master data generation">Master data generation</a>
<a href="<?=$root?>/manual/ADVANCED/MasterData/" title="Master data generation. Enumeration tables">Master data generation. Enumeration tables</a>
</li>
<li>
<a href="<?=$root?>/manual/ADVANCED/SchemaMapping/" title="Mapping generated schemata and tables to productive environments">Mapping generated schemata and tables to productive environments</a>
<a href="<?=$root?>/manual/ADVANCED/SchemaMapping/" title="Mapping generated schemata and tables">Mapping generated schemata and tables</a>
</li>
<li>
<a href="<?=$root?>/manual/ADVANCED/OracleHints/" title="Adding Oracle hints to queries">Adding Oracle hints to queries</a>
</li>
<li>
<a href="<?=$root?>/manual/ADVANCED/CONNECTBY/" title="The Oracle CONNECT BY clause for hierarchical queries">The Oracle CONNECT BY clause for hierarchical queries</a>
<a href="<?=$root?>/manual/ADVANCED/CONNECTBY/" title="The Oracle CONNECT BY clause">The Oracle CONNECT BY clause</a>
</li>
<li>
<a href="<?=$root?>/manual/ADVANCED/Export/" title="Exporting data to XML, CSV, JSON, HTML, Text">Exporting data to XML, CSV, JSON, HTML, Text</a>
<a href="<?=$root?>/manual/ADVANCED/Export/" title="Exporting to XML, CSV, JSON, HTML, Text">Exporting to XML, CSV, JSON, HTML, Text</a>
</li>
<li>
<a href="<?=$root?>/manual/ADVANCED/Import/" title="Importing data from XML, CSV">Importing data from XML, CSV</a>
</li>
</ol><br><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/ADVANCED/">Advanced topics</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/DSL/SQL/" title="Previous section: When it's just easier: Plain SQL">previous</a> : <a href="<?=$root?>/manual/ADVANCED/MasterData/" title="Next section: Master data generation">next</a></td>
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/ADVANCED/">Advanced topics</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/DSL/SQL/" title="Previous section: When it's just easier: Plain SQL">previous</a> : <a href="<?=$root?>/manual/ADVANCED/MasterData/" title="Next section: Master data generation. Enumeration tables">next</a></td>
</tr>
</table>
<?php

View File

@ -60,7 +60,7 @@ function printContent() {
<li>
<a href="https://github.com/lukaseder/jOOQ/blob/master/jOOQ/src/main/java/org/jooq/SchemaMapping.java" title="Internal API reference: org.jooq.SchemaMapping">org.jooq.SchemaMapping</a> :
An optional mapping of schemata. Check out the
<a href="<?=$root?>/manual/ADVANCED/SchemaMapping/" title="jOOQ Manual reference: Mapping generated schemata and tables to productive environments">SchemaMapping</a>
<a href="<?=$root?>/manual/ADVANCED/SchemaMapping/" title="jOOQ Manual reference: Mapping generated schemata and tables">SchemaMapping</a>
page for details</li>
</ul>
@ -89,7 +89,7 @@ MySQLFactory create = new MySQLFactory(connection);
</p>
<ul>
<li>Oracle's <a href="<?=$root?>/manual/ADVANCED/CONNECTBY/" title="jOOQ Manual reference: The Oracle CONNECT BY clause for hierarchical queries">CONNECT BY</a>
<li>Oracle's <a href="<?=$root?>/manual/ADVANCED/CONNECTBY/" title="jOOQ Manual reference: The Oracle CONNECT BY clause">CONNECT BY</a>
pseudo columns and functions</li>
<li>MySQL's encryption functions</li>

View File

@ -21,7 +21,87 @@ 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/QueryPart/">QueryParts and the global architecture</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/JOOQ/ResultQuery/" title="Previous section: ResultQuery and various ways of fetching data">previous</a> : <a href="<?=$root?>/manual/JOOQ/Serializability/" title="Next section: Serializability of QueryParts and Results">next</a></td>
</tr>
</table><br><table cellpadding="0" cellspacing="0" border="0" width="100%">
</table>
<h2>Everything is a QueryPart</h2>
<p>
A
<a href="https://github.com/lukaseder/jOOQ/blob/master/jOOQ/src/main/java/org/jooq/Query.java" title="Internal API reference: org.jooq.Query">org.jooq.Query</a>
and all its contained objects is a
<a href="https://github.com/lukaseder/jOOQ/blob/master/jOOQ/src/main/java/org/jooq/QueryPart.java" title="Internal API reference: org.jooq.QueryPart">org.jooq.QueryPart</a>.
QueryParts essentially provide this functionality:
</p>
<ul>
<li>they can render SQL using the toSQL(RenderContext) method</li>
<li>they can bind variables using the bind(BindContext) method</li>
</ul>
<p>Both of these methods are contained in jOOQ's internal API's
<a href="https://github.com/lukaseder/jOOQ/blob/master/jOOQ/src/main/java/org/jooq/QueryPartInternal.java" title="Internal API reference: org.jooq.QueryPartInternal">org.jooq.QueryPartInternal</a>, which is
internally implemented by every QueryPart. QueryPart internals are best
illustrated with an example.</p>
<h2>Example: CompareCondition</h2>
<p>A simple example can be provided by checking out jOOQ's internal
representation of a
<a href="https://github.com/lukaseder/jOOQ/blob/master/jOOQ/src/main/java/org/jooq/impl/CompareCondition.java" title="Internal API reference: org.jooq.impl.CompareCondition">org.jooq.impl.CompareCondition</a>.
It is used for any condition
comparing two fields as for example the T_AUTHOR.ID = T_BOOK.AUTHOR_ID
condition here: </p>
<pre class="prettyprint lang-sql">
-- [...]
FROM T_AUTHOR
JOIN T_BOOK ON T_AUTHOR.ID = T_BOOK.AUTHOR_ID
-- [...]</pre>
<p>This is how jOOQ implements such a condition: </p>
<pre class="prettyprint lang-java">
@Override
public final void bind(BindContext context) throws SQLException {
// The CompareCondition itself does not bind any variables.
// But the two fields involved in the condition might do so...
context.bind(field1).bind(field2);
}
@Override
public final void toSQL(RenderContext context) {
// The CompareCondition delegates rendering of the Fields to the Fields
// themselves and connects them using the Condition's comparator operator:
context.sql(field1)
.sql(" ");
// If the second field is null, some convenience behaviour can be
// implemented here
if (field2.isNullLiteral()) {
switch (comparator) {
case EQUALS:
context.sql("is null");
break;
case NOT_EQUALS:
context.sql("is not null");
break;
default:
throw new IllegalStateException("Cannot compare null with " + comparator);
}
}
// By default, also delegate the right hand side's SQL rendering to the
// underlying field
else {
context.sql(comparator.toSQL())
.sql(" ")
.sql(field2);
}
}
</pre>
<p>For more complex examples, please refer to the codebase, directly</p>
<br><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/QueryPart/">QueryParts and the global architecture</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/JOOQ/ResultQuery/" title="Previous section: ResultQuery and various ways of fetching data">previous</a> : <a href="<?=$root?>/manual/JOOQ/Serializability/" title="Next section: Serializability of QueryParts and Results">next</a></td>
</tr>

View File

@ -117,7 +117,7 @@ generator.generate.master-data-tables=[a list of tables]
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>
<a href="<?=$root?>/manual/ADVANCED/MasterData/" title="jOOQ Manual reference: Master data generation. Enumeration tables">master data</a>
to find out more
about those advanced configuration parameters. </p>

View File

@ -43,7 +43,7 @@ function printContent() {
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>
<a href="<?=$root?>/manual/ADVANCED/SchemaMapping/" title="jOOQ Manual reference: Mapping generated schemata and tables">multiple equivalent schemata</a>
</p>

View File

@ -328,7 +328,7 @@ public class TBookRecord extends UpdatableRecordImpl&lt;TBookRecord&gt; {
<p>Note that jOOQ allows you to simulate ENUM types where this makes
sense in your data model. See the section on
<a href="<?=$root?>/manual/ADVANCED/MasterData/" title="jOOQ Manual reference: Master data generation">master data</a> for more
<a href="<?=$root?>/manual/ADVANCED/MasterData/" title="jOOQ Manual reference: Master data generation. Enumeration tables">master data</a> for more
details. </p>
<br><table cellpadding="0" cellspacing="0" border="0" width="100%">
<tr>

View File

@ -189,19 +189,19 @@ function printContent() {
<a href="<?=$root?>/manual/ADVANCED/" title="Advanced topics">Advanced topics</a>
<ol>
<li>
<a href="<?=$root?>/manual/ADVANCED/MasterData/" title="Master data generation">Master data generation</a>
<a href="<?=$root?>/manual/ADVANCED/MasterData/" title="Master data generation. Enumeration tables">Master data generation. Enumeration tables</a>
</li>
<li>
<a href="<?=$root?>/manual/ADVANCED/SchemaMapping/" title="Mapping generated schemata and tables to productive environments">Mapping generated schemata and tables to productive environments</a>
<a href="<?=$root?>/manual/ADVANCED/SchemaMapping/" title="Mapping generated schemata and tables">Mapping generated schemata and tables</a>
</li>
<li>
<a href="<?=$root?>/manual/ADVANCED/OracleHints/" title="Adding Oracle hints to queries">Adding Oracle hints to queries</a>
</li>
<li>
<a href="<?=$root?>/manual/ADVANCED/CONNECTBY/" title="The Oracle CONNECT BY clause for hierarchical queries">The Oracle CONNECT BY clause for hierarchical queries</a>
<a href="<?=$root?>/manual/ADVANCED/CONNECTBY/" title="The Oracle CONNECT BY clause">The Oracle CONNECT BY clause</a>
</li>
<li>
<a href="<?=$root?>/manual/ADVANCED/Export/" title="Exporting data to XML, CSV, JSON, HTML, Text">Exporting data to XML, CSV, JSON, HTML, Text</a>
<a href="<?=$root?>/manual/ADVANCED/Export/" title="Exporting to XML, CSV, JSON, HTML, Text">Exporting to XML, CSV, JSON, HTML, Text</a>
</li>
<li>
<a href="<?=$root?>/manual/ADVANCED/Import/" title="Importing data from XML, CSV">Importing data from XML, CSV</a>

View File

@ -298,6 +298,11 @@ function printContent() {
<xsl:value-of select="text()"/>
</pre>
</xsl:when>
<xsl:when test="name(.) = 'text'">
<pre>
<xsl:value-of select="text()"/>
</pre>
</xsl:when>
<xsl:when test="name(.) = 'code-pair'">
<table width="100%" cellpadding="0" cellspacing="0">
<tr>

View File

@ -1017,6 +1017,84 @@ public interface ResultQuery&lt;R extends Record&gt; {
<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>
<content>
<h2>Everything is a QueryPart</h2>
<p>
A
<reference class="org.jooq.Query" />
and all its contained objects is a
<reference class="org.jooq.QueryPart" />.
QueryParts essentially provide this functionality:
</p>
<ul>
<li>they can render SQL using the toSQL(RenderContext) method</li>
<li>they can bind variables using the bind(BindContext) method</li>
</ul>
<p>Both of these methods are contained in jOOQ's internal API's
<reference class="org.jooq.QueryPartInternal"/>, which is
internally implemented by every QueryPart. QueryPart internals are best
illustrated with an example.</p>
<h2>Example: CompareCondition</h2>
<p>A simple example can be provided by checking out jOOQ's internal
representation of a
<reference class="org.jooq.impl.CompareCondition"/>.
It is used for any condition
comparing two fields as for example the T_AUTHOR.ID = T_BOOK.AUTHOR_ID
condition here: </p>
<sql>
-- [...]
FROM T_AUTHOR
JOIN T_BOOK ON T_AUTHOR.ID = T_BOOK.AUTHOR_ID
-- [...]</sql>
<p>This is how jOOQ implements such a condition: </p>
<java><![CDATA[
@Override
public final void bind(BindContext context) throws SQLException {
// The CompareCondition itself does not bind any variables.
// But the two fields involved in the condition might do so...
context.bind(field1).bind(field2);
}
@Override
public final void toSQL(RenderContext context) {
// The CompareCondition delegates rendering of the Fields to the Fields
// themselves and connects them using the Condition's comparator operator:
context.sql(field1)
.sql(" ");
// If the second field is null, some convenience behaviour can be
// implemented here
if (field2.isNullLiteral()) {
switch (comparator) {
case EQUALS:
context.sql("is null");
break;
case NOT_EQUALS:
context.sql("is not null");
break;
default:
throw new IllegalStateException("Cannot compare null with " + comparator);
}
}
// By default, also delegate the right hand side's SQL rendering to the
// underlying field
else {
context.sql(comparator.toSQL())
.sql(" ")
.sql(field2);
}
}
]]></java>
<p>For more complex examples, please refer to the codebase, directly</p>
</content>
</section>
@ -3307,7 +3385,7 @@ create.select(LAST_NAME, COUNT1, COUNT2)
<sections>
<section id="MasterData">
<title>Master data generation</title>
<title>Master data generation. Enumeration tables</title>
<slogan>Enumerations are a powerful concept. Unfortunately, almost no
RDBMS supports them, leaving you to create numerous tables for your
enumerated values. But these values are still enumerations!</slogan>
@ -3416,27 +3494,432 @@ public class TBookRecord extends UpdatableRecordImpl<TBookRecord> {
<section id="SchemaMapping">
<title>Mapping generated schemata and tables to productive environments</title>
<title>Mapping generated schemata and tables</title>
<slogan>
Sometimes, you cannot control productive schema names, because your
application is deployed on a shared host, and you only get one schema
to work with.
</slogan>
<content>
<h2>Mapping your DEV schema to a productive environment</h2>
<p>You may wish to design your database in a way that you have several
instances of your schema. This is useful when you want to cleanly
separate data belonging to several customers / organisation units /
branches / users and put each of those entities' data in a separate
database or schema. </p>
<p>In our T_AUTHOR example this would mean that you provide a book
reference database to several companies, such as My Book World and
Books R Us. In that case, you'll probably have a schema setup like
this: </p>
<ul>
<li>DEV: Your development schema. This will be the schema that you
base code generation upon, with jOOQ </li>
<li>MY_BOOK_WORLD: The schema instance for My Book World </li>
<li>BOOKS_R_US: The schema instance for Books R Us </li>
</ul>
<h2>Mapping DEV to MY_BOOK_WORLD with jOOQ</h2>
<p>When a user from My Book World logs in, you want them to access the
MY_BOOK_WORLD schema using classes generated from DEV. This can be
achieved with the
<reference class="org.jooq.SchemaMapping"/>
class, that you can equip your Factory
with. Take the following example: </p>
<java>
SchemaMapping mapping = new SchemaMapping();
mapping.add(DEV, "MY_BOOK_WORLD");
// Add the mapping to the factory
Factory create = new Factory(connection, SQLDialect.ORACLE, mapping);
// Run queries with the "mapped" factory
create.selectFrom(T_AUTHOR).fetch();</java>
<p>The query executed with a Factory equipped with the above mapping
will in fact produce this SQL statement: </p>
<sql>SELECT * FROM MY_BOOK_WORLD.T_AUTHOR</sql>
<p>Even if T_AUTHOR was generated from DEV. </p>
<h2>Mapping several schemata</h2>
<p>Your development database may not be restricted to hold only one DEV
schema. You may also have a LOG schema and a MASTER schema. Let's say
the MASTER schema is shared among all customers, but each customer has
their own LOG schema instance. Then you can enhance your SchemaMapping
like this: </p>
<java>
SchemaMapping mapping = new SchemaMapping();
mapping.add(DEV, "MY_BOOK_WORLD");
mapping.add(LOG, "MY_BOOK_WORLD_LOG");</java>
<p>This will map generated classes from DEV to MY_BOOK_WORLD, from LOG
to MY_BOOK_WORLD_LOG, but leave the MASTER schema alone. Whenever you
want to change your mapping configuration, you will have to create a
new Factory</p>
<h2>Using a default schema</h2>
<p>Another option to switch schema names is to use a default schema for
the Factory's underlying Connection. Many RDBMS support a USE or SET
SCHEMA command, which you can call like this: </p>
<java>
// Set the default schema
Schema MY_BOOK_WORLD = ...
create.use(MY_BOOK_WORLD);
// Run queries with factory having a default schema
create.selectFrom(T_AUTHOR).fetch();</java>
<p>Queries generated from the above Factory will produce this kind of SQL statement: </p>
<sql>
-- the schema name is omitted from all SQL constructs.
SELECT * FROM T_AUTHOR</sql>
<h2>Mapping of tables</h2>
<p>Not only schemata can be mapped, but also tables. If you are not the
owner of the database your application connects to, you might need to
install your schema with some sort of prefix to every table. In our
examples, this might mean that you will have to map DEV.T_AUTHOR to
something MY_BOOK_WORLD.MY_APP__T_AUTHOR, where MY_APP__ is a prefix
applied to all of your tables. This can be achieved by creating the
following mapping: </p>
<java>
SchemaMapping mapping = new SchemaMapping();
mapping.add(DEV, "MY_BOOK_WORLD");
mapping.add(T_AUTHOR, "MY_APP__T_AUTHOR");
// Add the mapping to the factory
Factory create = new Factory(connection, SQLDialect.ORACLE, mapping);
// Run queries with the "mapped" factory
create.selectFrom(T_AUTHOR).fetch();</java>
<p>The query executed with a Factory equipped with the above mapping will in fact produce this SQL statement: </p>
<sql>
SELECT * FROM MY_BOOK_WORLD.MY_APP__T_AUTHOR</sql>
</content>
</section>
<section id="OracleHints">
<title>Adding Oracle hints to queries</title>
<slogan>
Oracle has a powerful syntax to add hints as comments directly in your SQL
</slogan>
<content>
<h2>How to embed Oracle hints in SELECT</h2>
<p>If you are closely coupling your application to an Oracle database,
you might need to be able to pass hints of the form /*+HINT*/ with
your SQL statements to the Oracle database. For example: </p>
<sql>
SELECT /*+ALL_ROWS*/ FIRST_NAME, LAST_NAME
FROM T_AUTHOR</sql>
<p>This can be done in jOOQ using the .hint() clause in your SELECT statement: </p>
<java>
create.select(FIRST_NAME, LAST_NAME)
.hint("/*+ALL_ROWS*/")
.from(T_AUTHOR);</java>
<p>Note that you can pass any string in the .hint() clause. If you use
that clause, the passed string will always be put in between the
SELECT [DISTINCT] keywords and the actual projection list </p>
</content>
</section>
<section id="CONNECTBY">
<title>The Oracle CONNECT BY clause for hierarchical queries</title>
<title>The Oracle CONNECT BY clause</title>
<slogan>
Hierarchical queries are supported by many RDBMS using the WITH clause.
Oracle has a very neat and much less verbose syntax for hierarchical
queries: CONNECT BY .. STARTS WITH
</slogan>
<content>
<h2>CONNECT BY .. STARTS WITH</h2>
<p>If you are closely coupling your application to an Oracle database,
you can take advantage of some Oracle-specific features, such as the
CONNECT BY clause, used for hierarchical queries. The formal syntax
definition is as follows: </p>
<sql>
-- SELECT ..
-- FROM ..
-- WHERE ..
CONNECT BY [NOCYCLE] condition [AND condition, ...] [START WITH condition]
-- GROUP BY ..</sql>
<p>This can be done in jOOQ using the .connectBy(Condition) clauses in your SELECT statement: </p>
<java>
// Some Oracle-specific features are only available
// from the OracleFactory
OracleFactory create = new OracleFactory(connection);
// Get a table with elements 1, 2, 3, 4, 5
create.select(create.rownum())
.connectBy(create.level().lessOrEqual(5))
.fetch();</java>
<p>Here's a more complex example where you can recursively fetch
directories in your database, and concatenate them to a path:</p>
<java><![CDATA[
OracleFactory ora = new OracleFactory(connection);
List<?> paths =
ora.select(ora.sysConnectByPath(Directory.NAME, "/").substring(2))
.from(Directory)
.connectBy(ora.prior(Directory.ID).equal(Directory.PARENT_ID))
.startWith(Directory.PARENT_ID.isNull())
.orderBy(ora.literal(1))
.fetch(0);]]></java>
<p>The output might then look like this</p>
<text>
+------------------------------------------------+
|substring |
+------------------------------------------------+
|C: |
|C:/eclipse |
|C:/eclipse/configuration |
|C:/eclipse/dropins |
|C:/eclipse/eclipse.exe |
+------------------------------------------------+
|...21 record(s) truncated...
</text>
</content>
</section>
<section id="Export">
<title>Exporting data to XML, CSV, JSON, HTML, Text</title>
<title>Exporting to XML, CSV, JSON, HTML, Text</title>
<slogan>
Get your data out of the Java world. Stream your data using any of the supported, wide-spread formats
</slogan>
<content>
<h2>Exporting with jOOQ</h2>
<p>If you are using jOOQ for scripting purposes or in a slim, unlayered
application server, you might be interested in using jOOQ's exporting
functionality (see also importing functionality). You can export any
Result&lt;Record&gt; into any of these formats: </p>
<h3>XML</h3>
<p>Export your results as XML: </p>
<java>
// Fetch books and format them as XML
String xml = create.selectFrom(T_BOOK).fetch().formatXML();</java>
<p>The above query will result in an XML document looking like the following one: </p>
<xml><![CDATA[
<!-- Find the XSD definition on www.jooq.org: -->
<jooq-export:result xmlns:jooq-export="http://www.jooq.org/xsd/jooq-export-1.6.2.xsd">
<fields>
<field name="ID"/>
<field name="AUTHOR_ID"/>
<field name="TITLE"/>
</fields>
<records>
<record>
<value field="ID">1</value>
<value field="AUTHOR_ID">1</value>
<value field="TITLE">1984</value>
</record>
<record>
<value field="ID">2</value>
<value field="AUTHOR_ID">1</value>
<value field="TITLE">Animal Farm</value>
</record>
</records>
</jooq-export:result>]]></xml>
<h3>CSV</h3>
<p>Export your results as CSV: </p>
<java>
// Fetch books and format them as CSV
String csv = create.selectFrom(T_BOOK).fetch().formatCSV();</java>
<p>The above query will result in a CSV document looking like the following one: </p>
<text>
ID;AUTHOR_ID;TITLE
1;1;1984
2;1;Animal Farm</text>
<h3>JSON</h3>
<p>Export your results as JSON: </p>
<java>
// Fetch books and format them as JSON
String json = create.selectFrom(T_BOOK).fetch().formatJSON();</java>
<p>The above query will result in a JSON document looking like the following one: </p>
<text>
{fields:["ID","AUTHOR_ID","TITLE"],
records:[[1,1,"1984"],[2,1,"Animal Farm"]]}</text>
<h3>HTML </h3>
<p>Export your results as HTML: </p>
<java>
// Fetch books and format them as HTML
String html = create.selectFrom(T_BOOK).fetch().formatHTML();</java>
<p>The above query will result in an HTML document looking like the following one: </p>
<xml><![CDATA[
<table>
<thead>
<tr>
<th>ID</th>
<th>AUTHOR_ID</th>
<th>TITLE</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>1</td>
<td>1984</td>
</tr>
<tr>
<td>2</td>
<td>1</td>
<td>Animal Farm</td>
</tr>
</tbody>
</table>]]></xml>
<h3>Text</h3>
<p>Export your results as text: </p>
<java>
// Fetch books and format them as text
String text = create.selectFrom(T_BOOK).fetch().format();</java>
<p>The above query will result in a text document looking like the following one: </p>
<text>
+---+---------+-----------+
| ID|AUTHOR_ID|TITLE |
+---+---------+-----------+
| 1| 1|1984 |
| 2| 1|Animal Farm|
+---+---------+-----------+</text>
</content>
</section>
<section id="Import">
<title>Importing data from XML, CSV</title>
<slogan>
Use jOOQ to easily merge imported data into your database.
</slogan>
<content>
<h2>Importing with jOOQ</h2>
<p>If you are using jOOQ for scripting purposes or in a slim, unlayered
application server, you might be interested in using jOOQ's importing
functionality (see also exporting functionality). You can import data
directly into a table from any of these formats: </p>
<h3>CSV</h3>
<p>The below CSV data represents two author records that may have been
exported previously, by jOOQ's exporting functionality, and then
modified in Microsoft Excel or any other spreadsheet tool: </p>
<text>
ID;AUTHOR_ID;TITLE
1;1;1984
2;1;Animal Farm</text>
<p>With jOOQ, you can load this data using various parameters from the
loader API. A simple load may look like this: </p>
<java>
Factory create = new Factory(connection, SQLDialect.ORACLE);
// Load data into the T_AUTHOR table from an input stream
// holding the CSV data.
create.loadInto(T_AUTHOR)
.loadCSV(inputstream)
.fields(ID, AUTHOR_ID, TITLE)
.execute();</java>
<p>Here are various other examples: </p>
<java>
// Ignore the AUTHOR_ID column from the CSV file when inserting
create.loadInto(T_AUTHOR)
.loadCSV(inputstream)
.fields(ID, null, TITLE)
.execute();
// Specify behaviour for duplicate records.
create.loadInto(T_AUTHOR)
// choose any of these methods
.onDuplicateKeyUpdate()
.onDuplicateKeyIgnore()
.onDuplicateKeyError() // the default
.loadCSV(inputstream)
.fields(ID, null, TITLE)
.execute();
// Specify behaviour when errors occur.
create.loadInto(T_AUTHOR)
// choose any of these methods
.onErrorIgnore()
.onErrorAbort() // the default
.loadCSV(inputstream)
.fields(ID, null, TITLE)
.execute();
// Specify transactional behaviour where this is possible
// (e.g. not in container-managed transactions)
create.loadInto(T_AUTHOR)
// choose any of these methods
.commitEach()
.commitAfter(10)
.commitAll()
.commitNone() // the default
.loadCSV(inputstream)
.fields(ID, null, TITLE)
.execute();</java>
<p>Any of the above configuration methods can be combined to achieve
the type of load you need. Please refer to the API's Javadoc to learn
about more details. Errors that occur during the load are reported by
the execute method's result: </p>
<java><![CDATA[
Loader<TAuthor> loader = /* .. */ .execute();
// The number of processed rows
int processed = loader.processed();
// The number of stored rows (INSERT or UPDATE)
int stored = loader.stored();
// The number of ignored rows (due to errors, or duplicate rule)
int ignored = loader.ignored();
// The errors that may have occurred during loading
List<LoaderError> errors = loader.errors();
LoaderError error = errors.get(0);
// The exception that caused the error
SQLException exception = error.exception();
// The row that caused the error
int rowIndex = error.rowIndex();
String[] row = error.row();
// The query that caused the error
Query query = error.query();]]></java>
<h3>XML </h3>
<p>This will be implemented soon... </p>
</content>
</section>
</sections>
</section>