相关文章推荐
This script outputs the google search parameters required for search on edocs documentation. This script outputs the product breadcrumb required for edocs documentation. Developers Guide for Kodo
10.2.1. JPQL Statement Types
10.2.1.1. JPQL Select Statement
10.2.1.2. JPQL Update and Delete Statements
10.2.2. JPQL Abstract Schema Types and Query Domains
10.2.2.1. JPQL Entity Naming
10.2.2.2. JPQL Schema Example
10.2.3. JPQL FROM Clause and Navigational Declarations
10.2.3.1. JPQL FROM Identifiers
10.2.3.2. JPQL Identification Variables
10.2.3.3. JPQL Range Declarations
10.2.3.4. JPQL Path Expressions
10.2.3.5. JPQL Joins
10.2.3.5.1. JPQL Inner Joins (Relationship Joins)
10.2.3.5.2. JPQL Outer Joins
10.2.3.5.3. JPQL Fetch Joins
10.2.3.6. JPQL Collection Member Declarations
10.2.3.7. JPQL Polymorphism
10.2.4. JPQL WHERE Clause
10.2.5. JPQL Conditional Expressions
10.2.5.1. JPQL Literals
10.2.5.2. JPQL Identification Variables
10.2.5.3. JPQL Path Expressions
10.2.5.4. JPQL Input Parameters
10.2.5.4.1. JPQL Positional Parameters
10.2.5.4.2. JPQL Named Parameters
10.2.5.5. JPQL Conditional Expression Composition
10.2.5.6. JPQL Operators and Operator Precedence
10.2.5.7. JPQL Between Expressions
10.2.5.8. JPQL In Expressions
10.2.5.9. JPQL Like Expressions
10.2.5.10. JPQL Null Comparison Expressions
10.2.5.11. JPQL Empty Collection Comparison Expressions
10.2.5.12. JPQL Collection Member Expressions
10.2.5.13. JPQL Exists Expressions
10.2.5.14. JPQL All or Any Expressions
10.2.5.15. JPQL Subqueries
10.2.5.16. JPQL Functional Expressions
10.2.5.16.1. JPQL String Functions
10.2.5.16.2. JPQL Arithmetic Functions
10.2.5.16.3. JPQL Datetime Functions
10.2.6. JPQL GROUP BY, HAVING
10.2.7. JPQL SELECT Clause
10.2.7.1. JPQL Result Type of the SELECT Clause
10.2.7.2. JPQL Constructor Expressions
10.2.7.3. JPQL Null Values in the Query Result
10.2.7.4. JPQL Aggregate Functions
10.2.7.4.1. JPQL Aggregate Examples
10.2.8. JPQL ORDER BY Clause
10.2.9. JPQL Bulk Update and Delete
10.2.10. JPQL Null Values
10.2.11. JPQL Equality and Comparison Semantics
10.2.12. JPQL BNF

The Java Persistence query language (JPQL) is used to define searches against persistent entities independent of the mechanism used to store those entities. As such, JPQL is "portable", and not constrained to any particular data store. The Java Persistence query language is an extension of the Enterprise JavaBeans query language, EJB QL , adding operations such as bulk deletes and updates, join operations, aggregates, projections, and subqueries. Furthermore, JPQL queries can be declared statically in metadata, or can be dynamically built in code. This chapter provides the full definition of the language. Much of this section is paraphrased or taken directly from Chapter 4 of the JSR 220 specification.

A JPQL statement may be either a SELECT statement, an UPDATE statement, or a DELETE statement. This chapter refers to all such statements as "queries". Where it is important to distinguish among statement types, the specific statement type is referenced. In BNF syntax, a query language statement is defined as:

  • QL_statement ::= select_statement | update_statement | delete_statement

The complete BNF for JPQL is defined in Section 10.2.12, “JPQL BNF” . Any JPQL statement may be constructed dynamically or may be statically defined in a metadata annotation or XML descriptor element. All statement types may have parameters, as discussed in Section 10.2.5.4, “JPQL Input Parameters” .

10.2.2. JPQL Abstract Schema Types and Query Domains

