blob: e0f1cfd43c6c642a79fbe362479e08c4af6ac975 [file] [log] [blame]
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- No caching headers -->
<meta http-equiv="cache-control" content="no-cache"/>
<meta http-equiv="pragma" content="no-cache"/>
<meta http-equiv="expires" content="-1"/>
<meta name="keywords" content="JDO, Apache, Java, Data, Objects"/>
<meta name="description" content="Apache JDO - Java Data Objects"/>
<title>JDOQL Typed</title>
<link rel="icon" type="image/png" href="images/JDOx150.png"/>
<!--
Apache JDO Documentation Template
==================================
This template derived various aspects from Apache Deltaspike template, the Apache ISIS template and the Datanucleus template.
This template uses
* Bootstrap v3.3.7 (https://getbootstrap.com/) for navbar.
* Asciidoctor "foundation" CSS
* Bootswatch "cosmo" theme for Bootstrap (https://bootswatch.com/cosmo).
* Bootstrap TOC plugin v0.4.1 (https://afeld.github.io/bootstrap-toc/) for the table of contents.
* jQuery (necessary for Bootstrap's JavaScript plugins)
* Font-Awesome for some icons used by Asciidoctor
NOTE: tried using Font-Awesome CSS hosted locally but then fails to work!
-->
<link href="css/bootswatch/3.3.7/bootstrap-cosmo.css" rel="stylesheet"/>
<link href="css/bootstrap-toc/0.4.1/bootstrap-toc.min.css" rel="stylesheet"/>
<link href="css/asciidoctor/foundation.css" rel="stylesheet"/>
<link href="css/datanucleus_theme.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.3.0/css/font-awesome.min.css" rel="stylesheet">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="js/bootstrap/3.3.7/bootstrap.min.js"></script>
<script src="js/bootstrap-toc/0.4.1/bootstrap-toc.min.js"></script>
<!-- Coderay syntax formatter -->
<style type="text/css">
/* Stylesheet for CodeRay to match GitHub theme | MIT License | http://foundation.zurb.com */
pre.CodeRay{background:#f7f7f8}
.CodeRay .line-numbers{border-right:1px solid currentColor;opacity:.35;padding:0 .5em 0 0}
.CodeRay span.line-numbers{display:inline-block;margin-right:.75em}
.CodeRay .line-numbers strong{color:#000}
table.CodeRay{border-collapse:separate;border:0;margin-bottom:0;background:none}
table.CodeRay td{vertical-align:top;line-height:inherit}
table.CodeRay td.line-numbers{text-align:right}
table.CodeRay td.code{padding:0 0 0 .75em}
.CodeRay .debug{color:#fff !important;background:#000080 !important}
.CodeRay .annotation{color:#007}
.CodeRay .attribute-name{color:#000080}
.CodeRay .attribute-value{color:#700}
.CodeRay .binary{color:#509}
.CodeRay .comment{color:#998;font-style:italic}
.CodeRay .char{color:#04d}
.CodeRay .char .content{color:#04d}
.CodeRay .char .delimiter{color:#039}
.CodeRay .class{color:#458;font-weight:bold}
.CodeRay .complex{color:#a08}
.CodeRay .constant,.CodeRay .predefined-constant{color:#008080}
.CodeRay .color{color:#099}
.CodeRay .class-variable{color:#369}
.CodeRay .decorator{color:#b0b}
.CodeRay .definition{color:#099}
.CodeRay .delimiter{color:#000}
.CodeRay .doc{color:#970}
.CodeRay .doctype{color:#34b}
.CodeRay .doc-string{color:#d42}
.CodeRay .escape{color:#666}
.CodeRay .entity{color:#800}
.CodeRay .error{color:#808}
.CodeRay .exception{color:inherit}
.CodeRay .filename{color:#099}
.CodeRay .function{color:#900;font-weight:bold}
.CodeRay .global-variable{color:#008080}
.CodeRay .hex{color:#058}
.CodeRay .integer,.CodeRay .float{color:#099}
.CodeRay .include{color:#555}
.CodeRay .inline{color:#000}
.CodeRay .inline .inline{background:#ccc}
.CodeRay .inline .inline .inline{background:#bbb}
.CodeRay .inline .inline-delimiter{color:#d14}
.CodeRay .inline-delimiter{color:#d14}
.CodeRay .important{color:#555;font-weight:bold}
.CodeRay .interpreted{color:#b2b}
.CodeRay .instance-variable{color:#008080}
.CodeRay .label{color:#970}
.CodeRay .local-variable{color:#963}
.CodeRay .octal{color:#40e}
.CodeRay .predefined{color:#369}
.CodeRay .preprocessor{color:#579}
.CodeRay .pseudo-class{color:#555}
.CodeRay .directive{font-weight:bold}
.CodeRay .type{font-weight:bold}
.CodeRay .predefined-type{color:inherit}
.CodeRay .reserved,.CodeRay .keyword {color:#000;font-weight:bold}
.CodeRay .key{color:#808}
.CodeRay .key .delimiter{color:#606}
.CodeRay .key .char{color:#80f}
.CodeRay .value{color:#088}
.CodeRay .regexp .delimiter{color:#808}
.CodeRay .regexp .content{color:#808}
.CodeRay .regexp .modifier{color:#808}
.CodeRay .regexp .char{color:#d14}
.CodeRay .regexp .function{color:#404;font-weight:bold}
.CodeRay .string{color:#d20}
.CodeRay .string .string .string{background:#ffd0d0}
.CodeRay .string .content{color:#d14}
.CodeRay .string .char{color:#d14}
.CodeRay .string .delimiter{color:#d14}
.CodeRay .shell{color:#d14}
.CodeRay .shell .delimiter{color:#d14}
.CodeRay .symbol{color:#990073}
.CodeRay .symbol .content{color:#a60}
.CodeRay .symbol .delimiter{color:#630}
.CodeRay .tag{color:#008080}
.CodeRay .tag-special{color:#d70}
.CodeRay .variable{color:#036}
.CodeRay .insert{background:#afa}
.CodeRay .delete{background:#faa}
.CodeRay .change{color:#aaf;background:#007}
.CodeRay .head{color:#f8f;background:#505}
.CodeRay .insert .insert{color:#080}
.CodeRay .delete .delete{color:#800}
.CodeRay .change .change{color:#66f}
.CodeRay .head .head{color:#f4f}
</style>
</head>
<body data-spy="scroll" data-target="#toc">
<!-- Navbar -->
<nav class="navbar navbar-default navbar-static-top">
<div class="container">
<div class="navbar-header">
<!-- Three line menu button for use on mobile screens -->
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<!-- 'style' added to align image with navbar. FIX THIS -->
<a class="navbar-brand" href="https://db.apache.org/jdo/">
<img style="margin-top: -12px;" alt="Brand" width="45.5" height="45.5" src="images/JDOx150.png"/>
</a>
<!-- TODO Any way to abstract the version from Maven? -->
<a class="navbar-brand" href="index.html">Apache JDO</a>
</div>
<!-- Navbar that will collapse on mobile screens -->
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="dropdown">
<!-- menu item General -->
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">General<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="why_jdo.html">Why JDO?</a></li>
<li><a href="getting-started.html">Getting Started</a></li>
<li><a href="specifications.html">Specifications</a></li>
<li><a href="tck.html">TCK</a></li>
<li><a href="javadoc.html">API Javadoc</a></li>
<li role="separator" class="divider"></li>
<li><a href="jdo_v_jpa.html">JDO v JPA</a></li>
<li><a href="jdo_v_jpa_api.html">JDO v JPA : API</a></li>
<li><a href="jdo_v_jpa_orm.html">JDO v JPA : ORM</a></li>
<li role="separator" class="divider"></li>
<li><a href="license.html">License</a></li>
<li><a href="impls.html">Implementations</a></li>
<li><a href="jdo_3_0_overview.html">JDO 3.0 Overview</a></li>
<li><a href="references.html">References</a></li>
<li><a href="glossary.html">Glossary</a></li>
</ul>
</li>
<!-- menu item API Usage -->
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">API Usage<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="pmf.html">PersistenceManagerFactory</a></li>
<li><a href="pm.html">PersistenceManager</a></li>
<li><a href="transactions.html">Transactions</a></li>
<li><a href="attach_detach.html">Attach-Detach</a></li>
<li><a href="fetchgroups.html">Fetch Plan/Groups</a></li>
<li><a href="state_transition.html">Object States</a></li>
<li><a href="object_retrieval.html">Object Retrieval</a></li>
<li><a href="exceptions.html">Exceptions</a></li>
<li><a href="jdohelper.html">JDO Helper</a></li>
<li role="separator" class="divider"></li>
<li><a href="guides-replication.html">Data Replication</a></li>
</ul>
</li>
<!-- menu item Types & Metadata -->
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Types &amp; Metadata<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="class_types.html">Types of Classes</a></li>
<li><a href="field_types.html">Types of Fields</a></li>
<li role="separator" class="divider"></li>
<!-- <li class="dropdown-header">Metadata</li> -->
<li><a href="metadata.html">MetaData</a></li>
<li><a href="annotations.html">Annotations</a></li>
<li><a href="jdo_dtd.html">jdo DTD/XSD</a></li>
<li><a href="orm_dtd.html">orm DTD/XSD</a></li>
<li><a href="jdoquery_dtd.html">jdoquery DTD/XSD</a></li>
<li><a href="jdoconfig_dtd.html">jdoconfig DTD/XSD</a></li>
<li role="separator" class="divider"></li>
<li><a href="enhancement.html">Bytecode Enhancement</a></li>
</ul>
</li>
<!-- menu item Query -->
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false" style="background-color:#2385c6">Query<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="query_api.html">Query API</a></li>
<li role="separator" class="divider"></li>
<li><a href="jdoql.html">JDOQL</a></li>
<li><a href="jdoql_methods.html">Methods</a></li>
<li><a href="jdoql_result.html">Result</a></li>
<li><a href="jdoql_quickref.pdf">Quick Ref PDF</a></li>
<li><a href="jdoql_typed.html">JDOQL Typed API</a></li>
<li role="separator" class="divider"></li>
<li><a href="query_sql.html">SQL</a></li>
</ul>
</li>
<!-- menu item Community -->
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Community<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="get-involved.html">Get Involved</a></li>
<li><a href="team-list.html">Project Team</a></li>
<li><a href="mail-lists.html">Mailing Lists</a></li>
<li><a href="faq.html">FAQ</a></li>
</ul>
</li>
<!-- menu item Development -->
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Development<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="roadmap.html">RoadMap / TODO</a></li>
<li><a href="downloads.html">Downloads</a></li>
<li><a href="source-code.html">Source Code</a></li>
<li><a href="coding-standards.html">Coding Standards</a></li>
<li><a href="issuetracking.html">Issue Tracking</a></li>
</ul>
</li>
</ul>
<!-- 'style' added to fix height of input box. FIX THIS -->
<form class="navbar-form navbar-left" role="search" id="search-form" action="https://www.google.com/search" method="get" style="padding: 1px 15px;">
<div class="form-group">
<input name="sitesearch" value="db.apache.org/jdo" type="hidden">
<input name="q" type="text" class="form-control" placeholder="Search" style="margin-top: 7px; padding: 1px; border-radius: 5px; height: 30px; vertical-align: middle;">
</div>
</form>
</div>
</div>
</nav>
<div class="container">
<div class="row-fluid">
<div class="col-sm-9">
<!-- <div class="page-title">
<h3>JDOQL Typed</h3>
</div>
-->
<div id="doc-content">
<div class="sect1">
<h2 id="JDOQLTyped">JDOQL Typed API</h2>
<div class="sectionbody">
<div class="paragraph">
<p>JDO 3.2 introduces a way of performing queries using a JDOQLTypedQuery API, that copes with refactoring of classes/fields.
The API follows the same <a href="jdoql.html">JDOQL</a> syntax that we have seen earlier in terms of the components of the query etc.
It produces queries that are much more elegant and simpler than the equivalent "Criteria" API in JPA.</p>
</div>
<div class="sect2">
<h3 id="_preparation">Preparation</h3>
<div class="paragraph">
<p>To set up your environment to use this JDOQLTypedQuery API you need to enable annotation processing, place your JDO 3.2 provider jars in your build path,
and specify a <code>@PersistenceCapable</code> annotation on your classes to be used in queries (you can still provide the remaining information in XML metadata if you wish to).
This annotation processor will (just before compile of your persistable classes), create a query metamodel "Q" class for each persistable class.
This is similar step to what QueryDSL requires, or indeed the JPA Criteria static metamodel.</p>
</div>
<div class="sect3">
<h4 id="_using_maven">Using Maven</h4>
<div class="paragraph">
<p>For example, using the JDO 3.2 RI, with Maven you need to have the following in your POM</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="xml"><span class="tag">&lt;dependencies&gt;</span>
<span class="tag">&lt;dependency&gt;</span>
<span class="tag">&lt;groupId&gt;</span>org.datanucleus<span class="tag">&lt;/groupId&gt;</span>
<span class="tag">&lt;artifactId&gt;</span>datanucleus-jdo-query<span class="tag">&lt;/artifactId&gt;</span>
<span class="tag">&lt;version&gt;</span>5.0.9<span class="tag">&lt;/version&gt;</span>
<span class="tag">&lt;/dependency&gt;</span>
<span class="tag">&lt;dependency&gt;</span>
<span class="tag">&lt;groupId&gt;</span>javax.jdo<span class="tag">&lt;/groupId&gt;</span>
<span class="tag">&lt;artifactId&gt;</span>jdo-api<span class="tag">&lt;/artifactId&gt;</span>
<span class="tag">&lt;version&gt;</span>3.2<span class="tag">&lt;/version&gt;</span>
<span class="tag">&lt;/dependency&gt;</span>
...
<span class="tag">&lt;/dependencies&gt;</span></code></pre>
</div>
</div>
<div class="paragraph">
<p>This creates the "metamodel" Q classes under <em>target/generated-sources/annotations/</em>.
You can change this location using the configuration property <strong>generatedSourcesDirectory</strong> of the <em>maven-compiler-plugin</em>.</p>
</div>
</div>
<div class="sect3">
<h4 id="_using_eclipse">Using Eclipse</h4>
<div class="paragraph">
<p>With Eclipse you need to</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Go to <em>Java Compiler</em> and make sure the compiler compliance level is 1.8 or above</p>
</li>
<li>
<p>Go to <em>Java Compiler &#8594; Annotation Processing</em> and enable the project specific settings and enable annotation processing</p>
</li>
<li>
<p>Go to <em>Java Compiler &#8594; Annotation Processing &#8594; Factory Path</em>, enable the project specific settings and then add the following jars to the list:
<code>datanucleus-jdo-query.jar</code>, <code>jdo-api.jar</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>This creates the "metamodel" Q classes under <em>target/generated-sources/annotations/</em>.
You can change this location on the <em>Java Compiler &#8594; Annotation Processing</em> page.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="classes">Query Classes</h3>
<div class="paragraph">
<p>The above preparation will mean that whenever you compile, the DataNucleus annotation processor (in <code>datanucleus-jdo-query.jar</code>) will generate a <strong>query class</strong>
for each model class that is annotated as persistable. So what is a <strong>query class</strong> you ask.
It is simply a mechanism for providing an intuitive API to generating queries. If we have the following model class</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="annotation">@PersistenceCapable</span>
<span class="directive">public</span> <span class="type">class</span> <span class="class">Product</span>
{
<span class="annotation">@PrimaryKey</span>
<span class="type">long</span> id;
<span class="predefined-type">String</span> name;
<span class="type">double</span> value;
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>then the (generated) <strong>query class</strong> for this will be</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java"><span class="directive">public</span> <span class="type">class</span> <span class="class">QProduct</span> <span class="directive">extends</span> org.datanucleus.api.jdo.query.PersistableExpressionImpl&lt;Product&gt;
<span class="directive">implements</span> PersistableExpression&lt;Product&gt;
{
<span class="directive">public</span> <span class="directive">static</span> QProduct candidate(<span class="predefined-type">String</span> name) {...}
<span class="directive">public</span> <span class="directive">static</span> QProduct candidate() {...}
<span class="directive">public</span> <span class="directive">static</span> QProduct variable(<span class="predefined-type">String</span> name) {...}
<span class="directive">public</span> <span class="directive">static</span> QProduct parameter(<span class="predefined-type">String</span> name) {...}
<span class="directive">public</span> NumericExpression&lt;<span class="predefined-type">Long</span>&gt; id;
<span class="directive">public</span> StringExpression name;
<span class="directive">public</span> NumericExpression&lt;<span class="predefined-type">Double</span>&gt; value;
...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The generated class has the name of form <em>*Q*{className}</em>.
Also the generated class, by default, has a public field for each persistable field/property and is of a type <em>XXXExpression</em>.
These expressions allow us to give Java like syntax when defining your queries (see below).
So you access your persistable members in a query as <strong>candidate.name</strong> for example.</p>
</div>
<div class="paragraph">
<p>As mentioned above this is the default style of query class. However you can also create it in <em>property</em> style,
where you access your persistable members as <strong>candidate.name()</strong> for example.
The benefit of this approach is that if you have 1-1, N-1 relationship fields then it only initialises the members when called, whereas in the <em>field</em>
case above it has to initialise all in the constructor, so at static initialisation.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The JDOQL Typed query mechanism only works for classes that are annotated, and not for classes that use XML metadata.
This is due to the fact that it makes use of a Java <em>annotation processor</em>.
</td>
</tr>
</table>
</div>
<div class="sect3">
<h4 id="_limitations">Limitations</h4>
<div class="paragraph">
<p>There are some corner cases where the use of expressions and this API may require casting to allow the full range of operations for JDOQL. Some examples</p>
</div>
<div class="ulist">
<ul>
<li>
<p>If you have a List field and call <code>ListExpression.get(position)</code> this returns an <code>Expression</code> rather than a specific <code>NumericExpression</code>, <code>StringExpression</code>, or whatever subtype.
You would need to cast the result to do subsequent calls.</p>
</li>
<li>
<p>If you have a Map field and call <code>MapExpression.get(key)</code> this returns an <code>Expression</code> rather than a specific <code>NumericExpression</code>, <code>StringExpression</code>, or whatever subtype.
You would need to cast the result to do subsequent calls.</p>
</li>
<li>
<p>If you have a Collection parameter and call <code>CollectionParameter.contains(fieldExpression)</code> then you may need to cast the <code>fieldExpression</code> to <code>Expression</code>
since the <code>CollectionParameter</code> will not have adequate java generic information for the compiler to do it automatically</p>
</li>
<li>
<p>If you have a Map parameter and call <code>MapParameter.contains(fieldExpression)</code> then you may need to cast the <code>fieldExpression</code> to <code>Expression</code>
since the <code>MapParameter</code> will not have adequate java generic information for the compiler to do it automatically</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="filter">Filtering</h3>
<div class="paragraph">
<p>Let&#8217;s provide a sample usage of this query API.
We want to construct a query for all products with a value below a certain level, and where the name starts with "Wal".
So a typical query in a JDO-enabled application</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">pm = pmf.getPersistenceManager();
JDOQLTypedQuery&lt;Product&gt; tq = pm.newJDOQLTypedQuery(Product.class);
QProduct cand = QProduct.candidate();
<span class="predefined-type">List</span>&lt;Product&gt; results = tq.filter(cand.value.lt(<span class="float">40.00</span>).and(cand.name.startsWith(<span class="string"><span class="delimiter">&quot;</span><span class="content">Wal</span><span class="delimiter">&quot;</span></span>)))
.executeList();</code></pre>
</div>
</div>
<div class="paragraph">
<p>This equates to the single-string query</p>
</div>
<div class="listingblock">
<div class="content">
<pre>SELECT FROM mydomain.Product WHERE this.value &lt; 40.0 &amp;&amp; this.name.startsWith("Wal")</pre>
</div>
</div>
<div class="paragraph">
<p>As you see, we create a parametrised query, and then make use of the <strong>query class</strong> to access the candidate,
and from that make use of its fields, and the various Java methods present for the types of those fields.
Note that the API is <em>fluent</em>, meaning you can chain calls easily.</p>
</div>
</div>
<div class="sect2">
<h3 id="order">Ordering</h3>
<div class="paragraph">
<p>We want to order the results of the previous query by the product name, putting nulls first.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">tq.orderBy(cand.name.asc().nullsFirst());</code></pre>
</div>
</div>
<div class="paragraph">
<p>This query now equates to the single-string query</p>
</div>
<div class="listingblock">
<div class="content">
<pre>SELECT FROM mydomain.Product WHERE this.value &lt; 40.0 &amp;&amp; this.name.startsWith("Wal") ORDER BY this.name ASCENDING NULLS FIRST</pre>
</div>
</div>
<div class="paragraph">
<p>If you don&#8217;t want to specify null positioning, simply omit the <code>nullsFirst()</code> call. Similarly to put nulls last then call <code>nullsLast()</code>.</p>
</div>
</div>
<div class="sect2">
<h3 id="methods">Methods</h3>
<div class="paragraph">
<p>In the above example you will have seen the use of some of the normal JDOQL methods. With the JDOQLTyped API these are available on the different types of expressions.
For example, <em>cand.name</em> is a <code>StringExpression</code> and consequently it has all of the normal String methods available, just like in JDOQL and just like in Java.
Similarly if we had a class <code>Inventory</code> which had a Collection of <code>Product</code>, then we could use the method <strong>contains</strong> on the <code>CollectionExpression</code>.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The JDOQL methods <em>JDOHelper.getObjectId</em> and <em>JDOHelper.getVersion</em> are available on <code>PersistableExpression</code>, for the object that they would be invoked on.
</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The JDOQL methods <em>Math.{xxx}</em> are available on <code>NumericExpression</code>, for the numeric that they would be invoked on.
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="result">Results</h3>
<div class="paragraph">
<p>Let&#8217;s take the query in the above example and return the name and value of the Products only</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">JDOQLTypedQuery&lt;Product&gt; tq = pm.newJDOQLTypedQuery(Product.class);
QProduct cand = QProduct.candidate();
<span class="predefined-type">List</span>&lt;<span class="predefined-type">Object</span><span class="type">[]</span>&gt; results = tq.filter(cand.value.lt(<span class="float">40.00</span>).and(cand.name.startsWith(<span class="string"><span class="delimiter">&quot;</span><span class="content">Wal</span><span class="delimiter">&quot;</span></span>))).orderBy(cand.name.asc())
.result(<span class="predefined-constant">false</span>, cand.name, cand.value).executeResultList();</code></pre>
</div>
</div>
<div class="paragraph">
<p>This equates to the single-string query</p>
</div>
<div class="listingblock">
<div class="content">
<pre>SELECT this.name,this.value FROM mydomain.Product WHERE this.value &lt; 40.0 &amp;&amp; this.name.startsWith("Wal") ORDER BY this.name ASCENDING</pre>
</div>
</div>
<div class="paragraph">
<p>A further example using aggregates</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">JDOQLTypedQuery&lt;Product&gt; tq = pm.newJDOQLTypedQuery(Product.class);
<span class="predefined-type">Object</span> results =
tq.result(<span class="predefined-constant">false</span>, QProduct.candidate().value.max(), QProduct.candidate().value.min()).executeResultUnique();</code></pre>
</div>
</div>
<div class="paragraph">
<p>This equates to the single-string query</p>
</div>
<div class="listingblock">
<div class="content">
<pre>SELECT max(this.value), min(this.value) FROM mydomain.Product</pre>
</div>
</div>
<div class="paragraph">
<p>If you wanted to assign an alias to a result component you do it like this</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">tq.result(<span class="predefined-constant">false</span>, cand.name.as(<span class="string"><span class="delimiter">&quot;</span><span class="content">THENAME</span><span class="delimiter">&quot;</span></span>), cand.value.as(<span class="string"><span class="delimiter">&quot;</span><span class="content">THEVALUE</span><span class="delimiter">&quot;</span></span>));</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="parameters">Parameters</h3>
<div class="paragraph">
<p>It is important to note that JDOQLTypedQuery only accepts <strong>named</strong> parameters.
You obtain a named parameter from the JDOQLTypedQuery, and then use it in the specification of the filter, ordering, grouping etc.
Let&#8217;s take the query in the above example and specify the "Wal" in a parameter.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">JDOQLTypedQuery&lt;Product&gt; tq = pm.newJDOQLTypedQuery(Product.class);
QProduct cand = QProduct.candidate();
<span class="predefined-type">List</span>&lt;Product&gt; results =
tq.filter(cand.value.lt(<span class="float">40.00</span>).and(cand.name.startsWith(tq.stringParameter(<span class="string"><span class="delimiter">&quot;</span><span class="content">prefix</span><span class="delimiter">&quot;</span></span>))))
.orderBy(cand.name.asc())
.setParameter(<span class="string"><span class="delimiter">&quot;</span><span class="content">prefix</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">Wal</span><span class="delimiter">&quot;</span></span>).executeList();</code></pre>
</div>
</div>
<div class="paragraph">
<p>This equates to the single-string query</p>
</div>
<div class="listingblock">
<div class="content">
<pre>SELECT FROM mydomain.Product WHERE this.value &lt; 40.0 &amp;&amp; this.name.startsWith(:prefix) ORDER BY this.name ASCENDING</pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="variables">Variables</h3>
<div class="paragraph">
<p>Let&#8217;s try to find all Inventory objects containing a Product with a particular name.
This means we need to use a variable. Just like with a parameter, we obtain a <em>variable</em> from the Q class.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">JDOQLTypedQuery&lt;Inventory&gt; tq = pm.newJDOQLTypedQuery(Inventory.class);
QProduct <span class="type">var</span> = QProduct.variable(<span class="string"><span class="delimiter">&quot;</span><span class="content">var</span><span class="delimiter">&quot;</span></span>);
QInventory cand = QInventory.candidate();
<span class="predefined-type">List</span>&lt;Inventory&gt; results = tq.filter(cand.products.contains(<span class="type">var</span>).and(<span class="type">var</span>.name.startsWith(<span class="string"><span class="delimiter">&quot;</span><span class="content">Wal</span><span class="delimiter">&quot;</span></span>))).executeList();</code></pre>
</div>
</div>
<div class="paragraph">
<p>This equates to the single-string query</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">SELECT FROM mydomain.Inventory WHERE <span class="local-variable">this</span>.products.contains(<span class="type">var</span>) &amp;&amp; <span class="type">var</span>.name.startsWith(<span class="string"><span class="delimiter">&quot;</span><span class="content">Wal</span><span class="delimiter">&quot;</span></span>)</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="ifthenelse">If-Then-Else</h3>
<div class="paragraph">
<p>Let&#8217;s make use of an IF-THEN-ELSE expression to return the products based on whether they are "domestic" or "international" (in our case its just based on the "id")</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">JDOQLTypedQuery&lt;Product&gt; tq = pm.newJDOQLTypedQuery(Product.class);
QProduct cand = QProduct.candidate();
IfThenElseExpression&lt;<span class="predefined-type">String</span>&gt; ifElseExpr = tq.ifThenElse(<span class="predefined-type">String</span>.class, cand.id.lt(<span class="integer">1000</span>), <span class="string"><span class="delimiter">&quot;</span><span class="content">Domestic</span><span class="delimiter">&quot;</span></span>, <span class="string"><span class="delimiter">&quot;</span><span class="content">International</span><span class="delimiter">&quot;</span></span>);
tq.result(<span class="predefined-constant">false</span>, ifElseExpr);
<span class="predefined-type">List</span>&lt;<span class="predefined-type">String</span>&gt; results = tq.executeResultList();</code></pre>
</div>
</div>
<div class="paragraph">
<p>This equates to the single-string query</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">SELECT IF (<span class="local-variable">this</span>.id &lt; <span class="integer">1000</span>) <span class="string"><span class="delimiter">&quot;</span><span class="content">Domestic</span><span class="delimiter">&quot;</span></span> ELSE <span class="string"><span class="delimiter">&quot;</span><span class="content">International</span><span class="delimiter">&quot;</span></span> FROM mydomain.Product</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="subquery">Subqueries</h3>
<div class="paragraph">
<p>Let&#8217;s try to find all Products that have a value below the average of all Products. This means we need to use a subquery</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">JDOQLTypedQuery&lt;Product&gt; tq = pm.newJDOQLTypedQuery(Product.class);
QProduct cand = QProduct.candidate();
TypesafeSubquery&lt;Product&gt; tqsub = tq.subquery(Product.class, <span class="string"><span class="delimiter">&quot;</span><span class="content">p</span><span class="delimiter">&quot;</span></span>);
QProduct candsub = QProduct.candidate(<span class="string"><span class="delimiter">&quot;</span><span class="content">p</span><span class="delimiter">&quot;</span></span>);
<span class="predefined-type">List</span>&lt;Product&gt; results = tq.filter(cand.value.lt(tqsub.selectUnique(candsub.value.avg()))).executeList();</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that where we want to refer to the candidate of the subquery, we specify the alias ("p") explicitly.
This equates to the single-string query</p>
</div>
<div class="listingblock">
<div class="content">
<pre>SELECT FROM mydomain.Product WHERE this.value &lt; (SELECT AVG(p.value) FROM mydomain.Product p)</pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
When you are using a subquery and want to refer to the candidate (or field thereof) of the outer query in the subquery
then you would use <code>cand</code> in the above example (or a field of it as required).
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="candidates">Candidates</h3>
<div class="paragraph">
<p>If you don&#8217;t want to query instances in the datastore but instead query a collection of candidate instances, you can do this by setting the candidates, like this</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="CodeRay highlight"><code data-lang="java">JDOQLTypedQuery&lt;Product&gt; tq = pm.newJDOQLTypedQuery(Product.class);
QProduct cand = QProduct.candidate();
<span class="predefined-type">List</span>&lt;Product&gt; results = tq.filter(cand.value.lt(<span class="float">40.00</span>)).setCandidates(myCandidates).executeList();</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-sm-3">
<nav id="toc" data-spy="affix" data-toggle="toc"></nav>
</div>
</div>
</div>
<footer style="color:#fff; background-color:#222222; padding: 5px;">
<div class="container">
<div class="row" style="margin-top:25px">
<div class="col-sm" align="center">
<a href="https://www.facebook.com/JavaDataObjects" class="externalLink" title="Facebook">Facebook</a>
|
<a href="https://twitter.com/JavaDataObjects" class="externalLink" title="Twitter">Twitter</a>
|
<a href="http://wiki.apache.org/jdo" class="externalLink" title="Wiki">Wiki</a>
|
<a href="http://issues.apache.org/jira/secure/BrowseProject.jspa?id=10630" class="externalLink" title="Issue Tracker">Issue Tracker</a>
|
<a href="mail-lists.html" title="Mailing Lists">Mailing Lists</a>
|
<a href="api31/apidocs/index.html" title="Latest Javadocs">Latest Javadocs</a>
|
<a href="https://privacy.apache.org/policies/privacy-policy-public.html" title="Privacy Policy">Privacy Policy</a>
</div>
</div>
<p class="text-center" style="margin-top:16px">&copy; 2005-2022 Apache Software Foundation. All Rights Reserved.</p>
</div>
</footer>
</body>
</html>