You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jdo-commits@db.apache.org by an...@apache.org on 2022/04/13 14:19:09 UTC
[db-jdo-site] branch main updated: Change to JDO 3.2 javadocs links. Remove extents doc since already part of object retrieval. Copy query_api doc from DN docs, removing DN-specific parts.
This is an automated email from the ASF dual-hosted git repository.
andyj pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/db-jdo-site.git
The following commit(s) were added to refs/heads/main by this push:
new 3981aa6 Change to JDO 3.2 javadocs links. Remove extents doc since already part of object retrieval. Copy query_api doc from DN docs, removing DN-specific parts.
3981aa6 is described below
commit 3981aa68583132f75760ac7637a21bf7f3aace14
Author: andyjefferson <an...@datanucleus.org>
AuthorDate: Wed Apr 13 15:19:03 2022 +0100
Change to JDO 3.2 javadocs links.
Remove extents doc since already part of object retrieval.
Copy query_api doc from DN docs, removing DN-specific parts.
---
src/main/asciidoc/extents.adoc | 29 ---
src/main/asciidoc/fetchgroups.adoc | 2 +-
src/main/asciidoc/jdohelper.adoc | 2 +-
src/main/asciidoc/jdoql.adoc | 170 ++++++++------
src/main/asciidoc/jdoql_methods.adoc | 28 ++-
src/main/asciidoc/jdoql_result.adoc | 87 ++++---
src/main/asciidoc/object_retrieval.adoc | 66 +++---
src/main/asciidoc/pm.adoc | 2 +-
src/main/asciidoc/pmf.adoc | 2 +-
src/main/asciidoc/query_api.adoc | 399 ++++++++++++++++++++++++++++++++
src/main/template/document.html.erb | 6 +-
11 files changed, 604 insertions(+), 189 deletions(-)
diff --git a/src/main/asciidoc/extents.adoc b/src/main/asciidoc/extents.adoc
deleted file mode 100644
index a8422ed..0000000
--- a/src/main/asciidoc/extents.adoc
+++ /dev/null
@@ -1,29 +0,0 @@
-:_basedir:
-:_imagesdir: images/
-:notoc:
-:notitle:
-:grid: cols
-:query:
-
-[[index]]
-
-== JDO Extentsanchor:JDO_Extents[]
-
-JDO implementations manage the persistence of objects into the
-datastore. An *Extent* is a collection of objects of a particular type
-of object that have been persisted. When you define the MetaData for a
-class you can define if the class requires an Extent. The default is
-true. You access the Extent as follows
-
-....
-Extent e = pm.getExtent(MyClass.class, true);
-
-....
-
-This example will return an Extent that contains all persisted instances
-of the class _MyClass_ and its subclasses (the second argument in the
-call). An Extent is useful where you want to restrict a Query to query
-over just that set of objects. It can also be used where you just want
-to retrieve all persisted objects of a type (as an alternative to using
-a Query).
-
diff --git a/src/main/asciidoc/fetchgroups.adoc b/src/main/asciidoc/fetchgroups.adoc
index e96ffd2..de6f573 100644
--- a/src/main/asciidoc/fetchgroups.adoc
+++ b/src/main/asciidoc/fetchgroups.adoc
@@ -24,7 +24,7 @@ that are part of that fetch group. The definition here is _static_
groups at runtime via an API
The *fetch group* in use for a class is controled via the _FetchPlan_
-http://db.apache.org/jdo/api20/apidocs/javax/jdo/FetchPlan.html[image:images/javadoc.png[image]]
+http://db.apache.org/jdo/api32/apidocs/javax/jdo/FetchPlan.html[image:images/javadoc.png[image]]
interface. To get a handle on the current _FetchPlan_ we do
....
diff --git a/src/main/asciidoc/jdohelper.adoc b/src/main/asciidoc/jdohelper.adoc
index 06d776b..4c93589 100644
--- a/src/main/asciidoc/jdohelper.adoc
+++ b/src/main/asciidoc/jdohelper.adoc
@@ -10,7 +10,7 @@
JDO provides a standard utility that gives access to useful parts of the
JDO persistence process. This is known as *JDOHelper*
(javax.jdo.JDOHelper)
-link:api20/apidocs/javax/jdo/JDOHelper.html[image:images/javadoc.png[image]]
+link:api32/apidocs/javax/jdo/JDOHelper.html[image:images/javadoc.png[image]]
=== PersistenceManagerFactory methodsanchor:PersistenceManagerFactory_methods[]
diff --git a/src/main/asciidoc/jdoql.adoc b/src/main/asciidoc/jdoql.adoc
index d8cd6e9..2da77cc 100644
--- a/src/main/asciidoc/jdoql.adoc
+++ b/src/main/asciidoc/jdoql.adoc
@@ -5,50 +5,49 @@
[[index]]
-== JDOQLanchor:JDOQL[]
+[[JDOQL]]
+== JDOQL
-JDO defines ways of querying objects persisted into the datastore. It
-provides its own object-based query language (JDOQL). JDOQL is designed
-as the Java developers way of having the power of SQL queries, yet
-retaining the Java object relationship that exist in their application
-model. A typical JDOQL query may be set up in one of 2 ways. Here's an
-example
+JDO defines ways of querying objects persisted into the datastore.
+It provides its own object-based query language (JDOQL).
+JDOQL is designed as the Java developers way of having the power of SQL queries, yet retaining the Java object relationship that exist in their application model.
+A typical JDOQL query may be set up in one of 2 ways. Here's an example.
-....
Declarative JDOQL :
+
+[source,java]
+....
Query q = pm.newQuery(mydomain.Person.class, "lastName == \"Jones\" && age < age_limit");
q.declareParameters("double age_limit");
List results = (List)q.execute(20.0);
+....
Single-String JDOQL :
+
+[source,java]
+....
Query q = pm.newQuery("SELECT FROM mydomain.Person WHERE lastName == \"Jones\"" +
" && age < :age_limit PARAMETERS double age_limit");
List results = (List)q.execute(20.0);
....
-So here in our example we select all "Person" objects with surname of
-"Jones" and where the persons age is below 20. The language is intuitive
-for Java developers, and is intended as their interface to accessing the
-persisted data model. As can be seen above, the query is made up of
-distinct parts. The class being selected (the SELECT clause in SQL), the
-filter (which equates to the WHERE clause in SQL), together with any
-sorting (the ORDER BY clause in SQL), etc.
+So here in our example we select all "Person" objects with surname of "Jones" and where the persons age is below 20.
+The language is intuitive for Java developers, and is intended as their interface to accessing the persisted data model.
+As can be seen above, the query is made up of distinct parts.
+The class being selected (the SELECT clause in SQL), the filter (which equates to the WHERE clause in SQL),
+together with any sorting (the ORDER BY clause in SQL), etc.
-Before giving details on JDOQL, you can download a quick reference guide
-link:jdoql_quickref.pdf[here]
+Before giving details on JDOQL, you can download a quick reference guide link:jdoql_quickref.pdf[here]
-{empty} +
-anchor:singlestring[]
-=== Single-String JDOQLanchor:Single-String_JDOQL[]
+[[singlestring]]
+=== Single-String JDOQL
-In traditional (declarative) JDOQL (JDO 1.0) it was necessary to specify
-the component parts (filter, candidate class, ordering, etc) of the
-query using the mutator methods on the Query. In JDO 2 you can now
-specify it all in a single string. This string has to follow a
-particular pattern, but provides the convenience that many people have
-been asking for. The pattern to use is as follows
+In original (declarative) JDOQL (JDO 1.0) it was necessary to specify the component parts (filter, candidate class, ordering, etc)
+of the query using the mutator methods on the Query. From JDO 2 onwards you can specify it all in a single string.
+This string has to follow a particular pattern, but provides the convenience that many people require.
+The pattern to use is as follows
....
SELECT [UNIQUE] [<result>] [INTO <result-class>]
@@ -62,8 +61,7 @@ SELECT [UNIQUE] [<result>] [INTO <result-class>]
[RANGE <start>, <end>]
....
-The "keywords" in the query are shown in UPPER CASE but can be in
-_UPPER_ or _lower_ case.
+The "keywords" in the query are shown in UPPER CASE but can be in _UPPER_ or _lower_ case.
Lets give an example of a query using this syntax
@@ -71,39 +69,41 @@ Lets give an example of a query using this syntax
SELECT UNIQUE FROM org.datanucleus.samples.Employee ORDER BY departmentNumber
....
-so we form the parts of the query as before, yet here we just specify it
-all in a single call.
+so we form the parts of the query as before, yet here we just specify it all in a single call.
+
+
-=== Accessing Fieldsanchor:Accessing_Fields[]
+[[Accessing_Fields]]
+=== Accessing Fields
In JDOQL you access fields in the query by referring to the field name.
-For example, if you are querying a class called _Product_ and it has a
-field "price", then you access it like this
+For example, if you are querying a class called _Product_ and it has a field "price", then you access it like this
+[source,java]
....
Query query = pm.newQuery(mydomain.Product.class, "price < 150.0");
....
-In addition to the persistent fields, you can also access "public static
-final" fields of any class. You can do this as follows
+In addition to the persistent fields, you can also access "public static final" fields of any class. You can do this as follows
+[source,java]
....
-Query query = pm.newQuery(mydomain.Product.class,
- "taxPercent < mydomain.Product.TAX_BAND_A");
+Query query = pm.newQuery(mydomain.Product.class, "taxPercent < mydomain.Product.TAX_BAND_A");
....
-So this will find all products that include a tax percentage less than
-some "BAND A" level. Where you are using "public static final" fields
-you can either fully-qualify the class name or you can include it in the
+So this will find all products that include a tax percentage less than some "BAND A" level.
+Where you are using "public static final" fields you can either fully-qualify the class name or you can include it in the
"imports" section of the query (see later).
-=== Data types : literalsanchor:Data_types_:_literals[]
-JDOQL supports the following literals: IntegerLiteral,
-FloatingPointLiteral, BooleanLiteral, CharacterLiteral, StringLiteral,
-and NullLiteral.
+[[Data_types_:_literals]]
+=== Data types : literals
+
+JDOQL supports the following literals: IntegerLiteral, FloatingPointLiteral, BooleanLiteral, CharacterLiteral, StringLiteral, and NullLiteral.
+
-=== Operators precedenceanchor:Operators_precedence[]
+[[Operators_precedence]]
+=== Operators precedence
The following list describes the operator precedence in JDOQL.
@@ -120,26 +120,34 @@ The following list describes the operator precedence in JDOQL.
. Conditional AND ("&&")
. Conditional OR ("||")
-=== Concatenation Expressionsanchor:Concatenation_Expressions[]
-The concatenation operator(+) concatenates a String to either another
-String or Number. Concatenations of String or Numbers to null results in
-null.
+[[Concatenation_Expressions]]
+=== Concatenation Expressions
-=== Example 1 - Use of Explicit Parametersanchor:Example_1_-_Use_of_Explicit_Parameters[]
+The concatenation operator(+) concatenates a String to either another String or Number.
+Concatenations of String or Numbers to null results in null.
-Here's a simple example for finding the elements of a class with a field
-below a particular threshold level. Here we pass in the threshold value
-(_limit_), and sort the output in order of ascending price.
-....
+[[Example_1_-_Use_of_Explicit_Parameters]]
+=== Example 1 - Use of Explicit Parameters
+
+Here's a simple example for finding the elements of a class with a field below a particular threshold level.
+Here we pass in the threshold value (_limit_), and sort the output in order of ascending price.
+
Declarative JDOQL :
+
+[source,java]
+....
Query query = pm.newQuery(mydomain.Product.class,"price < limit");
query.declareParameters("double limit");
query.setOrdering("price ascending");
List results = (List)query.execute(150.00);
+....
Single-String JDOQL :
+
+[source,java]
+....
Query query = pm.newQuery("SELECT FROM mydomain.Product WHERE " +
"price < limit PARAMETERS double limit ORDER BY price ASCENDING");
List results = (List)query.execute(150.00);
@@ -147,6 +155,7 @@ List results = (List)query.execute(150.00);
For completeness, the class is shown here
+[source,java]
....
class Product
{
@@ -155,7 +164,10 @@ class Product
java.util.Date endDate;
...
}
+....
+[source,xml]
+....
<jdo>
<package name="mydomain">
<class name="Product">
@@ -175,46 +187,56 @@ class Product
{empty} +
-=== Example 2 - Use of Implicit Parametersanchor:Example_2_-_Use_of_Implicit_Parameters[]
+[[Example_2_-_Use_of_Implicit_Parameters]]
+=== Example 2 - Use of Implicit Parameters
-Let's repeat the previous query but this time using _implicit_
-parameters.
+Let's repeat the previous query but this time using _implicit_ parameters.
-....
Declarative JDOQL :
+
+[source,java]
+....
Query query = pm.newQuery(mydomain.Product.class,"price < :limit");
query.setOrdering("price ascending");
List results = (List)query.execute(150.00);
+....
Single-String JDOQL :
+
+[source,java]
+....
Query query = pm.newQuery("SELECT FROM mydomain.Product WHERE " +
"price < :limit ORDER BY price ASCENDING");
List results = (List)query.execute(150.00);
....
-So we omitted the declaration of the parameter and just prefixed it with
-a colon (:)
-
-{empty} +
+So we omitted the declaration of the parameter and just prefixed it with a colon (:).
-=== Example 3 - Comparison against Datesanchor:Example_3_-_Comparison_against_Dates[]
+[[Example_3_-_Comparison_against_Dates]]
+=== Example 3 - Comparison against Dates
Here's another example using the same Product class as above, but this
time comparing to a Date field. Because we are using a type in our
query, we need to _import_ it ... just like you would in a Java class if
you were using it there.
-....
Declarative JDOQL :
+
+[source,java]
+....
Query query = pm.newQuery(domain.Product.class,
"endDate > best_before_limit");
query.declareImports("import java.util.Date");
query.declareParameters("Date best_before_limit");
query.setOrdering("endDate descending");
Collection results = (Collection)query.execute(my_date_limit);
+....
Single-String JDOQL :
+
+[source,java]
+....
Query query = pm.newQuery("SELECT FROM mydomain.Product " +
"WHERE endDate > best_before_limit " +
"PARAMETERS Date best_before_limit " +
@@ -222,24 +244,28 @@ Query query = pm.newQuery("SELECT FROM mydomain.Product " +
List results = (List)query.execute(my_date_limit);
....
-{empty} +
+[[Example_4_-_Instanceof]]
+=== Example 4 - Instanceof
-=== Example 4 - Instanceofanchor:Example_4_-_Instanceof[]
+This example demonstrates use of the "instanceof" operator.
+We have a class A that has a field "b" of type B and B has subclasses B1, B2, B3.
+Clearly the field "b" of A can be of type B, B1, B2, B3 etc, and we want to find all objects of type A that have the field "b" that is of type B2.
+We do it like this
-This example demonstrates use of the "instanceof" operator. We have a
-class A that has a field "b" of type B and B has subclasses B1, B2, B3.
-Clearly the field "b" of A can be of type B, B1, B2, B3 etc, and we want
-to find all objects of type A that have the field "b" that is of type
-B2. We do it like this
+Declarative JDOQL :
+[source,java]
....
-Declarative JDOQL :
Query query = pm.newQuery(mydomain.A.class);
query.setFilter("b instanceof mydomain.B2");
List results = (List)query.execute();
+....
Single-String JDOQL :
+
+[source,java]
+....
Query query = pm.newQuery("SELECT FROM mydomain.A WHERE b instanceof mydomain.B2");
List results = (List)query.execute();
....
diff --git a/src/main/asciidoc/jdoql_methods.adoc b/src/main/asciidoc/jdoql_methods.adoc
index e79d050..2f7b457 100644
--- a/src/main/asciidoc/jdoql_methods.adoc
+++ b/src/main/asciidoc/jdoql_methods.adoc
@@ -5,7 +5,8 @@
[[index]]
-== JDOQL : Methodsanchor:JDOQL_:_Methods[]
+[[JDOQL_:_Methods]]
+== JDOQL : Methods
When writing the "filter" for a JDOQL Query you can make use of some
methods on the various Java types. The range of methods included as
@@ -15,7 +16,9 @@ the ones that are available are typically of much use.
{empty} +
-=== String Methodsanchor:String_Methods[]
+[[String_Methods]]
+=== String Methods
+
[cols=",",options="header",]
|===
@@ -100,7 +103,8 @@ List results = (List)query.execute();
{empty} +
-=== Collection Methodsanchor:Collection_Methods[]
+[[Collection_Methods]]
+=== Collection Methods
[cols=",",options="header",]
|===
@@ -138,7 +142,8 @@ List results = (List)query.execute();
{empty} +
-=== List Methodsanchor:List_Methods[]
+[[List_Methods]]
+=== List Methods
[cols=",",options="header",]
|===
@@ -153,7 +158,8 @@ List results = (List)query.execute();
{empty} +
-=== Map Methodsanchor:Map_Methods[]
+[[Map_Methods]]
+=== Map Methods
[cols=",",options="header",]
|===
@@ -198,7 +204,8 @@ List results = (List)query.execute();
{empty} +
-=== Temporal Methodsanchor:Temporal_Methods[]
+[[Temporal_Methods]]
+=== Temporal Methods
The following methods apply to fields of temporal types.
@@ -285,7 +292,8 @@ The following methods apply to fields of temporal types.
{empty} +
-=== Enum Methodsanchor:Enum_Methods[]
+[[Enum_Methods]]
+=== Enum Methods
The following methods apply to fields of type _Enum_
@@ -304,7 +312,8 @@ The following methods apply to fields of type _Enum_
{empty} +
-=== Optional Methodsanchor:Optional_Methods[]
+[[Optional_Methods]]
+=== Optional Methods
The following methods apply to fields of type _Optional_
@@ -327,7 +336,8 @@ The following methods apply to fields of type _Optional_
{empty} +
-=== Other Methodsanchor:Other_Methods[]
+[[Other_Methods]]
+=== Other Methods
[cols=",",options="header",]
|===
diff --git a/src/main/asciidoc/jdoql_result.adoc b/src/main/asciidoc/jdoql_result.adoc
index 672d474..c953fcc 100644
--- a/src/main/asciidoc/jdoql_result.adoc
+++ b/src/main/asciidoc/jdoql_result.adoc
@@ -5,65 +5,58 @@
[[index]]
-== JDOQL : Resultanchor:JDOQL_:_Result[]
+[[JDOQL_:_Result]]
+== JDOQL : Result
-As we have seen, a JDOQL query is made up of different parts. In this
-section we look at the _result_ part of the query. The result is what we
-want returning. By default (when not specifying the result) the objects
-returned will be of the candidate class type, where they match the query
-filter. Firstly let's look at what you can include in the _result_
-clause.
+As we have seen, a JDOQL query is made up of different parts.
+In this section we look at the _result_ part of the query.
+The result is what we want returning.
+By default (when not specifying the result) the objects returned will be of the candidate class type, where they match the query filter.
+Firstly let's look at what you can include in the _result_ clause.
* _this_ - the candidate instance
* A field name
* A variable
-* A parameter (though why you would want a parameter returning is hard
-to see since you input the value in the first place)
+* A parameter (though why you would want a parameter returning is hard to see since you input the value in the first place)
* An aggregate (count(), avg(), sum(), min(), max())
* An expression involving a field (e.g "field1 + 1")
-* A navigational expression (navigating from one field to another ...
-e.g "field1.field4")
+* A navigational expression (navigating from one field to another ... e.g "field1.field4")
The result is specified in JDOQL like this
+[source,java]
....
query.setResult("count(field1), field2");
....
In *Single-String JDOQL* you would specify it directly.
-{empty} +
-=== Result typeanchor:Result_type[]
+[[Result_type]]
+=== Result type
-What you specify in the _result_ defines what form of result you get
-back.
+What you specify in the _result_ of a JDOQL query defines what form of result you get back.
-* *Object* - this is returned if you have only a single row in the
-results and a single column. This is achieved when you specified either
-UNIQUE, or just an aggregate (e.g "max(field2)")
-* *Object[]* - this is returned if you have only a single row in the
-results, but more than 1 column (e.g "max(field1), avg(field2)")
-* *List<Object>* - this is returned if you have only a single column in
-the result, and you don't have only aggregates in the result (e.g
-"field2")
-* *List<Object[]>* - this is returned if you have more than 1 column in
-the result, and you don't have only aggregates in the result (e.g
-"field2, avg(field3)")
+* *Object* - this is returned if you have only a single row in the results and a single column.
+This is achieved when you specified either UNIQUE, or just an aggregate (e.g "max(field2)")
+* *Object[]* - this is returned if you have only a single row in the results,
+but more than 1 column (e.g "max(field1), avg(field2)")
+* *List<Object>* - this is returned if you have only a single column in the result,
+and you don't have only aggregates in the result (e.g "field2")
+* *List<Object[]>* - this is returned if you have more than 1 column in the result,
+and you don't have only aggregates in the result (e.g "field2, avg(field3)")
-=== Aggregatesanchor:Aggregates[]
-There are situations when you want to return a single number for a
-column, representing an aggregate of the values of all records. There
-are 5 standard JDO2 aggregate functions available. These are
+[[Aggregates]]
+=== Aggregates
-* *avg(val)* - returns the average of "val". "val" can be a field,
-numeric field expression or "distinct field".
-* *sum(val)* - returns the sum of "val". "val" can be a field, numeric
-field expression, or "distinct field".
-* *count(val)* - returns the count of records of "val". "val" can be a
-field, or can be "this", or "distinct field".
+There are situations when you want to return a single number for a column, representing an aggregate of the values of all records.
+There are 5 standard JDOQL aggregate functions available. These are
+
+* *avg(val)* - returns the average of "val". "val" can be a field, numeric field expression or "distinct field".
+* *sum(val)* - returns the sum of "val". "val" can be a field, numeric field expression, or "distinct field".
+* *count(val)* - returns the count of records of "val". "val" can be a field, or can be "this", or "distinct field".
* *min(val)* - returns the minimum of "val". "val" can be a field
* *max(val)* - returns the maximum of "val". "val" can be a field
@@ -76,33 +69,35 @@ Query q = pm.newQuery("SELECT max(price), min(price) FROM mydomain.Product WHERE
This will return a single row of results with 2 values, the maximum
price and the minimum price of all products that have status code of 1.
-{empty} +
-
-=== Example - Use of aggregatesanchor:Example_-_Use_of_aggregates[]
+[[Example_-_Use_of_aggregates]]
+=== Example - Use of aggregates
-JDO 2 introduces the ability to use aggregates in queries. Here's
-another example using the same Product class as above, but this time
-looking for the maximum price of products that are CD Players. Note that
-the result for this particular query will be of type Double since there
+JDOQL has the ability to use aggregates in queries.
+Here's another example using the same Product class as above, but this time looking for the maximum price of products that are CD Players.
+Note that the result for this particular query will be of type Double since there
is a single double precision value being returned via the "result".
-....
Declarative JDOQL :
+
+[source,java]
+....
Query query = pm.newQuery(mydomain.Product.class);
query.setFilter("name == \"CD Player\"");
query.setResult("max(this.price)");
List results = (List)query.execute();
Iterator iter = c.iterator();
Double max_price = (Double)iter.next();
+....
Single-String JDOQL :
+
+[source,java]
+....
Query query = pm.newQuery("SELECT max(price) FROM mydomain.Product WHERE name == \"CD Player\"");
List results = (List)query.execute();
Iterator iter = c.iterator();
Double max_price = (Double)iter.next();
....
-{empty} +
-
diff --git a/src/main/asciidoc/object_retrieval.adoc b/src/main/asciidoc/object_retrieval.adoc
index 675f2c0..a41b1ee 100644
--- a/src/main/asciidoc/object_retrieval.adoc
+++ b/src/main/asciidoc/object_retrieval.adoc
@@ -5,32 +5,45 @@
[[index]]
-== Object Retrievalanchor:Object_Retrieval[]
+[[Object_Retrieval]]
+== Object Retrieval
-JDO provides persistence of objects. The logical next step after
-persisting objects is to retrieve them for use in your application.
-There are several ways to do this
+Any application will require access to persisted objects.
+The JDO API provides several ways to do this
-=== Retrieve an object from its identityanchor:Retrieve_an_object_from_its_identity[]
+
+[[get_object_by_id]]
+=== Retrieve an object from its identity
The simplest form of object retrieval is where we have the identity.
This is simply
+[source,java]
+....
+Person per = (Person)pm.getObjectById(identity);
....
-Object obj = pm.getObjectById(identity);
-
+
+or
+
+[source,java]
....
+Person per = pm.getObjectById(Person.class, identity);
+....
+
+If the object is in the JDO cache (Level 1 or Level 2) then it is retrieved from there,
+otherwise the JDO implementation goes to the datastore.
+When the object is retrieved its fields are populated according to its Fetch Group.
+
-If the object is in the JDO cache then it is retrieved from there,
-otherwise the JDO implementation goes to the datastore. When the object
-is retrieved its fields are populated according to its Fetch Group.
-=== Retrieve an object based on its Extentanchor:Retrieve_an_object_based_on_its_Extent[]
+[[extent]]
+=== Retrieve an object based on its Extent
-A persistable class can be persisted with an *Extent* of all instances
-of that type. You can use this to retrieve objects of the required type,
-like this
+An *Extent* is a collection of objects of a particular type of object that have been persisted.
+When you define the MetaData for a class you can define if the class requires an Extent.
+The default is true. You access the Extent as follows
+[source,java]
....
Extent ex = pm.getExtent(MyClass.class, true);
Iterator iter = ex.iterator();
@@ -41,23 +54,25 @@ while (iter.hasNext())
}
....
-The second argument in the _getExtent_ call is whether to include
-instances of subclasses.
+The second argument in the _getExtent_ call is whether to include instances of subclasses.
+An Extent is useful where you want to restrict a Query to query over just that set of objects.
+It can also be used where you just want to retrieve all persisted objects of a type (as an alternative to using a Query).
{empty} +
-=== Retrieve an object based on a criteriaanchor:Retrieve_an_object_based_on_a_criteria[]
+[[query]]
+=== Retrieve an object based on a query criteria
-Where we want to retrieve all objects based on some criteria (e.g all
-objects of class A where field 'x' of A is a certain value) we need to
-use a query language. JDO2 provides 2 options here. JDOQL is
-object-based and allows you to express your query in terms of the
-classes and fields you are using. SQL is datastore-based and allows you
-to express your query in terms of the datastore tables and columns.
+Where we want to retrieve all objects based on some criteria (e.g all objects of class A where field 'x' of A is a certain value) we need to
+use a query language.
+The JDO API provides the JDOQL object-based query language where you express your query in terms of classes and fields you are using.
+Dependent on your JDO provider and the datastore being used you may also be able to use a (native) query language such as SQL, expressing
+your query in terms of datastore tables/columns.
To give an example of a JDOQL query
+[source,java]
....
Query q = pm.newQuery(MyClass.class, "field1 < value");
q.declareParameters("int value");
@@ -70,7 +85,6 @@ while (iter.hasNext())
....
If the objects found by the query are in the JDO cache then they are
-retrieved from there, otherwise the JDO implementation goes to the
-datastore. When the objects are retrieved their fields are populated
-according to the Fetch Group.
+retrieved from there, otherwise the JDO implementation goes to the datastore.
+When the objects are retrieved their fields are populated according to the Fetch Group.
diff --git a/src/main/asciidoc/pm.adoc b/src/main/asciidoc/pm.adoc
index 5ff84a9..3e31796 100644
--- a/src/main/asciidoc/pm.adoc
+++ b/src/main/asciidoc/pm.adoc
@@ -12,7 +12,7 @@ _PersistenceManager_ (PM). This is obtained from the
xref:pmf.adoc[PersistenceManagerFactory] for the datastore.
The simplest way of creating a _PersistenceManager_
-link:api20/apidocs/javax/jdo/PersistenceManager.html[image:images/javadoc.png[image]]
+link:api32/apidocs/javax/jdo/PersistenceManager.html[image:images/javadoc.png[image]]
is as follows
....
diff --git a/src/main/asciidoc/pmf.adoc b/src/main/asciidoc/pmf.adoc
index 8537a3a..cd66753 100644
--- a/src/main/asciidoc/pmf.adoc
+++ b/src/main/asciidoc/pmf.adoc
@@ -17,7 +17,7 @@ retrieved. The _PersistenceManagerFactory_ can be configured to provide
particular behaviour.
The simplest way of creating a _PersistenceManagerFactory_
-link:api20/apidocs/javax/jdo/PersistenceManagerFactory.html[image:images/javadoc.png[image]]
+link:api32/apidocs/javax/jdo/PersistenceManagerFactory.html[image:images/javadoc.png[image]]
is as follows
....
diff --git a/src/main/asciidoc/query_api.adoc b/src/main/asciidoc/query_api.adoc
new file mode 100644
index 0000000..8d1c950
--- /dev/null
+++ b/src/main/asciidoc/query_api.adoc
@@ -0,0 +1,399 @@
+[[api]]
+= Query API
+:_basedir:
+:_imagesdir: images/
+:grid: cols
+:query:
+
+
+[[Query_API]]
+== Query API
+
+To understand the JDO Query
+image:../images/javadoc.png[Javadoc, link=api32/apidocs/javax/jdo/Query.html] API we firstly need to look at a typical Query.
+
+Let's create a JDOQL string-based query to highlight its usage
+
+[source,java]
+-----
+Query q = pm.newQuery("SELECT FROM mydomain.Product p WHERE p.price <= :threshold ORDER BY p.price ASC");
+List results = q.execute(my_threshold);
+-----
+
+In this Query, we implicitly select the _JDOQL_ language by just passing in a query string to the method _PersistenceManager.newQuery(String)_,
+and the query is specified to return all objects of type _Product_ (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 _threshold_ 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.
+
+
+
+
+=== Creating a query
+
+The principal ways of creating a query are
+
+
+* Specifying the query language, and using a single-string form of the query
+[source,java]
+-----
+Query q = pm.newQuery("javax.jdo.query.JDOQL",
+ "SELECT FROM mydomain.MyClass WHERE field2 < threshold PARAMETERS java.util.Date threshold");
+-----
+or alternatively
+[source,java]
+-----
+Query q = pm.newQuery("SQL", "SELECT * FROM MYTABLE WHERE COL1 == 25);
+-----
+* A link:#named["named" query], (pre-)defined in metadata (refer to metadata docs).
+[source,java]
+-----
+Query<MyClass> q = pm.newNamedQuery(MyClass.class, "MyQuery1");
+-----
+* JDOQL : Use the link:jdoql.html#singlestring[single-string] form of the query
+[source,java]
+-----
+Query q = pm.newQuery("SELECT FROM mydomain.MyClass WHERE field2 < threshold PARAMETERS java.util.Date threshold");
+-----
+* JDOQL : Use the link:jdoql.html#jdoql[declarative API] to define the query
+[source,java]
+-----
+Query<MyClass> q = pm.newQuery(MyClass.class);
+q.setFilter("field2 < threshold");
+q.declareParameters("java.util.Date threshold");
+-----
+* JDOQL : Use the link:jdoql.html#jdoql_typed[Typed Query API] to define the query
+[source,java]
+-----
+JDOQLTypedQuery<MyClass> q = pm.newJDOQLTypedQuery(MyClass.class);
+QMyClass cand = QMyClass.candidate();
+List<Product> results = q.filter(cand.field2.lt(q.doubleParameter("threshold"))).executeList();
+-----
+
+
+=== Closing a query
+
+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.
+
+You close a query (and all query results) like this
+
+[source,java]
+-----
+q.close();
+-----
+
+If you just wanted to close a specific query result you would call
+
+[source,java]
+-----
+q.close(queryResult);
+-----
+where the _queryResult_ is what you were returned from executing the query.
+
+
+
+[[named]]
+=== Named Query
+
+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 _Product_ (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.
+
+[source,xml]
+-----
+<package name="mydomain">
+ <class name="Product">
+ ...
+ <query name="SoldOut" language="javax.jdo.query.JDOQL"><![CDATA[
+ SELECT FROM mydomain.Product WHERE status == "Sold Out"
+ ]]></query>
+ </class>
+</package>
+-----
+
+So we have a JDOQL query called "SoldOut" defined for the class _Product_ that returns all Products (and subclasses) that have a _status_ of "Sold Out".
+Out of interest, what we would then do in our application to execute this query woule be
+
+[source,java]
+-----
+Query<Product> q = pm.newNamedQuery(mydomain.Product.class,"SoldOut");
+List<Product> results = q.executeList();
+-----
+
+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 _Product_ class
+
+[source,xml]
+-----
+<jdo>
+ <package name="mydomain">
+ <class name="Product">
+ ...
+ <query name="PriceBelowValue" language="javax.jdo.query.SQL"><![CDATA[
+ SELECT NAME FROM PRODUCT WHERE PRICE < ?
+ ]]></query>
+ </class>
+ </package>
+</jdo>
+-----
+
+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.
+
+[source,java]
+-----
+Query<Product> q = pm.newNamedQuery(mydomain.Product.class, "PriceBelowValue");
+q.setParameters(20.0);
+List<Product> results = q.executeList();
+-----
+
+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
+
+-----
+/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
+-----
+
+
+
+[[save_as_named]]
+==== Saving a Query as a Named Query
+
+JDO also allows you to create a query, and then save it as a "named" query for later reuse. You do this as follows
+
+[source,java]
+-----
+Query q = pm.newQuery("SELECT FROM mydomain.Product p WHERE ...");
+q.saveAsNamedQuery("MyQuery");
+-----
+
+and you can thereafter access the query via
+
+[source,java]
+-----
+Query q = pm.newNamedQuery(Product.class, "MyQuery");
+-----
+
+
+
+[[query_extensions]]
+=== Query Extensions
+
+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.
+
+You set an extension like this
+
+[source,java]
+-----
+q.extension("extension_name", value);
+-----
+
+[source,java]
+-----
+Map exts = new HashMap();
+exts.put("extension1", value1);
+exts.put("extension2", value2);
+q.extensions(exts);
+-----
+
+The Query API also has methods _setExtensions_ and _addExtension_ that are from the original version of the API, but function the same as these methods quoted.
+
+NOTE: Refer to the documentation of your JDO provider for what extensions are supported.
+
+
+[[query_parameters]]
+=== Setting query parameters
+
+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.
+
+[source,java]
+-----
+// JDOQL Using named parameters
+Query<Product> q = pm.newQuery(Product.class);
+q.setFilter("this.name == :name && this.serialNo == :serial");
+
+Map params = new HashMap();
+params.put("name", "Walkman");
+params.put("serial", "123021");
+q.setNamedParameters(params);
+
+
+// JDOQL Using numbered parameters
+Query<Product> q = pm.newQuery(Product.class);
+q.setFilter("this.name == ?1 && this.serialNo == ?2");
+
+q.setParameters("Walkman", "123021");
+-----
+
+Alternatively you can specify the query parameters in the _execute_ method call.
+
+
+[[compile]]
+=== Compiling a query
+
+An intermediate step once you have your query defined, if you want to check its validity, is to _compile_ it. You do this as follows
+
+[source,java]
+-----
+q.compile();
+-----
+
+If the query is invalid, then a JDOException will be thrown.
+
+
+
+=== Executing a query
+
+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
+
+[source,java]
+-----
+// Simple execute
+Object result = q.execute();
+
+// Execute with 1 parameter passed in
+Object result = q.execute(paramVal1);
+
+// Execute with multiple parameters passed in
+Object result = q.execute(paramVal1, paramVal2);
+
+// Execute with an array of parameters passed in (positions match the query parameter position)
+Object result = q.executeWithArray(new Object[]{paramVal1, paramVal2});
+
+// Execute with a map of parameters keyed by their name in the query
+Object result = q.executeWithMap(paramMap);
+
+// Execute knowing we want to receive a list of results
+List results = q.executeList();
+
+// Execute knowing there is 1 result row
+Object result = q.executeUnique();
+
+// Execute where we want a list of results and want each result row of a particular type
+List<ResultClass> results = q.executeResultList(ResultClass.class);
+
+// Execute where we want a single result and want the result row of a particular type
+ResultClass result = q.executeResultUnique(ResultClass.class);
+-----
+
+[[resultclass]]
+=== Result Class
+
+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 _Result Class_ has to meet certain requirements. These are
+
+* 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[]
+* 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.
+
+Please look at the specific help for the query language you are using for details of a user-defined result class.
+
+
+
+
+[[FetchPlan]]
+=== Controlling the execution : FetchPlan
+
+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 _fetch size_ on the _Fetch Plan_ to allow this control. You would set this as follows
+
+[source,java]
+-----
+Query q = pm.newQuery(...);
+q.getFetchPlan().setFetchSize(FetchPlan.FETCH_SIZE_OPTIMAL);
+-----
+
+_fetch size_ has 3 possible values.
+
+* *FETCH_SIZE_OPTIMAL* - 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).
+* *FETCH_SIZE_GREEDY* - 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.
+* *A positive value* - Your JDO provider will read this number of objects at query execution. Thereafter it will read the objects when requested.
+
+
+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 _FetchPlan_.
+
+
+
+[[ignore_cache]]
+=== ignoreCache(), setIgnoreCache()
+
+The ignoreCache option setting specifies whether when processing the query results it should check for the retrieved objects in the cache.
+
+[source,java]
+-----
+q.ignoreCache(true);
+-----
+
+
+
+[[locking]]
+=== Control over locking of fetched objects
+
+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
+
+[source,java]
+-----
+Query q = pm.newQuery(...);
+q.serializeRead(true);
+-----
+
+In addition you can perform this on a per-transaction basis by doing
+
+[source,java]
+-----
+tx.setSerializeRead(true);
+-----
+
+NOTE: If the datastore in use doesn't support locking of objects then this will do nothing
+
+
+
+[[read_timeout]]
+=== Timeout on query execution for reads
+
+[source,java]
+-----
+q.datastoreReadTimeoutMillis(1000);
+-----
+
+_Sets the timeout for this query (in milliseconds)._
+Will throw a JDOUnsupportedOperationException if the query implementation doesn't support timeouts (for the current datastore).
+
+
+
+[[write_timeout]]
+=== Timeout on query execution for writes
+
+[source,java]
+-----
+q.datastoreWriteTimeoutMillis(1000);
+-----
+
+_Sets the timeout for this query (in milliseconds) when it is a delete/update._
+Will throw a JDOUnsupportedOperationException if the query implementation doesn't support timeouts (for the current datastore).
+
+
diff --git a/src/main/template/document.html.erb b/src/main/template/document.html.erb
index 3bd41cc..51a8f28 100644
--- a/src/main/template/document.html.erb
+++ b/src/main/template/document.html.erb
@@ -200,12 +200,12 @@
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Query<span class="caret"></span></a>
<% end %>
<ul class="dropdown-menu">
+ <li><a href="<%= (attr :_basedir) %>query_api.html">Query API</a></li>
+ <li role="separator" class="divider"></li>
<li><a href="<%= (attr :_basedir) %>jdoql.html">JDOQL</a></li>
- <li><a href="<%= (attr :_basedir) %>jdoql_result.html">Result</a></li>
<li><a href="<%= (attr :_basedir) %>jdoql_methods.html">Methods</a></li>
+ <li><a href="<%= (attr :_basedir) %>jdoql_result.html">Result</a></li>
<li><a href="<%= (attr :_basedir) %>jdoql_quickref.pdf">Quick Ref PDF</a></li>
- <li role="separator" class="divider"></li>
- <li><a href="<%= (attr :_basedir) %>extents.html">Extents</a></li>
</ul>
</li>