The Java Persistence query language is a typed language, and every expression has a type. The type of an expression is derived from the structure of the expression, the abstract schema types of the identification variable declarations, the types to which the persistent fields and relationships evaluate, and the types of literals. The abstract schema type of an entity is derived from the entity class and the metadata information provided by Java language annotations or in the XML descriptor. Informally, the abstract schema type of an entity can be characterized as follows: For every persistent field or get accessor method (for a persistent property) of the entity class, there is a field ("state-field") whose abstract schema type corresponds to that of the field or the result type of the accessor method. For every persistent relationship field or get accessor method (for a persistent relationship property) of the entity class, there is a field ("association-field") whose type is the abstract schema type of the related entity (or, if the relationship is a one-to-many or many-to-many, a collection of such). Abstract schema types are specific to the query language data model. The persistence provider is not required to implement or otherwise materialize an abstract schema type. The domain of a query consists of the abstract schema types of all entities that are defined in the same persistence unit. The domain of a query may be restricted by the navigability of the relationships of the entity on which it is based. The association-fields of an entity's abstract schema type determine navigability. Using the association-fields and their values, a query can select related entities and use their abstract schema types in the query.

This example assumes that the application developer provides several entity classes representing magazines, publishers, authors, and articles. The abstract schema types for these entities are Magazine , Publisher , Author , and Article . The entity Publisher has a one-to-many relationships with Magazine . There is also a one-to-many relationship between Magazine and Article . The entity Article is related to Author in a one-to-one relationship. Queries to select magazines can be defined by navigating over the association-fields and state-fields defined by Magazine and Author . A query to find all magazines that have unpublished articles is as follows:

SELECT DISTINCT mag FROM Magazine AS mag JOIN mag.articles AS art WHERE art.published = FALSE
This query navigates over the association-field authors of the abstract schema type Magazine to find articles, and uses the state-field published of Article to select those magazines that have at least one article that is published. Although predefined reserved identifiers, such as DISTINCT , FROM , AS , JOIN , WHERE , and FALSE , appear in upper case in this example, predefined reserved identifiers are case insensitive. The SELECT clause of this example designates the return type of this query to be of type Magazine . Because the same persistence unit defines the abstract persistence schemas of the related entities, the developer can also specify a query over articles that utilizes the abstract schema type for products, and hence the state-fields and association-fields of both the abstract schema types Magazine and Author . For example, if the abstract schema type Author has a state-field named firstName , a query over articles can be specified using this state-field. Such a query might be to find all magazines that have articles authored by someone with the first name "John".
SELECT DISTINCT mag FROM Magazine mag
    JOIN mag.articles art JOIN art.author auth WHERE auth.firstName = 'John'
Because Magazine is related to Author by means of the relationships between Magazine and Article and between Article and Author , navigation using the association-fields authors and product is used to express the query. This query is specified by using the abstract schema name Magazine , which designates the abstract schema type over which the query ranges. The basis for the navigation is provided by the association-fields authors and product of the abstract schema types Magazine and Article respectively.

The FROM clause of a query defines the domain of the query by declaring identification variables. An identification variable is an identifier declared in the FROM clause of a query. The domain of the query may be constrained by path expressions. Identification variables designate instances of a particular entity abstract schema type. The FROM clause can contain multiple identification variable declarations separated by a comma (,).

  • from_clause ::= FROM identification_variable_declaration {, {identification_variable_declaration | collection_member_declaration}}*

  • identification_variable_declaration ::= range_variable_declaration { join | fetch_join }*

  • range_variable_declaration ::= abstract_schema_name [AS] identification_variable

  • join ::= join_spec join_association_path_expression [AS] identification_variable

  • fetch_join ::= join_spec FETCH join_association_path_expression

  • join_association_path_expression ::= join_collection_valued_path_expression | join_single_valued_association_path_expression

  • join_spec ::= [ LEFT [OUTER] | INNER ] JOIN

  • collection_member_declaration ::= IN (collection_valued_path_expression) [AS] identification_variable

An identification variable is a valid identifier declared in the FROM clause of a query. All identification variables must be declared in the FROM clause. Identification variables cannot be declared in other clauses. An identification variable must not be a reserved identifier or have the same name as any entity in the same persistence unit: Identification variables are case insensitive. An identification variable evaluates to a value of the type of the expression used in declaring the variable. For example, consider the previous query:

SELECT DISTINCT mag FROM Magazine mag JOIN mag.articles art JOIN art.author auth WHERE auth.firstName = 'John'
In the FROM clause declaration mag.articles art , the identification variable art evaluates to any Article value directly reachable from Magazine . The association-field articles is a collection of instances of the abstract schema type Article and the identification variable art refers to an element of this collection. The type of auth is the abstract schema type of Author . An identification variable ranges over the abstract schema type of an entity. An identification variable designates an instance of an entity abstract schema type or an element of a collection of entity abstract schema type instances. Identification variables are existentially quantified in a query. An identification variable always designates a reference to a single value. It is declared in one of three ways: in a range variable declaration, in a join clause, or in a collection member declaration. The identification variable declarations are evaluated from left to right in the FROM clause, and an identification variable declaration can use the result of a preceding identification variable declaration of the query string.

