Added some sections to the manual
Enhanced some styles
This commit is contained in:
parent
32feb254dc
commit
0379d92c5e
@ -8,6 +8,9 @@ function getSlogan() {
|
||||
motivated staff, providing new database integrations, website translations, and shouting out to
|
||||
the world about jOOQ. You have a blog? Write about jOOQ in your language!";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "contribute";
|
||||
}
|
||||
function printContent() {
|
||||
?>
|
||||
<h2>The hall of fame</h2>
|
||||
|
||||
@ -67,8 +67,19 @@ p.slogan {
|
||||
padding-left: 2em;
|
||||
color: #444;
|
||||
font-family: 'Georgia',Serif;
|
||||
font-style: italic;
|
||||
height: 2.5em;
|
||||
height: 3em;
|
||||
|
||||
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;
|
||||
line-height: 1.5em;
|
||||
margin: 1.5em 0;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
td.left {
|
||||
@ -139,10 +150,15 @@ a:hover {
|
||||
background: -webkit-gradient(linear, left, right, from(#f6cab9), to(#ffeedd));
|
||||
background: -moz-linear-gradient(left, #f6cab9, #ffeedd);
|
||||
background: gradient(linear, left, right, from(#f6cab9), to(#ffeedd));
|
||||
|
||||
-webkit-box-shadow: inset rgba(0,0,0,.1) 0 5px 5px;
|
||||
-moz-box-shadow: inset rgba(0,0,0,.1) 0 5px 5px;
|
||||
box-shadow: inset rgba(0,0,0,.1) 0 5px 5px;
|
||||
border-top: 1px solid rgba(0,0,0,.2);
|
||||
}
|
||||
|
||||
#navigation {
|
||||
padding-top: 1.3em;
|
||||
padding-top: 20px;
|
||||
padding-left: 3em;
|
||||
padding-right: 3em;
|
||||
|
||||
@ -153,14 +169,37 @@ a:hover {
|
||||
background: gradient(linear, left top, left bottom, from(#555), to(#333));
|
||||
}
|
||||
|
||||
#tweets {
|
||||
display: none;
|
||||
padding-top: 1.3em;
|
||||
padding-left: 3em;
|
||||
padding-right: 3em;
|
||||
|
||||
height: 40px;
|
||||
|
||||
background: #444;
|
||||
background: -webkit-gradient(linear, left top, left bottom, from(#555), to(#333));
|
||||
background: -moz-linear-gradient(top, #555, #333);
|
||||
background: gradient(linear, left top, left bottom, from(#555), to(#333));
|
||||
}
|
||||
|
||||
#navigation a,
|
||||
#navigation a:link,
|
||||
#navigation a:visited,
|
||||
#navigation a:hover,
|
||||
#navigation a:active {
|
||||
color: #fadccb;
|
||||
color: #aaa;
|
||||
text-shadow: #000 -1px -1px 0px;
|
||||
text-decoration: none;
|
||||
text-shadow: 0 1px 1px #666666;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
#navigation .navigation-item-active a,
|
||||
#navigation .navigation-item-active a:link,
|
||||
#navigation .navigation-item-active a:visited,
|
||||
#navigation .navigation-item-active a:hover,
|
||||
#navigation .navigation-item-active a:active {
|
||||
color: #fadccb;
|
||||
}
|
||||
|
||||
#navigation a:hover {
|
||||
@ -169,11 +208,12 @@ a:hover {
|
||||
|
||||
div.navigation-item-left {
|
||||
float: left;
|
||||
padding-right: 2em;
|
||||
margin-right: 2em;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
#tweets {
|
||||
height: 40px;
|
||||
div.navigation-item-active {
|
||||
background: url("../img/navigation-item-active.png") no-repeat center bottom;
|
||||
}
|
||||
|
||||
#footer {
|
||||
@ -193,7 +233,8 @@ div.navigation-item-left {
|
||||
-moz-box-shadow: inset rgba(0,0,0,.1) 0 5px 5px;
|
||||
box-shadow: inset rgba(0,0,0,.1) 0 5px 5px;
|
||||
border-top: 1px solid rgba(0,0,0,.2);
|
||||
text-shadow: #555 -1px -1px 0px;}
|
||||
text-shadow: #555 -1px -1px 0px;
|
||||
}
|
||||
|
||||
div.tweet-item-left {
|
||||
float: left;
|
||||
|
||||
@ -14,55 +14,59 @@
|
||||
<div id="wrapper">
|
||||
<div class="block">
|
||||
<div id="navigation">
|
||||
<div class="navigation-item-left">
|
||||
<?php
|
||||
$menu = getActiveMenu();
|
||||
?>
|
||||
<div class="navigation-item-left <?php if ($menu == 'home') print 'navigation-item-active'?>">
|
||||
<a href="<?=$root?>/" title="jOOQ Home Page">Home</a>
|
||||
</div>
|
||||
<div class="navigation-item-left">
|
||||
<div class="navigation-item-left <?php if ($menu == 'download') print 'navigation-item-active'?>">
|
||||
<a href="https://sourceforge.net/projects/jooq/files/" title="jOOQ Download">Download</a>
|
||||
</div>
|
||||
<div class="navigation-item-left">
|
||||
<div class="navigation-item-left <?php if ($menu == 'manual') print 'navigation-item-active'?>">
|
||||
<a href="<?=$root?>/manual" title="jOOQ User Manual">Manual</a>
|
||||
</div>
|
||||
<div class="navigation-item-left">
|
||||
<div class="navigation-item-left <?php if ($menu == 'javadoc') print 'navigation-item-active'?>">
|
||||
<a href="<?=$root?>/javadoc/latest/" title="jOOQ Main Javadoc">Javadoc</a>
|
||||
</div>
|
||||
<div class="navigation-item-left">
|
||||
<div class="navigation-item-left <?php if ($menu == 'notes') print 'navigation-item-active'?>">
|
||||
<a href="<?=$root?>/notes.php" title="jOOQ Release Notes">Release Notes</a>
|
||||
</div>
|
||||
<div class="navigation-item-left">
|
||||
<div class="navigation-item-left <?php if ($menu == 'roadmap') print 'navigation-item-active'?>">
|
||||
<a href="https://sourceforge.net/apps/trac/jooq/report/6" title="jOOQ Roadmap">Roadmap</a>
|
||||
</div>
|
||||
<div class="navigation-item-left">
|
||||
<div class="navigation-item-left <?php if ($menu == 'contribute') print 'navigation-item-active'?>">
|
||||
<a href="<?=$root?>/contribute.php" title="Contribute to jOOQ">Contribute</a>
|
||||
</div>
|
||||
<div class="navigation-item-left">
|
||||
<div class="navigation-item-left <?php if ($menu == 'donations') print 'navigation-item-active'?>">
|
||||
<a href="https://sourceforge.net/project/project_donations.php?group_id=283484" title="Donate to jOOQ, if you like it!">Donate</a>
|
||||
</div>
|
||||
<div class="navigation-item-left">
|
||||
<div class="navigation-item-left <?php if ($menu == 'links') print 'navigation-item-active'?>">
|
||||
<a href="<?=$root?>/links.php" title="Interesting links for jOOQ users">Links</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<div id="tweets">
|
||||
<div class="tweet-item-left">
|
||||
<a href="http://twitter.com/share" class="twitter-share-button" data-text="jOOQ - A nice database abstraction library for Java" data-count="horizontal" data-via="lukaseder">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
|
||||
</div>
|
||||
<div class="tweet-item-left">
|
||||
<g:plusone size="medium"></g:plusone>
|
||||
</div>
|
||||
<div class="tweet-item-left">
|
||||
<div id="fb-root"></div>
|
||||
<script>(function(d, s, id) {
|
||||
var js, fjs = d.getElementsByTagName(s)[0];
|
||||
if (d.getElementById(id)) {return;}
|
||||
js = d.createElement(s); js.id = id;
|
||||
js.src = "//connect.facebook.net/en_US/all.js#appId=232666253447462&xfbml=1";
|
||||
fjs.parentNode.insertBefore(js, fjs);
|
||||
}(document, 'script', 'facebook-jssdk'));</script>
|
||||
<div class="fb-like" data-send="false" data-layout="button_count" data-width="450" data-show-faces="true" data-font="verdana"></div>
|
||||
</div>
|
||||
<div id="tweets">
|
||||
<div class="tweet-item-left">
|
||||
<a href="http://twitter.com/share" class="twitter-share-button" data-text="jOOQ - A nice database abstraction library for Java" data-count="horizontal" data-via="lukaseder">Tweet</a><script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
|
||||
</div>
|
||||
<div class="tweet-item-left">
|
||||
<g:plusone size="medium"></g:plusone>
|
||||
</div>
|
||||
<div class="tweet-item-left">
|
||||
<div id="fb-root"></div>
|
||||
<script>(function(d, s, id) {
|
||||
var js, fjs = d.getElementsByTagName(s)[0];
|
||||
if (d.getElementById(id)) {return;}
|
||||
js = d.createElement(s); js.id = id;
|
||||
js.src = "//connect.facebook.net/en_US/all.js#appId=232666253447462&xfbml=1";
|
||||
fjs.parentNode.insertBefore(js, fjs);
|
||||
}(document, 'script', 'facebook-jssdk'));</script>
|
||||
<div class="fb-like" data-send="false" data-layout="button_count" data-width="450" data-show-faces="true" data-font="verdana"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="content">
|
||||
<table width="100%" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td width="700" valign="top">
|
||||
|
||||
BIN
jOOQ-website/img/navigation-item-active.png
Normal file
BIN
jOOQ-website/img/navigation-item-active.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
@ -9,49 +9,37 @@ function getSlogan() {
|
||||
SQL was never meant to be object-oriented. SQL was never meant to be
|
||||
anything other than... SQL!";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "home";
|
||||
}
|
||||
function printContent() {
|
||||
?>
|
||||
<h2>What does jOOQ code look like?</h2>
|
||||
<p>It's simple. With the jOOQ DSL, SQL looks almost as if it were
|
||||
natively supported by Java.</p>
|
||||
natively supported by Java. For instance, get all books published in 2011, ordered by title</p>
|
||||
|
||||
<table width="100%" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td width="50%" class="left"><p>A simple SQL statement</p></td>
|
||||
<td width="50%" class="right"><p>...and its equivalent in jOOQ</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="50%" class="left"><pre class="prettyprint lang-sql">
|
||||
-- get all books published in 2011, ordered by title
|
||||
|
||||
SELECT *
|
||||
FROM BOOK
|
||||
SELECT * FROM BOOK
|
||||
WHERE PUBLISHED_IN = 2011
|
||||
ORDER BY TITLE</pre></td>
|
||||
<td width="50%" class="right"><pre class="prettyprint lang-java">
|
||||
Result<Book> books =
|
||||
create.selectFrom(BOOK)
|
||||
.where(PUBLISHED_IN.equal(2011))
|
||||
.orderBy(TITLE)
|
||||
.fetch();
|
||||
</pre></td>
|
||||
.orderBy(TITLE)</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>jOOQ also supports more complex SQL statements. get all authors'
|
||||
first and last names, and the number of books they've written in
|
||||
German, if they have written more than five books in German in the last
|
||||
three years (from 2011), and sort those authors by last names limiting
|
||||
results to the second and third row, then lock first and last names
|
||||
columns for update</p>
|
||||
<table width="100%" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td width="50%" class="left"><p>jOOQ also supports more complex SQL statements</p></td>
|
||||
<td width="50%" class="right"><p>...and their equivalent in jOOQ</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr>
|
||||
<td width="50%" class="left"><pre class="prettyprint lang-sql">
|
||||
-- get all authors' first and last names, and the number
|
||||
-- of books they've written in German, if they have written
|
||||
-- more than five books in German in the last three years
|
||||
-- (from 2011), and sort those authors by last names
|
||||
-- limiting results to the second and third row, then lock
|
||||
-- first and last names columns for update
|
||||
|
||||
SELECT FIRST_NAME, LAST_NAME, COUNT(*)
|
||||
FROM AUTHOR
|
||||
JOIN BOOK ON AUTHOR.ID = BOOK.AUTHOR_ID
|
||||
@ -65,12 +53,6 @@ ORDER BY LAST_NAME ASC NULLS FIRST
|
||||
FOR UPDATE
|
||||
OF FIRST_NAME, LAST_NAME</pre></td>
|
||||
<td width="50%" class="right"><pre class="prettyprint lang-java">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Result<Record> result =
|
||||
create.select(FIRST_NAME, LAST_NAME, create.count())
|
||||
.from(AUTHOR)
|
||||
.join(BOOK).on(Author.ID.equal(Book.AUTHOR_ID))
|
||||
@ -82,36 +64,20 @@ create.select(FIRST_NAME, LAST_NAME, create.count())
|
||||
.limit(2)
|
||||
.offset(1)
|
||||
.forUpdate()
|
||||
.of(FIRST_NAME, LAST_NAME)
|
||||
.fetch();</pre></td>
|
||||
.of(FIRST_NAME, LAST_NAME)</pre></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>What's jOOQ</h2>
|
||||
<h2>What is jOOQ?</h2>
|
||||
<p>jOOQ stands for Java Object Oriented Querying. It combines these essential features:</p>
|
||||
|
||||
<table cellpadding="0" cellspacing="0" width="100%">
|
||||
<tr>
|
||||
<td width="50%" class="left"><h3>Code Generation:</h3></td>
|
||||
<td width="50%" class="right"><p>jOOQ generates a simple Java representation of your database schema. Every table, view, stored procedure, enum, UDT is a class.</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="left"><h3>Active records:</h3></td>
|
||||
<td class="right"><p>jOOQ implements an easy-to-use active record pattern. It is NOT an OR-mapper, but provides a 1:1 mapping between tables/views and classes. Between columns and members.</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="left"><h3>Typesafe SQL:</h3></td>
|
||||
<td class="right"><p>jOOQ allows for writing compile-time typesafe querying using its built-in fluent API.</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="left"><h3>SQL standard:</h3></td>
|
||||
<td class="right"><p>jOOQ supports all standard SQL language features including the more complex UNION's, nested SELECTs, joins, aliasing</p></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="left"><h3>Vendor-specific feature support:</h3></td>
|
||||
<td class="right"><p>jOOQ encourages the use of vendor-specific extensions such as stored procedures, UDT's and ARRAY's, recursive queries, and many more.</p></td>
|
||||
</tr>
|
||||
</table>
|
||||
<ul>
|
||||
<li>Code Generation: jOOQ generates a simple Java representation of your database schema. Every table, view, stored procedure, enum, UDT is a class.</li>
|
||||
<li>Active records: jOOQ implements an easy-to-use active record pattern. It is NOT an OR-mapper, but provides a 1:1 mapping between tables/views and classes. Between columns and members.</li>
|
||||
<li>Typesafe SQL: jOOQ allows for writing compile-time typesafe querying using its built-in fluent API.</li>
|
||||
<li>SQL standard: jOOQ supports all standard SQL language features including the more complex UNION's, nested SELECTs, joins, aliasing</li>
|
||||
<li>Vendor-specific feature support: jOOQ encourages the use of vendor-specific extensions such as stored procedures, UDT's and ARRAY's, recursive queries, and many more.</li>
|
||||
</ul>
|
||||
|
||||
<h2>How does jOOQ help you?</h2>
|
||||
<ul>
|
||||
|
||||
@ -8,6 +8,9 @@ function getSlogan() {
|
||||
Here you will find further resources related to jOOQ, to similar products and
|
||||
other inspiration related to jOOQ";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "links";
|
||||
}
|
||||
function printContent() {
|
||||
global $root;
|
||||
?>
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "The Oracle CONNECT BY clause for hierarchical queries";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Exporting data to XML, CSV, JSON, HTML, Text";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Importing data from XML, CSV";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Master data generation";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Adding Oracle hints to queries";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Mapping generated schemata and tables to productive environments";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../frame.php';
|
||||
function printH1() {
|
||||
print "Advanced topics";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Aliased tables and fields";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "
|
||||
Aliasing is at the core of SQL and relational algebra. When you join
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Arithmetic operations";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "The CASE clause";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Type casting";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Conditions";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "
|
||||
The creation of conditions is the part of any database abstraction that
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Nested SELECT using the EXISTS operator";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "The EXISTS operator is a bit different from all other SQL
|
||||
elements, as it cannot really be applied to any object in a DSL.
|
||||
|
||||
@ -4,21 +4,133 @@
|
||||
// Please do not edit this content manually
|
||||
require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Functions, aggregate operators, and window functions";
|
||||
print "Functions and aggregate operators";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
return "
|
||||
Highly effective SQL cannot do without functions. Operations on
|
||||
VARCHAR, DATE, and NUMERIC types in GROUP BY or ORDER BY clauses allow
|
||||
for very elegant queries.
|
||||
";
|
||||
}
|
||||
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/DSL/">DSL or fluent API. Where SQL meets Java</a> : <a href="<?=$root?>/manual/DSL/FUNCTIONS/">Functions, aggregate operators, and window functions</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/DSL/UNION/" title="Previous section: UNION and other set operations">previous</a> : <a href="<?=$root?>/manual/DSL/PROCEDURES/" title="Next section: Stored procedures and functions">next</a></td>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/DSL/">DSL or fluent API. Where SQL meets Java</a> : <a href="<?=$root?>/manual/DSL/FUNCTIONS/">Functions and aggregate operators</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/DSL/UNION/" title="Previous section: UNION and other set operations">previous</a> : <a href="<?=$root?>/manual/DSL/PROCEDURES/" title="Next section: Stored procedures and functions">next</a></td>
|
||||
</tr>
|
||||
</table><br><table cellpadding="0" cellspacing="0" border="0" width="100%">
|
||||
</table>
|
||||
<h2>jOOQ's strategy for supporting vendor-specific functions</h2>
|
||||
<p>jOOQ allows you to access native functions from your RDBMS. jOOQ
|
||||
follows two strategies: </p>
|
||||
<ul>
|
||||
|
||||
<li>Implement all SQL-92, SQL:1999, SQL:2003, and SQL:2008 standard
|
||||
functions, aggregate operators, and window functions. Standard
|
||||
functions could be
|
||||
<a href="http://oreilly.com/catalog/sqlnut/chapter/ch04.html" title="O'Reilly listing of SQL-92 standard functions and deviations thereof">these functions as listed by O'Reilly</a>. </li>
|
||||
|
||||
<li>Take the most useful of vendor-specific functions and simulate
|
||||
them for other RDBMS, where they may not be supported. An example for
|
||||
this are
|
||||
<a href="http://psoug.org/reference/analytic_functions.html" title="An example listing of Oracle Analytic Functions">Oracle Analytic Functions</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h2>Functions </h2>
|
||||
<p>These are just a few functions in the Field interface, so you get the idea: </p>
|
||||
|
||||
<pre class="prettyprint lang-java">
|
||||
Field<String> rpad(Field<? extends Number> length);
|
||||
Field<String> rpad(int length);
|
||||
Field<String> rpad(Field<? extends Number> length, Field<String> c);
|
||||
Field<String> rpad(int length, char c);
|
||||
Field<String> lpad(Field<? extends Number> length);
|
||||
Field<String> lpad(int length);
|
||||
Field<String> lpad(Field<? extends Number> length, Field<String> c);
|
||||
Field<String> lpad(int length, char c);
|
||||
Field<String> replace(Field<String> search);
|
||||
Field<String> replace(String search);
|
||||
Field<String> replace(Field<String> search, Field<String> replace);
|
||||
Field<String> replace(String search, String replace);
|
||||
Field<Integer> position(String search);
|
||||
Field<Integer> position(Field<String> search);</pre>
|
||||
|
||||
<h2>Aggregate operators</h2>
|
||||
<p>Aggregate operators work just like functions, even if they have a
|
||||
slightly different semantics. Some of them are also placed in the
|
||||
Field interface. Others in the Factory. Here are some examples from
|
||||
Field: </p>
|
||||
|
||||
<pre class="prettyprint lang-java">
|
||||
Field<Integer> count();
|
||||
Field<Integer> countDistinct();
|
||||
Field<T> max();
|
||||
Field<T> min();
|
||||
Field<BigDecimal> sum();
|
||||
Field<BigDecimal> avg();</pre>
|
||||
|
||||
<p>A typical example of how to use an aggregate operator is when
|
||||
generating the next key on insertion of an ID. When you want to
|
||||
achieve something like this </p>
|
||||
|
||||
<table width="100%" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/DSL/">DSL or fluent API. Where SQL meets Java</a> : <a href="<?=$root?>/manual/DSL/FUNCTIONS/">Functions, aggregate operators, and window functions</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/DSL/UNION/" title="Previous section: UNION and other set operations">previous</a> : <a href="<?=$root?>/manual/DSL/PROCEDURES/" title="Next section: Stored procedures and functions">next</a></td>
|
||||
<td width="50%" class="left">
|
||||
<pre class="prettyprint lang-sql">
|
||||
SELECT MAX(ID) + 1 AS next_id
|
||||
FROM T_AUTHOR</pre>
|
||||
</td><td width="50%" class="right">
|
||||
<pre class="prettyprint lang-java">
|
||||
create.select(ID.max().add(1).as("next_id"))
|
||||
.from(T_AUTHOR);</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>See also the section about
|
||||
<a href="<?=$root?>/manual/DSL/ARITHMETIC/" title="jOOQ Manual reference: Arithmetic operations">Arithmetic operations</a>
|
||||
</p>
|
||||
|
||||
<h2>Window functions</h2>
|
||||
<p>Most major RDBMS support the concept of window functions. jOOQ knows
|
||||
of implementations in DB2, Oracle, Postgres, SQL Server, and Sybase
|
||||
SQL Anywhere,
|
||||
and supports most of their specific syntaxes. Window functions can be
|
||||
used for things like calculating a "running total". The following example
|
||||
fetches transactions and the running total for every transaction going
|
||||
back to the beginning of the transaction table (ordered by booked_at)
|
||||
</p>
|
||||
|
||||
<table width="100%" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td width="50%" class="left">
|
||||
<pre class="prettyprint lang-sql">
|
||||
SELECT booked_at, amount,
|
||||
SUM(amount) OVER (PARTITION BY 1
|
||||
ORDER BY booked_at
|
||||
ROWS BETWEEN UNBOUNDED PRECEDING
|
||||
AND CURRENT ROW) AS total
|
||||
FROM transactions</pre>
|
||||
</td><td width="50%" class="right">
|
||||
<pre class="prettyprint lang-java">
|
||||
create.select(BOOKED_AT, AMOUNT,
|
||||
AMOUNT.sumOver().partitionByOne()
|
||||
.orderBy(BOOKED_AT)
|
||||
.rowsBetweenUnboundedPreceding()
|
||||
.andCurrentRow().as("total")
|
||||
.from(TRANSACTIONS);</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<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/DSL/">DSL or fluent API. Where SQL meets Java</a> : <a href="<?=$root?>/manual/DSL/FUNCTIONS/">Functions and aggregate operators</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/DSL/UNION/" title="Previous section: UNION and other set operations">previous</a> : <a href="<?=$root?>/manual/DSL/PROCEDURES/" title="Next section: Stored procedures and functions">next</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Nested SELECT using the IN operator";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "
|
||||
Set equal operations are very common when you want to select multiple
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Other types of nested SELECT";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "Apart from the most common IN and EXISTS clauses that encourage
|
||||
the use of nested selects, SQL knows a few more syntaxes to make use
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Stored procedures and functions";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
}
|
||||
@ -14,11 +17,11 @@ 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/DSL/">DSL or fluent API. Where SQL meets Java</a> : <a href="<?=$root?>/manual/DSL/PROCEDURES/">Stored procedures and functions</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/DSL/FUNCTIONS/" title="Previous section: Functions, aggregate operators, and window functions">previous</a> : <a href="<?=$root?>/manual/DSL/ARITHMETIC/" title="Next section: Arithmetic operations">next</a></td>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/DSL/">DSL or fluent API. Where SQL meets Java</a> : <a href="<?=$root?>/manual/DSL/PROCEDURES/">Stored procedures and functions</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/DSL/FUNCTIONS/" title="Previous section: Functions and aggregate operators">previous</a> : <a href="<?=$root?>/manual/DSL/ARITHMETIC/" title="Next section: Arithmetic operations">next</a></td>
|
||||
</tr>
|
||||
</table><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/DSL/">DSL or fluent API. Where SQL meets Java</a> : <a href="<?=$root?>/manual/DSL/PROCEDURES/">Stored procedures and functions</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/DSL/FUNCTIONS/" title="Previous section: Functions, aggregate operators, and window functions">previous</a> : <a href="<?=$root?>/manual/DSL/ARITHMETIC/" title="Next section: Arithmetic operations">next</a></td>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/DSL/">DSL or fluent API. Where SQL meets Java</a> : <a href="<?=$root?>/manual/DSL/PROCEDURES/">Stored procedures and functions</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/DSL/FUNCTIONS/" title="Previous section: Functions and aggregate operators">previous</a> : <a href="<?=$root?>/manual/DSL/ARITHMETIC/" title="Next section: Arithmetic operations">next</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Complete SELECT syntax";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "
|
||||
A SELECT statement is more than just the R in CRUD. It allows for
|
||||
@ -59,7 +62,7 @@ create.select(TAuthor.FIRST_NAME, TAuthor.LAST_NAME, create.count());</pre>
|
||||
<p>
|
||||
jOOQ will return an "intermediary" type to you, representing the
|
||||
SELECT statement about to be created (by the way, check out the
|
||||
section on <a href="<?=$root?>/manual/DSL/FUNCTIONS/" title="jOOQ Manual reference: Functions, aggregate operators, and window functions">aggregate operators</a>
|
||||
section on <a href="<?=$root?>/manual/DSL/FUNCTIONS/" title="jOOQ Manual reference: Functions and aggregate operators">aggregate operators</a>
|
||||
to learn more about the COUNT(*)
|
||||
function). This type is the
|
||||
<a href="https://github.com/lukaseder/jOOQ/blob/master/jOOQ/src/main/java/org/jooq/SelectFromStep.java" title="Internal API reference: org.jooq.SelectFromStep">org.jooq.SelectFromStep</a>.
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "When it's just much easier: Plain SQL";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@ -6,19 +6,161 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "UNION and other set operations";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "";
|
||||
return "Unions, differences and intersections are vital set operations taken from set theory.";
|
||||
}
|
||||
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/DSL/">DSL or fluent API. Where SQL meets Java</a> : <a href="<?=$root?>/manual/DSL/UNION/">UNION and other set operations</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/DSL/NESTED/" title="Previous section: Other types of nested SELECT">previous</a> : <a href="<?=$root?>/manual/DSL/FUNCTIONS/" title="Next section: Functions, aggregate operators, and window functions">next</a></td>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/DSL/">DSL or fluent API. Where SQL meets Java</a> : <a href="<?=$root?>/manual/DSL/UNION/">UNION and other set operations</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/DSL/NESTED/" title="Previous section: Other types of nested SELECT">previous</a> : <a href="<?=$root?>/manual/DSL/FUNCTIONS/" title="Next section: Functions and aggregate operators">next</a></td>
|
||||
</tr>
|
||||
</table><br><table cellpadding="0" cellspacing="0" border="0" width="100%">
|
||||
</table>
|
||||
<h2>jOOQ's set operation API</h2>
|
||||
<p>The
|
||||
<a href="https://github.com/lukaseder/jOOQ/blob/master/jOOQ/src/main/java/org/jooq/Select.java" title="Internal API reference: org.jooq.Select">org.jooq.Select</a> API directly supports the UNION
|
||||
syntax for all types of Select as discussed in the manual's section about
|
||||
<a href="<?=$root?>/manual/JOOQ/Query/" title="jOOQ Manual reference: The Query and its various subtypes">Queries and Query subtypes</a>.
|
||||
It consists of these methods: </p>
|
||||
|
||||
<pre class="prettyprint lang-java">
|
||||
public interface Select<R extends Record> {
|
||||
Select<R> union(Select<R> select);
|
||||
Select<R> unionAll(Select<R> select);
|
||||
Select<R> except(Select<R> select);
|
||||
Select<R> intersect(Select<R> select);
|
||||
}</pre>
|
||||
|
||||
<p>Hence, this is how you can write a simple UNION with jOOQ:</p>
|
||||
<table width="100%" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td align="left" valign="top"><a href="<?=$root?>/manual/">The jOOQ User Manual</a> : <a href="<?=$root?>/manual/DSL/">DSL or fluent API. Where SQL meets Java</a> : <a href="<?=$root?>/manual/DSL/UNION/">UNION and other set operations</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/DSL/NESTED/" title="Previous section: Other types of nested SELECT">previous</a> : <a href="<?=$root?>/manual/DSL/FUNCTIONS/" title="Next section: Functions, aggregate operators, and window functions">next</a></td>
|
||||
<td width="50%" class="left">
|
||||
<pre class="prettyprint lang-sql">
|
||||
SELECT TITLE
|
||||
FROM T_BOOK
|
||||
WHERE PUBLISHED_IN > 1945
|
||||
UNION
|
||||
SELECT TITLE
|
||||
FROM T_BOOK
|
||||
WHERE AUTHOR_ID = 1</pre>
|
||||
</td><td width="50%" class="right">
|
||||
<pre class="prettyprint lang-java">
|
||||
create.select(TBook.TITLE)
|
||||
.from(T_BOOK)
|
||||
.where(TBook.PUBLISHED_IN.greaterThan(1945))
|
||||
.union(
|
||||
create.select(TBook.TITLE)
|
||||
.from(T_BOOK)
|
||||
.where(TBook.AUTHOR_ID.equal(1)));</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h2>Nested UNIONs</h2>
|
||||
<p>In some SQL dialects, you can arbitrarily nest UNIONs to several
|
||||
levels. Be aware, though, that SQLite, Derby and MySQL have serious
|
||||
syntax limitations. jOOQ tries to render correct UNION SQL statements,
|
||||
but unfortunately, you can create situations that will cause syntax
|
||||
errors in the aforementioned dialects. </p>
|
||||
|
||||
<p>An example of advanced UNION usage is the following statement in jOOQ: </p>
|
||||
<pre class="prettyprint lang-java">
|
||||
// Create a UNION of several types of books
|
||||
Select<?> union =
|
||||
create.select(TBook.TITLE, TBook.AUTHOR_ID).from(T_BOOK).where(TBook.PUBLISHED_IN.greaterThan(1945)).union(
|
||||
create.select(TBook.TITLE, TBook.AUTHOR_ID).from(T_BOOK).where(TBook.AUTHOR_ID.equal(1)));
|
||||
|
||||
// Now, re-use the above UNION and order it by author
|
||||
create.select(union.getField(TBook.TITLE))
|
||||
.from(union)
|
||||
.orderBy(union.getField(TBook.AUTHOR_ID).descending());</pre>
|
||||
|
||||
<p>This example does not seem surprising, when you have read the
|
||||
previous chapters about
|
||||
<a href="<?=$root?>/manual/DSL/NESTED/" title="jOOQ Manual reference: Other types of nested SELECT">nested SELECT statements</a>.
|
||||
But when you check
|
||||
out the rendered SQL: </p>
|
||||
|
||||
<pre class="prettyprint lang-sql">
|
||||
-- alias_38173 is an example of a generated alias,
|
||||
-- generated by jOOQ for union queries
|
||||
SELECT alias_38173.TITLE FROM (
|
||||
SELECT T_BOOK.TITLE, T_BOOK.AUTHOR_ID FROM T_BOOK WHERE T_BOOK.PUBLISHED_IN > 1945
|
||||
UNION
|
||||
SELECT T_BOOK.TITLE, T_BOOK.AUTHOR_ID FROM T_BOOK WHERE T_BOOK.AUTHOR_ID = 1
|
||||
) alias_38173
|
||||
ORDER BY alias_38173.AUTHOR_ID DESC</pre>
|
||||
|
||||
<p>You can see that jOOQ takes care of many syntax pitfalls, when
|
||||
you're not used to the various dialects' unique requirements. The
|
||||
above automatic aliasing was added in order to be compliant with
|
||||
MySQL's requirements about aliasing nested selects. </p>
|
||||
|
||||
<h2>Several UNIONs</h2>
|
||||
<p>It is no problem either for you to create SQL statements with several unions. Just write: </p>
|
||||
<pre class="prettyprint lang-java">
|
||||
Select<?> part1;
|
||||
Select<?> part2;
|
||||
Select<?> part3;
|
||||
Select<?> part4;
|
||||
|
||||
// [...]
|
||||
|
||||
part1.union(part2).union(part3).union(part4);</pre>
|
||||
|
||||
<h2>UNION and the ORDER BY clause</h2>
|
||||
<p>
|
||||
Strictly speaking, in SQL, you cannot order a subselect that is part
|
||||
of a UNION operation. You can only order the whole set. In set theory,
|
||||
or relational algebra, it wouldn't make sense to order subselects
|
||||
anyway, as a set operation cannot guarantee order correctness. Often,
|
||||
you still want to do it, because you apply a LIMIT to every subselect.
|
||||
Let's say, you want to find the employees with the highest salary in
|
||||
every department in Postgres syntax:
|
||||
</p>
|
||||
<table width="100%" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<td width="50%" class="left">
|
||||
<pre class="prettyprint lang-sql">
|
||||
SELECT * FROM (
|
||||
SELECT * FROM emp WHERE dept = 'IT'
|
||||
ORDER BY salary LIMIT 1
|
||||
) UNION (
|
||||
SELECT * FROM emp WHERE dept = 'Marketing'
|
||||
ORDER BY salary LIMIT 1
|
||||
) UNION (
|
||||
SELECT * FROM emp WHERE dept = 'R&D'
|
||||
ORDER BY salary LIMIT 1
|
||||
)</pre>
|
||||
</td><td width="50%" class="right">
|
||||
<pre class="prettyprint lang-java">
|
||||
create.selectFrom(EMP).where(DEPT.equal("IT"))
|
||||
.orderBy(SALARY).limit(1)
|
||||
.union(
|
||||
create.selectFrom(EMP).where(DEPT.equal("Marketing"))
|
||||
.orderBy(SALARY).limit(1))
|
||||
.union(
|
||||
create.selectFrom(EMP).where(DEPT.equal("R&D")
|
||||
.orderBy(SALARY).limit(1)))
|
||||
|
||||
|
||||
</pre>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>There is a subtle difference between the above two queries.
|
||||
In SQL, every UNION subselect is in fact a
|
||||
<a href="<?=$root?>/manual/DSL/NESTED/" title="jOOQ Manual reference: Other types of nested SELECT">nested SELECT</a>, wrapped in parentheses.
|
||||
In this example, the notion of "nested SELECT" and "subselect" are slightly
|
||||
different.</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/DSL/">DSL or fluent API. Where SQL meets Java</a> : <a href="<?=$root?>/manual/DSL/UNION/">UNION and other set operations</a></td><td align="right" valign="top" style="white-space: nowrap"><a href="<?=$root?>/manual/DSL/NESTED/" title="Previous section: Other types of nested SELECT">previous</a> : <a href="<?=$root?>/manual/DSL/FUNCTIONS/" title="Next section: Functions and aggregate operators">next</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../frame.php';
|
||||
function printH1() {
|
||||
print "DSL or fluent API. Where SQL meets Java";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "
|
||||
";
|
||||
@ -75,7 +78,7 @@ create.select()
|
||||
<a href="<?=$root?>/manual/DSL/UNION/" title="UNION and other set operations">UNION and other set operations</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?=$root?>/manual/DSL/FUNCTIONS/" title="Functions, aggregate operators, and window functions">Functions, aggregate operators, and window functions</a>
|
||||
<a href="<?=$root?>/manual/DSL/FUNCTIONS/" title="Functions and aggregate operators">Functions and aggregate operators</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?=$root?>/manual/DSL/PROCEDURES/" title="Stored procedures and functions">Stored procedures and functions</a>
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "The example database";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "
|
||||
For the examples in this manual, the same database will always be
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Extend jOOQ with custom types";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
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
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "The Factory class";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "
|
||||
jOOQ hides most implementation facts from you by letting you
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "The Query and its various subtypes";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "
|
||||
The Query type hierarchy is what you use to execute queries. It has the
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "QueryParts and the global architecture";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "When constructing Query objects in jOOQ, everything is
|
||||
considered a QueryPart. The purpose of this quickly becomes clear when
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Results and Records";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "
|
||||
Results and their Records come into play, when SELECT statements are
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "ResultQuery and various ways of fetching data";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "
|
||||
Various jOOQ query type extend the ResultQuery which provides many means of
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Serializability of QueryParts and Results";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "Most of the jOOQ API implements the Serializable interface.
|
||||
This helps storing queries and partial queries in files, transferring
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Tables and Fields";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "
|
||||
Tables and their Fields are probably the most important objects in
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Updatable Records";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "
|
||||
UpdatableRecords are a specific subtype of TableRecord that have
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../frame.php';
|
||||
function printH1() {
|
||||
print "jOOQ classes and their usage";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "
|
||||
In these sections, you will learn about how to use jOOQ object
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Configuration and setup of the generator";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "jOOQ uses a simple configuration file to configure source code generation.";
|
||||
}
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Procedures and packages";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "
|
||||
Procedure support is one of the most important reasons why you should consider
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "The schema, top-level generated artefact";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
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
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Sequences";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "
|
||||
jOOQ also generates convenience artefacts for sequences, where this is
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "Tables, views and their corresponding records";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "
|
||||
The most important generated artefacts are Tables and TableRecords.
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../../frame.php';
|
||||
function printH1() {
|
||||
print "UDT's including ARRAY and ENUM types";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "
|
||||
Databases become more powerful when you can structure your data in user
|
||||
|
||||
@ -6,6 +6,9 @@ require '../../frame.php';
|
||||
function printH1() {
|
||||
print "Meta model code generation";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "In these sections you will learn about how to configure and use
|
||||
jOOQ's source code generator";
|
||||
|
||||
@ -6,6 +6,9 @@ require '../frame.php';
|
||||
function printH1() {
|
||||
print "The jOOQ User Manual";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "
|
||||
Learn about jOOQ using its single or multi-paged manuals
|
||||
@ -163,7 +166,7 @@ function printContent() {
|
||||
<a href="<?=$root?>/manual/DSL/UNION/" title="UNION and other set operations">UNION and other set operations</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?=$root?>/manual/DSL/FUNCTIONS/" title="Functions, aggregate operators, and window functions">Functions, aggregate operators, and window functions</a>
|
||||
<a href="<?=$root?>/manual/DSL/FUNCTIONS/" title="Functions and aggregate operators">Functions and aggregate operators</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="<?=$root?>/manual/DSL/PROCEDURES/" title="Stored procedures and functions">Stored procedures and functions</a>
|
||||
|
||||
@ -8,6 +8,9 @@ function getSlogan() {
|
||||
in the beginning, jOOQ was no more than type-safe querying for simple statements. See how
|
||||
jOOQ is growing to support almost all SQL constructs by 12 different RDBMS";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "notes";
|
||||
}
|
||||
function printContent() {
|
||||
$contents = file('inc/RELEASENOTES.txt');
|
||||
|
||||
|
||||
@ -24,6 +24,9 @@ function printH1() {
|
||||
<xsl:value-of select="//section[@id = $sectionID]/title"/>
|
||||
<xsl:text disable-output-escaping="yes">";
|
||||
}
|
||||
function getActiveMenu() {
|
||||
return "manual";
|
||||
}
|
||||
function getSlogan() {
|
||||
return "</xsl:text>
|
||||
<xsl:value-of select="//section[@id = $sectionID]/slogan"/>
|
||||
|
||||
@ -2687,11 +2687,235 @@ create.select(TAuthor.ID, books)
|
||||
|
||||
<section id="UNION">
|
||||
<title>UNION and other set operations</title>
|
||||
<slogan>Unions, differences and intersections are vital set operations taken from set theory.</slogan>
|
||||
<content>
|
||||
<h2>jOOQ's set operation API</h2>
|
||||
<p>The
|
||||
<reference class="org.jooq.Select"/> API directly supports the UNION
|
||||
syntax for all types of Select as discussed in the manual's section about
|
||||
<reference id="Query" title="Queries and Query subtypes"/>.
|
||||
It consists of these methods: </p>
|
||||
|
||||
<java>
|
||||
public interface Select<R extends Record> {
|
||||
Select<R> union(Select<R> select);
|
||||
Select<R> unionAll(Select<R> select);
|
||||
Select<R> except(Select<R> select);
|
||||
Select<R> intersect(Select<R> select);
|
||||
}</java>
|
||||
|
||||
<p>Hence, this is how you can write a simple UNION with jOOQ:</p>
|
||||
<code-pair>
|
||||
<sql>
|
||||
SELECT TITLE
|
||||
FROM T_BOOK
|
||||
WHERE PUBLISHED_IN > 1945
|
||||
UNION
|
||||
SELECT TITLE
|
||||
FROM T_BOOK
|
||||
WHERE AUTHOR_ID = 1</sql>
|
||||
<java>
|
||||
create.select(TBook.TITLE)
|
||||
.from(T_BOOK)
|
||||
.where(TBook.PUBLISHED_IN.greaterThan(1945))
|
||||
.union(
|
||||
create.select(TBook.TITLE)
|
||||
.from(T_BOOK)
|
||||
.where(TBook.AUTHOR_ID.equal(1)));</java>
|
||||
</code-pair>
|
||||
|
||||
<h2>Nested UNIONs</h2>
|
||||
<p>In some SQL dialects, you can arbitrarily nest UNIONs to several
|
||||
levels. Be aware, though, that SQLite, Derby and MySQL have serious
|
||||
syntax limitations. jOOQ tries to render correct UNION SQL statements,
|
||||
but unfortunately, you can create situations that will cause syntax
|
||||
errors in the aforementioned dialects. </p>
|
||||
|
||||
<p>An example of advanced UNION usage is the following statement in jOOQ: </p>
|
||||
<java>
|
||||
// Create a UNION of several types of books
|
||||
Select<?> union =
|
||||
create.select(TBook.TITLE, TBook.AUTHOR_ID).from(T_BOOK).where(TBook.PUBLISHED_IN.greaterThan(1945)).union(
|
||||
create.select(TBook.TITLE, TBook.AUTHOR_ID).from(T_BOOK).where(TBook.AUTHOR_ID.equal(1)));
|
||||
|
||||
// Now, re-use the above UNION and order it by author
|
||||
create.select(union.getField(TBook.TITLE))
|
||||
.from(union)
|
||||
.orderBy(union.getField(TBook.AUTHOR_ID).descending());</java>
|
||||
|
||||
<p>This example does not seem surprising, when you have read the
|
||||
previous chapters about
|
||||
<reference id="NESTED" title="nested SELECT statements"/>.
|
||||
But when you check
|
||||
out the rendered SQL: </p>
|
||||
|
||||
<sql>
|
||||
-- alias_38173 is an example of a generated alias,
|
||||
-- generated by jOOQ for union queries
|
||||
SELECT alias_38173.TITLE FROM (
|
||||
SELECT T_BOOK.TITLE, T_BOOK.AUTHOR_ID FROM T_BOOK WHERE T_BOOK.PUBLISHED_IN > 1945
|
||||
UNION
|
||||
SELECT T_BOOK.TITLE, T_BOOK.AUTHOR_ID FROM T_BOOK WHERE T_BOOK.AUTHOR_ID = 1
|
||||
) alias_38173
|
||||
ORDER BY alias_38173.AUTHOR_ID DESC</sql>
|
||||
|
||||
<p>You can see that jOOQ takes care of many syntax pitfalls, when
|
||||
you're not used to the various dialects' unique requirements. The
|
||||
above automatic aliasing was added in order to be compliant with
|
||||
MySQL's requirements about aliasing nested selects. </p>
|
||||
|
||||
<h2>Several UNIONs</h2>
|
||||
<p>It is no problem either for you to create SQL statements with several unions. Just write: </p>
|
||||
<java>
|
||||
Select<?> part1;
|
||||
Select<?> part2;
|
||||
Select<?> part3;
|
||||
Select<?> part4;
|
||||
|
||||
// [...]
|
||||
|
||||
part1.union(part2).union(part3).union(part4);</java>
|
||||
|
||||
<h2>UNION and the ORDER BY clause</h2>
|
||||
<p>
|
||||
Strictly speaking, in SQL, you cannot order a subselect that is part
|
||||
of a UNION operation. You can only order the whole set. In set theory,
|
||||
or relational algebra, it wouldn't make sense to order subselects
|
||||
anyway, as a set operation cannot guarantee order correctness. Often,
|
||||
you still want to do it, because you apply a LIMIT to every subselect.
|
||||
Let's say, you want to find the employees with the highest salary in
|
||||
every department in Postgres syntax:
|
||||
</p>
|
||||
<code-pair>
|
||||
<sql>
|
||||
SELECT * FROM (
|
||||
SELECT * FROM emp WHERE dept = 'IT'
|
||||
ORDER BY salary LIMIT 1
|
||||
) UNION (
|
||||
SELECT * FROM emp WHERE dept = 'Marketing'
|
||||
ORDER BY salary LIMIT 1
|
||||
) UNION (
|
||||
SELECT * FROM emp WHERE dept = 'R&D'
|
||||
ORDER BY salary LIMIT 1
|
||||
)</sql><java>
|
||||
create.selectFrom(EMP).where(DEPT.equal("IT"))
|
||||
.orderBy(SALARY).limit(1)
|
||||
.union(
|
||||
create.selectFrom(EMP).where(DEPT.equal("Marketing"))
|
||||
.orderBy(SALARY).limit(1))
|
||||
.union(
|
||||
create.selectFrom(EMP).where(DEPT.equal("R&D")
|
||||
.orderBy(SALARY).limit(1)))
|
||||
|
||||
|
||||
</java>
|
||||
</code-pair>
|
||||
|
||||
<p>There is a subtle difference between the above two queries.
|
||||
In SQL, every UNION subselect is in fact a
|
||||
<reference id="NESTED" title="nested SELECT"/>, wrapped in parentheses.
|
||||
In this example, the notion of "nested SELECT" and "subselect" are slightly
|
||||
different.</p>
|
||||
</content>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="FUNCTIONS">
|
||||
<title>Functions, aggregate operators, and window functions</title>
|
||||
<title>Functions and aggregate operators</title>
|
||||
<slogan>
|
||||
Highly effective SQL cannot do without functions. Operations on
|
||||
VARCHAR, DATE, and NUMERIC types in GROUP BY or ORDER BY clauses allow
|
||||
for very elegant queries.
|
||||
</slogan>
|
||||
<content>
|
||||
<h2>jOOQ's strategy for supporting vendor-specific functions</h2>
|
||||
<p>jOOQ allows you to access native functions from your RDBMS. jOOQ
|
||||
follows two strategies: </p>
|
||||
<ul>
|
||||
<li>Implement all SQL-92, SQL:1999, SQL:2003, and SQL:2008 standard
|
||||
functions, aggregate operators, and window functions. Standard
|
||||
functions could be
|
||||
<a href="http://oreilly.com/catalog/sqlnut/chapter/ch04.html" title="O'Reilly listing of SQL-92 standard functions and deviations thereof">these functions as listed by O'Reilly</a>. </li>
|
||||
<li>Take the most useful of vendor-specific functions and simulate
|
||||
them for other RDBMS, where they may not be supported. An example for
|
||||
this are
|
||||
<a href="http://psoug.org/reference/analytic_functions.html" title="An example listing of Oracle Analytic Functions">Oracle Analytic Functions</a></li>
|
||||
</ul>
|
||||
|
||||
<h2>Functions </h2>
|
||||
<p>These are just a few functions in the Field interface, so you get the idea: </p>
|
||||
|
||||
<java>
|
||||
Field<String> rpad(Field<? extends Number> length);
|
||||
Field<String> rpad(int length);
|
||||
Field<String> rpad(Field<? extends Number> length, Field<String> c);
|
||||
Field<String> rpad(int length, char c);
|
||||
Field<String> lpad(Field<? extends Number> length);
|
||||
Field<String> lpad(int length);
|
||||
Field<String> lpad(Field<? extends Number> length, Field<String> c);
|
||||
Field<String> lpad(int length, char c);
|
||||
Field<String> replace(Field<String> search);
|
||||
Field<String> replace(String search);
|
||||
Field<String> replace(Field<String> search, Field<String> replace);
|
||||
Field<String> replace(String search, String replace);
|
||||
Field<Integer> position(String search);
|
||||
Field<Integer> position(Field<String> search);</java>
|
||||
|
||||
<h2>Aggregate operators</h2>
|
||||
<p>Aggregate operators work just like functions, even if they have a
|
||||
slightly different semantics. Some of them are also placed in the
|
||||
Field interface. Others in the Factory. Here are some examples from
|
||||
Field: </p>
|
||||
|
||||
<java>
|
||||
Field<Integer> count();
|
||||
Field<Integer> countDistinct();
|
||||
Field<T> max();
|
||||
Field<T> min();
|
||||
Field<BigDecimal> sum();
|
||||
Field<BigDecimal> avg();</java>
|
||||
|
||||
<p>A typical example of how to use an aggregate operator is when
|
||||
generating the next key on insertion of an ID. When you want to
|
||||
achieve something like this </p>
|
||||
|
||||
<code-pair>
|
||||
<sql>
|
||||
SELECT MAX(ID) + 1 AS next_id
|
||||
FROM T_AUTHOR</sql><java>
|
||||
create.select(ID.max().add(1).as("next_id"))
|
||||
.from(T_AUTHOR);</java>
|
||||
</code-pair>
|
||||
|
||||
<p>See also the section about
|
||||
<reference id="ARITHMETIC" title="Arithmetic operations"/></p>
|
||||
|
||||
<h2>Window functions</h2>
|
||||
<p>Most major RDBMS support the concept of window functions. jOOQ knows
|
||||
of implementations in DB2, Oracle, Postgres, SQL Server, and Sybase
|
||||
SQL Anywhere,
|
||||
and supports most of their specific syntaxes. Window functions can be
|
||||
used for things like calculating a "running total". The following example
|
||||
fetches transactions and the running total for every transaction going
|
||||
back to the beginning of the transaction table (ordered by booked_at)
|
||||
</p>
|
||||
|
||||
<code-pair>
|
||||
<sql>
|
||||
SELECT booked_at, amount,
|
||||
SUM(amount) OVER (PARTITION BY 1
|
||||
ORDER BY booked_at
|
||||
ROWS BETWEEN UNBOUNDED PRECEDING
|
||||
AND CURRENT ROW) AS total
|
||||
FROM transactions</sql><java>
|
||||
create.select(BOOKED_AT, AMOUNT,
|
||||
AMOUNT.sumOver().partitionByOne()
|
||||
.orderBy(BOOKED_AT)
|
||||
.rowsBetweenUnboundedPreceding()
|
||||
.andCurrentRow().as("total")
|
||||
.from(TRANSACTIONS);</java>
|
||||
</code-pair>
|
||||
</content>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user