| <!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>Query API</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 & 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>Query API</h3> |
| </div> |
| --> |
| <div id="doc-content"> |
| <div class="sect1"> |
| <h2 id="Query_API">Query API</h2> |
| <div class="sectionbody"> |
| <div class="paragraph"> |
| <p>To understand the JDO Query |
| <span class="image"><a class="image" href="api32/apidocs/javax/jdo/Query.html"><img src="../images/javadoc.png" alt="Javadoc"></a></span> API we firstly need to look at a typical Query.</p> |
| </div> |
| <div class="paragraph"> |
| <p>Let’s create a JDOQL string-based query to highlight its usage</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">Query</span> q = pm.newQuery(<span class="string"><span class="delimiter">"</span><span class="content">SELECT FROM mydomain.Product p WHERE p.price <= :threshold ORDER BY p.price ASC</span><span class="delimiter">"</span></span>); |
| <span class="predefined-type">List</span> results = q.execute(my_threshold);</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>In this Query, we implicitly select the <em>JDOQL</em> language by just passing in a query string to the method <em>PersistenceManager.newQuery(String)</em>, |
| and the query is specified to return all objects of type <em>Product</em> (or subclasses) which have the price less than or equal to some threshold value |
| and ordering the results by the price. |
| We’ve specified the query like this because we want to pass the threshold value in as a parameter (so maybe running it once with one value, |
| and once with a different value). |
| We then set the parameter value of our <em>threshold</em> parameter. |
| The Query is then executed to return a List of results. |
| The example is to highlight the typical methods specified for a (JDOQL) string-based Query.</p> |
| </div> |
| <div class="sect2"> |
| <h3 id="_creating_a_query">Creating a query</h3> |
| <div class="paragraph"> |
| <p>The principal ways of creating a query are</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>Specifying the query language, and using a single-string form of the query</p> |
| </li> |
| </ul> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre>Query q = pm.newQuery("javax.jdo.query.JDOQL", |
| "SELECT FROM mydomain.MyClass WHERE field2 < threshold PARAMETERS java.util.Date threshold");</pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>or alternatively</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">Query</span> q = pm.newQuery(<span class="string"><span class="delimiter">"</span><span class="content">SQL</span><span class="delimiter">"</span></span>, <span class="string"><span class="delimiter">"</span><span class="content">SELECT * FROM MYTABLE WHERE COL1 == 25);</span></span></code></pre> |
| </div> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>A <a href="#named">"named" query</a>, (pre-)defined in metadata (refer to metadata docs).</p> |
| </li> |
| </ul> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre>Query<MyClass> q = pm.newNamedQuery(MyClass.class, "MyQuery1");</pre> |
| </div> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>JDOQL : Use the <a href="jdoql.html#singlestring">single-string</a> form of the query</p> |
| </li> |
| </ul> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre>Query q = pm.newQuery("SELECT FROM mydomain.MyClass WHERE field2 < threshold PARAMETERS java.util.Date threshold");</pre> |
| </div> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>JDOQL : Use the <a href="jdoql.html#jdoql">declarative API</a> to define the query</p> |
| </li> |
| </ul> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre>Query<MyClass> q = pm.newQuery(MyClass.class); |
| q.setFilter("field2 < threshold"); |
| q.declareParameters("java.util.Date threshold");</pre> |
| </div> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>JDOQL : Use the <a href="jdoql.html#jdoql_typed">Typed Query API</a> to define the query</p> |
| </li> |
| </ul> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre>JDOQLTypedQuery<MyClass> q = pm.newJDOQLTypedQuery(MyClass.class); |
| QMyClass cand = QMyClass.candidate(); |
| List<Product> results = q.filter(cand.field2.lt(q.doubleParameter("threshold"))).executeList();</pre> |
| </div> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="_closing_a_query">Closing a query</h3> |
| <div class="paragraph"> |
| <p>When a query is executed it will have access to the results of that query. |
| Each time it is executed (maybe with different parameters) it will have separate results. |
| This can consume significant resources if the query returned a lot of records.</p> |
| </div> |
| <div class="paragraph"> |
| <p>You close a query (and all query results) like this</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="java">q.close();</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>If you just wanted to close a specific query result you would call</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="java">q.close(queryResult);</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>where the <em>queryResult</em> is what you were returned from executing the query.</p> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="named">Named Query</h3> |
| <div class="paragraph"> |
| <p>With the JDO Query API you can either define a query at runtime, or define it in the MetaData/annotations for a class and refer to it at runtime using a symbolic name. |
| This second option means that the method of invoking the query at runtime is much simplified. |
| To demonstrate the process, lets say we have a class called <em>Product</em> (something to sell in a store). |
| We define the JDO Meta-Data for the class in the normal way, but we also have some query that we know we will require, so we define the following in the Meta-Data.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="xml"><span class="tag"><package</span> <span class="attribute-name">name</span>=<span class="string"><span class="delimiter">"</span><span class="content">mydomain</span><span class="delimiter">"</span></span><span class="tag">></span> |
| <span class="tag"><class</span> <span class="attribute-name">name</span>=<span class="string"><span class="delimiter">"</span><span class="content">Product</span><span class="delimiter">"</span></span><span class="tag">></span> |
| ... |
| <span class="tag"><query</span> <span class="attribute-name">name</span>=<span class="string"><span class="delimiter">"</span><span class="content">SoldOut</span><span class="delimiter">"</span></span> <span class="attribute-name">language</span>=<span class="string"><span class="delimiter">"</span><span class="content">javax.jdo.query.JDOQL</span><span class="delimiter">"</span></span><span class="tag">></span><span class="inline-delimiter"><![CDATA[</span> |
| SELECT FROM mydomain.Product WHERE status == "Sold Out" |
| <span class="inline-delimiter">]]></span><span class="tag"></query></span> |
| <span class="tag"></class></span> |
| <span class="tag"></package></span></code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>So we have a JDOQL query called "SoldOut" defined for the class <em>Product</em> that returns all Products (and subclasses) that have a <em>status</em> of "Sold Out". |
| Out of interest, what we would then do in our application to execute this query woule be</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">Query</span><Product> q = pm.newNamedQuery(mydomain.Product.class,<span class="string"><span class="delimiter">"</span><span class="content">SoldOut</span><span class="delimiter">"</span></span>); |
| <span class="predefined-type">List</span><Product> results = q.executeList();</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>The above example was for the JDOQL object-based query language. We can do a similar thing using SQL, so we define the following in our MetaData for our <em>Product</em> class</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="xml"><span class="tag"><jdo></span> |
| <span class="tag"><package</span> <span class="attribute-name">name</span>=<span class="string"><span class="delimiter">"</span><span class="content">mydomain</span><span class="delimiter">"</span></span><span class="tag">></span> |
| <span class="tag"><class</span> <span class="attribute-name">name</span>=<span class="string"><span class="delimiter">"</span><span class="content">Product</span><span class="delimiter">"</span></span><span class="tag">></span> |
| ... |
| <span class="tag"><query</span> <span class="attribute-name">name</span>=<span class="string"><span class="delimiter">"</span><span class="content">PriceBelowValue</span><span class="delimiter">"</span></span> <span class="attribute-name">language</span>=<span class="string"><span class="delimiter">"</span><span class="content">javax.jdo.query.SQL</span><span class="delimiter">"</span></span><span class="tag">></span><span class="inline-delimiter"><![CDATA[</span> |
| SELECT NAME FROM PRODUCT WHERE PRICE < ? |
| <span class="inline-delimiter">]]></span><span class="tag"></query></span> |
| <span class="tag"></class></span> |
| <span class="tag"></package></span> |
| <span class="tag"></jdo></span></code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>So here we have an SQL query that will return the names of all Products that have a price less than a specified value. |
| This leaves us the flexibility to specify the value at runtime. So here we run our named query, asking for the names of all Products with price below 20 euros.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">Query</span><Product> q = pm.newNamedQuery(mydomain.Product.class, <span class="string"><span class="delimiter">"</span><span class="content">PriceBelowValue</span><span class="delimiter">"</span></span>); |
| q.setParameters(<span class="float">20.0</span>); |
| <span class="predefined-type">List</span><Product> results = q.executeList();</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>All of the examples above have been specifed within the <class> element of the MetaData. |
| You can, however, specify queries below <jdo> in which case the query is not scoped by a particular candidate class. |
| In this case you must put your queries in any of the following MetaData files</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre>/META-INF/package.jdo |
| /WEB-INF/package.jdo |
| /package.jdo |
| /META-INF/package-{mapping}.orm |
| /WEB-INF/package-{mapping}.orm |
| /package-{mapping}.orm |
| /META-INF/package.jdoquery |
| /WEB-INF/package.jdoquery |
| /package.jdoquery</pre> |
| </div> |
| </div> |
| <div class="sect3"> |
| <h4 id="save_as_named">Saving a Query as a Named Query</h4> |
| <div class="paragraph"> |
| <p>JDO also allows you to create a query, and then save it as a "named" query for later reuse. You do this as follows</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">Query</span> q = pm.newQuery(<span class="string"><span class="delimiter">"</span><span class="content">SELECT FROM mydomain.Product p WHERE ...</span><span class="delimiter">"</span></span>); |
| q.saveAsNamedQuery(<span class="string"><span class="delimiter">"</span><span class="content">MyQuery</span><span class="delimiter">"</span></span>);</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>and you can thereafter access the query via</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">Query</span> q = pm.newNamedQuery(Product.class, <span class="string"><span class="delimiter">"</span><span class="content">MyQuery</span><span class="delimiter">"</span></span>);</code></pre> |
| </div> |
| </div> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="query_extensions">Query Extensions</h3> |
| <div class="paragraph"> |
| <p>The JDO query API allows implementations to support "extensions" and provides a simple interface for enabling the use of such extensions on queries. |
| An extension specifies additional information to the query mechanism about how to perform the query. |
| Individual extensions will be explained later in this guide.</p> |
| </div> |
| <div class="paragraph"> |
| <p>You set an extension like this</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="java">q.extension(<span class="string"><span class="delimiter">"</span><span class="content">extension_name</span><span class="delimiter">"</span></span>, value);</code></pre> |
| </div> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">Map</span> exts = <span class="keyword">new</span> <span class="predefined-type">HashMap</span>(); |
| exts.put(<span class="string"><span class="delimiter">"</span><span class="content">extension1</span><span class="delimiter">"</span></span>, value1); |
| exts.put(<span class="string"><span class="delimiter">"</span><span class="content">extension2</span><span class="delimiter">"</span></span>, value2); |
| q.extensions(exts);</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>The Query API also has methods <em>setExtensions</em> and <em>addExtension</em> that are from the original version of the API, but function the same as these methods quoted.</p> |
| </div> |
| <div class="admonitionblock note"> |
| <table> |
| <tr> |
| <td class="icon"> |
| <i class="fa icon-note" title="Note"></i> |
| </td> |
| <td class="content"> |
| Refer to the documentation of your JDO provider for what extensions are supported. |
| </td> |
| </tr> |
| </table> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="query_parameters">Setting query parameters</h3> |
| <div class="paragraph"> |
| <p>Queries can be made flexible and reusable by defining parameters as part of the query, so that we can execute the same query |
| with different sets of parameters and minimise resources.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="java"><span class="comment">// JDOQL Using named parameters</span> |
| <span class="predefined-type">Query</span><Product> q = pm.newQuery(Product.class); |
| q.setFilter(<span class="string"><span class="delimiter">"</span><span class="content">this.name == :name && this.serialNo == :serial</span><span class="delimiter">"</span></span>); |
| |
| <span class="predefined-type">Map</span> params = <span class="keyword">new</span> <span class="predefined-type">HashMap</span>(); |
| params.put(<span class="string"><span class="delimiter">"</span><span class="content">name</span><span class="delimiter">"</span></span>, <span class="string"><span class="delimiter">"</span><span class="content">Walkman</span><span class="delimiter">"</span></span>); |
| params.put(<span class="string"><span class="delimiter">"</span><span class="content">serial</span><span class="delimiter">"</span></span>, <span class="string"><span class="delimiter">"</span><span class="content">123021</span><span class="delimiter">"</span></span>); |
| q.setNamedParameters(params); |
| |
| |
| <span class="comment">// JDOQL Using numbered parameters</span> |
| <span class="predefined-type">Query</span><Product> q = pm.newQuery(Product.class); |
| q.setFilter(<span class="string"><span class="delimiter">"</span><span class="content">this.name == ?1 && this.serialNo == ?2</span><span class="delimiter">"</span></span>); |
| |
| q.setParameters(<span class="string"><span class="delimiter">"</span><span class="content">Walkman</span><span class="delimiter">"</span></span>, <span class="string"><span class="delimiter">"</span><span class="content">123021</span><span class="delimiter">"</span></span>);</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>Alternatively you can specify the query parameters in the <em>execute</em> method call.</p> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="compile">Compiling a query</h3> |
| <div class="paragraph"> |
| <p>An intermediate step once you have your query defined, if you want to check its validity, is to <em>compile</em> it. You do this as follows</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="java">q.compile();</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>If the query is invalid, then a JDOException will be thrown.</p> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="_executing_a_query">Executing a query</h3> |
| <div class="paragraph"> |
| <p>So we have set up our query. We now execute it. We have various methods to do this, depending on what result we are expecting etc</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="java"><span class="comment">// Simple execute</span> |
| <span class="predefined-type">Object</span> result = q.execute(); |
| |
| <span class="comment">// Execute with 1 parameter passed in</span> |
| <span class="predefined-type">Object</span> result = q.execute(paramVal1); |
| |
| <span class="comment">// Execute with multiple parameters passed in</span> |
| <span class="predefined-type">Object</span> result = q.execute(paramVal1, paramVal2); |
| |
| <span class="comment">// Execute with an array of parameters passed in (positions match the query parameter position)</span> |
| <span class="predefined-type">Object</span> result = q.executeWithArray(<span class="keyword">new</span> <span class="predefined-type">Object</span><span class="type">[]</span>{paramVal1, paramVal2}); |
| |
| <span class="comment">// Execute with a map of parameters keyed by their name in the query</span> |
| <span class="predefined-type">Object</span> result = q.executeWithMap(paramMap); |
| |
| <span class="comment">// Execute knowing we want to receive a list of results</span> |
| <span class="predefined-type">List</span> results = q.executeList(); |
| |
| <span class="comment">// Execute knowing there is 1 result row</span> |
| <span class="predefined-type">Object</span> result = q.executeUnique(); |
| |
| <span class="comment">// Execute where we want a list of results and want each result row of a particular type</span> |
| <span class="predefined-type">List</span><ResultClass> results = q.executeResultList(ResultClass.class); |
| |
| <span class="comment">// Execute where we want a single result and want the result row of a particular type</span> |
| ResultClass result = q.executeResultUnique(ResultClass.class);</code></pre> |
| </div> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="resultclass">Result Class</h3> |
| <div class="paragraph"> |
| <p>By default a JDO query of whatever language will return a result matching the result clause. You can override this if you wish by specifying a result class. |
| If your query has only a single row in the results then you will get an object of your result class back, otherwise you get a List of result class objects. |
| The <em>Result Class</em> has to meet certain requirements. These are</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p>Can be one of Integer, Long, Short, Float, Double, Character, Byte, Boolean, String, java.math.BigInteger, java.math.BigDecimal, |
| java.util.Date, java.sql.Date, java.sql.Time, java.sql.Timestamp, java.time.LocalDate, java.time.LocalTime, java.time.LocalDateTime, or Object[]</p> |
| </li> |
| <li> |
| <p>Can be a user-defined class, that has either a constructor taking arguments of the same type as those returned by the query (in the same order), |
| or has a public put(Object, Object) method, or public setXXX() methods, or public fields.</p> |
| </li> |
| </ul> |
| </div> |
| <div class="paragraph"> |
| <p>Please look at the specific help for the query language you are using for details of a user-defined result class.</p> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="FetchPlan">Controlling the execution : FetchPlan</h3> |
| <div class="paragraph"> |
| <p>When a Query is executed it executes in the datastore, which returns a set of results. |
| Your JDO provider could clearly read all results from this ResultSet in one go and return them all to the user, or could allow control over this fetching process. |
| JDO provides a <em>fetch size</em> on the <em>Fetch Plan</em> to allow this control. You would set this as follows</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">Query</span> q = pm.newQuery(...); |
| q.getFetchPlan().setFetchSize(FetchPlan.FETCH_SIZE_OPTIMAL);</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p><em>fetch size</em> has 3 possible values.</p> |
| </div> |
| <div class="ulist"> |
| <ul> |
| <li> |
| <p><strong>FETCH_SIZE_OPTIMAL</strong> - allows your JDO provider full control over the fetching. |
| In this case your JDO provider will fetch each object when they are requested, and then when the owning transaction is committed will retrieve all remaining rows |
| (so that the Query is still usable after the close of the transaction).</p> |
| </li> |
| <li> |
| <p><strong>FETCH_SIZE_GREEDY</strong> - Your JDO provider will read all objects in at query execution. |
| This can be efficient for queries with few results, and very inefficient for queries returning large result sets.</p> |
| </li> |
| <li> |
| <p><strong>A positive value</strong> - Your JDO provider will read this number of objects at query execution. Thereafter it will read the objects when requested.</p> |
| </li> |
| </ul> |
| </div> |
| <div class="paragraph"> |
| <p>In addition to the number of objects fetched, you can also control which fields are fetched for each object of the candidate type. |
| This is controlled via the <a href="fetchgroups.html#singlestring">FetchPlan</a>.</p> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="ignore_cache">ignoreCache(), setIgnoreCache()</h3> |
| <div class="paragraph"> |
| <p>The ignoreCache option setting specifies whether when processing the query results it should check for the retrieved objects in the cache.</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="java">q.ignoreCache(<span class="predefined-constant">true</span>);</code></pre> |
| </div> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="locking">Control over locking of fetched objects</h3> |
| <div class="paragraph"> |
| <p>JDO allows control over whether objects found by a query are locked during that transaction so that other transactions can’t update them in the meantime. |
| To do this you would do</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="java"><span class="predefined-type">Query</span> q = pm.newQuery(...); |
| q.serializeRead(<span class="predefined-constant">true</span>);</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p>In addition you can perform this on a per-transaction basis by doing</p> |
| </div> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="java">tx.setSerializeRead(<span class="predefined-constant">true</span>);</code></pre> |
| </div> |
| </div> |
| <div class="admonitionblock note"> |
| <table> |
| <tr> |
| <td class="icon"> |
| <i class="fa icon-note" title="Note"></i> |
| </td> |
| <td class="content"> |
| If the datastore in use doesn’t support locking of objects then this will do nothing |
| </td> |
| </tr> |
| </table> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="read_timeout">Timeout on query execution for reads</h3> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="java">q.datastoreReadTimeoutMillis(<span class="integer">1000</span>);</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p><em>Sets the timeout for this query (in milliseconds).</em> |
| Will throw a JDOUnsupportedOperationException if the query implementation doesn’t support timeouts (for the current datastore).</p> |
| </div> |
| </div> |
| <div class="sect2"> |
| <h3 id="write_timeout">Timeout on query execution for writes</h3> |
| <div class="listingblock"> |
| <div class="content"> |
| <pre class="CodeRay highlight"><code data-lang="java">q.datastoreWriteTimeoutMillis(<span class="integer">1000</span>);</code></pre> |
| </div> |
| </div> |
| <div class="paragraph"> |
| <p><em>Sets the timeout for this query (in milliseconds) when it is a delete/update.</em> |
| Will throw a JDOUnsupportedOperationException if the query implementation doesn’t support timeouts (for the current datastore).</p> |
| </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">© 2005-2022 Apache Software Foundation. All Rights Reserved.</p> |
| </div> |
| </footer> |
| |
| </body> |
| </html> |