An identification variable followed by the navigation operator (.) and a state-field or association-field is a path expression. The type of the path expression is the type computed as the result of navigation; that is, the type of the state-field or association-field to which the expression navigates. Depending on navigability, a path expression that leads to an association-field may be further composed. Path expressions can be composed from other path expressions if the original path expression evaluates to a single-valued type (not a collection) corresponding to an association-field. Path-expression navigability is composed using "inner join" semantics. That is, if the value of a non-terminal association-field in the path expression is null, the path is considered to have no value, and does not participate in the determination of the result. The syntax for single-valued path expressions and collection-valued path expressions is as follows:

A single_valued_association_field is designated by the name of an association-field in a one-to-one or many-to-one relationship. The type of a single_valued_association_field and thus a single_valued_association_path_expression is the abstract schema type of the related entity. A collection_valued_association_field is designated by the name of an association-field in a one-to-many or a many-to-many relationship. The type of a collection_valued_association_field is a collection of values of the abstract schema type of the related entity. An embedded_class_state _field is designated by the name of an entity-state field that corresponds to an embedded class. Navigation to a related entity results in a value of the related entity's abstract schema type. The evaluation of a path expression terminating in a state-field results in the abstract schema type corresponding to the Java type designated by the state-field. It is syntactically illegal to compose a path expression from a path expression that evaluates to a collection. For example, if designates Magazine , the path expression mag.articles.author is illegal since navigation to authors results in a collection. This case should produce an error when the query string is verified. To handle such a navigation, an identification variable must be declared in the FROM clause to range over the elements of the articles collection. Another path expression must be used to navigate over each such element in the WHERE clause of the query, as in the following query, which returns all authors that have any articles in any magazines:

SELECT DISTINCT art.author FROM Magazine AS mag, IN(mag.articles) art

An inner join may be implicitly specified by the use of a cartesian product in the FROM clause and a join condition in the WHERE clause. The syntax for explicit join operations is as follows:

  • join ::= join_spec join_association_path_expression [AS] identification_variable

  • fetch_join ::= join_spec FETCH join_association_path_expression

  • join_association_path_expression ::= join_collection_valued_path_expression | join_single_valued_association_path_expression

  • join_spec ::= [ LEFT [OUTER] | INNER ] JOIN

The following inner and outer join operation types are supported.

A FETCH JOIN enables the fetching of an association as a side effect of the execution of a query. A FETCH JOIN is specified over an entity and its related entities. The syntax for a fetch join is

The association referenced by the right side of the FETCH JOIN clause must be an association that belongs to an entity that is returned as a result of the query. It is not permitted to specify an identification variable for the entities referenced by the right side of the FETCH JOIN clause, and hence references to the implicitly fetched entities cannot appear elsewhere in the query. The following query returns a set of magazines. As a side effect, the associated articles for those magazines are also retrieved, even though they are not part of the explicit query result. The persistent fields or properties of the articles that are eagerly fetched are fully initialized. The initialization of the relationship properties of the articles that are retrieved is determined by the metadata for the Article entity class.

SELECT mag FROM Magazine mag LEFT JOIN FETCH mag.articles WHERE mag.id = 1
A fetch join has the same join semantics as the corresponding inner or outer join, except that the related objects specified on the right-hand side of the join operation are not returned in the query result or otherwise referenced in the query. Hence, for example, if magazine id 1 has five articles, the above query returns five references to the magazine 1 entity.

An identification variable declared by a collection_member_declaration ranges over values of a collection obtained by navigation using a path expression. Such a path expression represents a navigation involving the association-fields of an entity abstract schema type. Because a path expression can be based on another path expression, the navigation can use the association-fields of related entities. An identification variable of a collection member declaration is declared using a special operator, the reserved identifier IN . The argument to the IN operator is a collection-valued path expression. The path expression evaluates to a collection type specified as a result of navigation to a collection-valued association-field of an entity abstract schema type. The syntax for declaring a collection member identification variable is as follows:

For example, the query

SELECT DISTINCT mag FROM Magazine mag
    JOIN mag.articles art
    JOIN art.author auth
    WHERE auth.lastName = 'Grisham'
may equivalently be expressed as follows, using the IN operator:
SELECT DISTINCT mag FROM Magazine mag,
    IN(mag.articles) art
    WHERE art.author.lastName = 'Grisham'
In this example, articles is the name of an association-field whose value is a collection of instances of the abstract schema type Article . The identification variable art designates a member of this collection, a single Article abstract schema type instance. In this example, mag is an identification variable of the abstract schema type Magazine .

The following sections describe the language constructs that can be used in a conditional expression of the WHERE clause or HAVING clause. State-fields that are mapped in serialized form or as lobs may not be portably used in conditional expressions. The implementation is not expected to perform such query operations involving such fields in memory rather than in the database.

10.2.5.2. JPQL Identification Variables

All identification variables used in the WHERE or HAVING clause of a SELECT or DELETE statement must be declared in the FROM clause, as described in Section 10.2.3.2, “JPQL Identification Variables” . The identification variables used in the WHERE clause of an UPDATE statement must be declared in the UPDATE clause. Identification variables are existentially quantified in the WHERE and HAVING clause. This means that an identification variable represents a member of a collection or an instance of an entity's abstract schema type. An identification variable never designates a collection in its entirety.

Either positional or named parameters may be used. Positional and named parameters may not be mixed in a single query. Input parameters can only be used in the WHERE clause or HAVING clause of a query. Note that if an input parameter value is null, comparison operations or arithmetic operations involving the input parameter will return an unknown value. See Section 10.2.10, “JPQL Null Values” .

The syntax for the use of the comparison operator [ NOT ] IN in a conditional expression is as follows: The state_field_path_expression must have a string, numeric, or enum value. The literal and/or input_parameter values must be like the same abstract schema type of the state_field_path_expression in type. (See Section 10.2.11, “JPQL Equality and Comparison Semantics” ). The results of the subquery must be like the same abstract schema type of the state_field_path_expression in type. Subqueries are discussed in Section 10.2.5.15, “JPQL Subqueries” . Examples are:

o.country IN ('UK', 'US', 'France')
is true for UK and false for Peru, and is equivalent to the expression:
(o.country = 'UK') OR (o.country = 'US') OR (o.country = ' France')
In the following expression:
o.country NOT IN ('UK', 'US', 'France')
is false for UK and true for Peru, and is equivalent to the expression:
NOT ((o.country = 'UK') OR (o.country = 'US') OR (o.country = 'France'))
There must be at least one element in the comma separated list that defines the set of values for the IN expression. If the value of a state_field_path_expression in an IN or NOT IN expression is NULL or unknown, the value of the expression is unknown.

The JPQL includes the following built-in functions, which may be used in the WHERE or HAVING clause of a query. If the value of any argument to a functional expression is null or unknown, the value of the functional expression is unknown.

10.2.5.16.1. JPQL String Functions

The CONCAT function returns a string that is a concatenation of its arguments. The second and third arguments of the SUBSTRING function denote the starting position and length of the substring to be returned. These arguments are integers. The first position of a string is denoted by 1. The SUBSTRING function returns a string. The TRIM function trims the specified character from a string. If the character to be trimmed is not specified, it is assumed to be space (or blank). The optional trim_character is a single-character string literal or a character-valued input parameter (i.e., char or Character). If a trim specification is not provided, BOTH is assumed. The TRIM function returns the trimmed string. The LOWER and UPPER functions convert a string to lower and upper case, respectively. They return a string. The LOCATE function returns the position of a given string within a string, starting the search at a specified position. It returns the first position at which the string was found as an integer. The first argument is the string to be located; the second argument is the string to be searched; the optional third argument is an integer that represents the string position at which the search is started (by default, the beginning of the string to be searched). The first position in a string is denoted by 1. If the string is not found, 0 is returned. The LENGTH function returns the length of the string in characters as an integer.

The SELECT clause denotes the query result. More than one value may be returned from the SELECT clause of a query. The SELECT clause may contain one or more of the following elements: a single range variable or identification variable that ranges over an entity abstract schema type, a single-valued path expression, an aggregate select expression, a constructor expression. The SELECT clause has the following syntax:

  • select_clause ::= SELECT [DISTINCT] select_expression {, select_expression}*

  • select_expression ::= single_valued_path_expression | aggregate_expression | identification_variable | OBJECT(identification_variable) | constructor_expression

  • constructor_expression ::= NEW constructor_name ( constructor_item {, constructor_item}* )

  • constructor_item ::= single_valued_path_expression | aggregate_expression

  • aggregate_expression ::= { AVG | MAX | MIN | SUM } ([DISTINCT] state_field_path_expression) | COUNT ([DISTINCT] identification_variable | state_field_path_expression | single_valued_association_path_expression)

For example:

SELECT pub.id, pub.revenue
    FROM Publisher pub JOIN pub.magazines mag WHERE mag.price > 5.00
Note that the SELECT clause must be specified to return only single-valued expressions. The query below is therefore not valid:

SELECT mag.authors FROM Magazine AS mag
The DISTINCT keyword is used to specify that duplicate values must be eliminated from the query result. If DISTINCT is not specified, duplicate values are not eliminated. Standalone identification variables in the SELECT clause may optionally be qualified by the OBJECT operator. The SELECT clause must not use the OBJECT operator to qualify path expressions.

The type of the query result specified by the SELECT clause of a query is an entity abstract schema type, a state-field type, the result of an aggregate function, the result of a construction operation, or some sequence of these. The result type of the SELECT clause is defined by the the result types of the select_expressions contained in it. When multiple select_expressions are used in the SELECT clause, the result of the query is of type Object[], and the elements in this result correspond in order to the order of their specification in the SELECT clause and in type to the result types of each of the select_expressions. The type of the result of a select_expression is as follows: A single_valued_path_expression that is a state_field_path_expression results in an object of the same type as the corresponding state field of the entity. If the state field of the entity is a primitive type, the corresponding object type is returned. single_valued_path_expression that is a single_valued_association_path_expression results in an entity object of the type of the relationship field or the subtype of the relationship field of the entity object as determined by the object/relational mapping. The result type of an identification_variable is the type of the entity to which that identification variable corresponds or a subtype as determined by the object/relational mapping. The result type of aggregate_expression is defined in section Section 10.2.7.4, “JPQL Aggregate Functions” . The result type of a constructor_expression is the type of the class for which the constructor is defined. The types of the arguments to the constructor are defined by the above rules.

in the SELECT Clause The result of a query may be the result of an aggregate function applied to a path expression. The following aggregate functions can be used in the SELECT clause of a query: AVG , COUNT , MAX , MIN , SUM . For all aggregate functions except COUNT , the path expression that is the argument to the aggregate function must terminate in a state-field. The path expression argument to COUNT may terminate in either a state-field or a association-field, or the argument to COUNT may be an identification variable. Arguments to the functions SUM and AVG must be numeric. Arguments to the functions MAX and MIN must correspond to orderable state-field types (i.e., numeric types, string types, character types, or date types). The Java type that is contained in the result of a query using an aggregate function is as follows: COUNT returns Long. MAX , MIN return the type of the state-field to which they are applied. AVG returns Double. SUM returns Long when applied to state-fields of integral types (other than BigInteger); Double when applied to state-fields of floating point types; BigInteger when applied to state-fields of type BigInteger; and BigDecimal when applied to state-fields of type BigDecimal. If SUM , AVG , MAX , or MIN is used, and there are no values to which the aggregate function can be applied, the result of the aggregate function is NULL . If COUNT is used, and there are no values to which COUNT can be applied, the result of the aggregate function is 0. The argument to an aggregate function may be preceded by the keyword DISTINCT to specify that duplicate values are to be eliminated before the aggregate function is applied. Null values are eliminated before the aggregate function is applied, regardless of whether the keyword DISTINCT is specified.

Operations Bulk update and delete operations apply to entities of a single entity class (together with its subclasses, if any). Only one entity abstract schema type may be specified in the FROM or UPDATE clause. The syntax of these operations is as follows:

The syntax of the WHERE clause is described in Section 10.2.4, “JPQL WHERE Clause” . A delete operation only applies to entities of the specified class and its subclasses. It does not cascade to related entities. The new_value specified for an update operation must be compatible in type with the state-field to which it is assigned. Bulk update maps directly to a database update operation, bypassing optimistic locking checks. Portable applications must manually update the value of the version column, if desired, and/or manually validate the value of the version column. The persistence context is not synchronized with the result of the bulk update or delete. Caution should be used when executing bulk update or delete operations because they may result in inconsistencies between the database and the entities in the active persistence context. In general, bulk update and delete operations should only be performed within a separate transaction or at the beginning of a transaction (before entities have been accessed whose state might be affected by such operations).

DELETE FROM Publisher pub WHERE pub.revenue > 1000000.0
DELETE FROM Publisher pub WHERE pub.revenue = 0 AND pub.magazines IS EMPTY
UPDATE Publisher pub SET pub.status = 'outstanding'
    WHERE pub.revenue < 1000000 AND 20 > (SELECT COUNT(mag) FROM pub.magazines mag)
 
推荐文章