|
Home TOC Index |
|
Search
Feedback |
Full Syntax
This section discusses the EJB QL syntax, as defined in the Enterprise JavaBeans Specification. Much of the following material paraphrases or directly quotes the Enterprise JavaBeans Specification.
BNF Grammar of EJB QL
Here is the entire BNF diagram for EJB QL:
EJB QL ::= select_clause from_clause [where_clause] from_clause ::= FROM identification_variable_declaration [, identification_variable_declaration]* identification_variable_declaration ::= collection_member_declaration | range_variable_declaration collection_member_declaration ::= IN (collection_valued_path_expression) [AS] identifier range_variable_declaration ::= abstract_schema_name [AS] identifier single_valued_path_expression ::= {single_valued_navigation | identification_variable}.cmp_field | single_valued_navigation single_valued_navigation ::= identification_variable.[single_valued_cmr_field.]* single_valued_cmr_field collection_valued_path_expression ::= identification_variable.[single_valued_cmr_field.]* collection_valued_cmr_field select_clause ::= SELECT [DISTINCT] {single_valued_path_expression | OBJECT(identification_variable)} where_clause ::= WHERE conditional_expression conditional_expression ::= conditional_term | conditional_expression OR conditional_term conditional_term ::= conditional_factor | conditional_term AND conditional_factor conditional_factor ::= [ NOT ] conditional_test conditional_test :: = conditional_primary conditional_primary ::= simple_cond_expression | (conditional_expression) simple_cond_expression ::= comparison_expression | between_expression | like_expression | in_expression | null_comparison_expression | empty_collection_comparison_expression | collection_member_expression between_expression ::= arithmetic_expression [NOT] BETWEEN arithmetic_expression AND arithmetic_expression in_expression ::= single_valued_path_expression [NOT] IN (string_literal [, string_literal]* ) like_expression ::= single_valued_path_expression [NOT] LIKE pattern_value [ESCAPE escape-character] null_comparison_expression ::= single_valued_path_expression IS [NOT] NULL empty_collection_comparison_expression ::= collection_valued_path_expression IS [NOT] EMPTY collection_member_expression ::= {single_valued_navigation | identification_variable | input_parameter} [NOT] MEMBER [OF] collection_valued_path_expression comparison_expression ::= string_value { =|<>} string_expression | boolean_value { =|<>} boolean_expression} | datetime_value { = | <> | > | < } datetime_expression | entity_bean_value { = | <> } entity_bean_expression | arithmetic_value comparison_operator single_value_designator arithmetic_value ::= single_valued_path_expression | functions_returning_numerics single_value_designator ::= scalar_expression comparison_operator ::= = | > | >= | < | <= | <> scalar_expression ::= arithmetic_expression arithmetic_expression ::= arithmetic_term | arithmetic_expression { + | - } arithmetic_term arithmetic_term ::= arithmetic_factor | arithmetic_term { * | / } arithmetic_factor arithmetic_factor ::= { + |- } arithmetic_primary arithmetic_primary ::= single_valued_path_expression | literal | (arithmetic_expression) | input_parameter | functions_returning_numerics string_value ::= single_valued_path_expression | functions_returning_strings string_expression ::= string_primary | input_expression string_primary ::= single_valued_path_expression | literal | (string_expression) | functions_returning_strings datetime_value ::= single_valued_path_expression datetime_expression ::= datetime_value | input_parameter boolean_value ::= single_valued_path_expression boolean_expression ::= single_valued_path_expression | literal | input_parameter entity_bean_value ::= single_valued_navigation | identification_variable entity_bean_expression ::= entity_bean_value | input_parameter functions_returning_strings ::= CONCAT(string_expression, string_expression) | SUBSTRING(string_expression, arithmetic_expression, arithmetic_expression) functions_returning_numerics::= LENGTH(string_expression) | LOCATE(string_expression, string_expression[, arithmetic_expression]) | ABS(arithmetic_expression) | SQRT(arithmetic_expression)BNF Symbols
Table 8-1 describes the BNF symbols used in this chapter.
FROM Clause
The
FROMclause defines the domain of the query by declaring identification variables. Here is the syntax of theFROMclause:from_clause ::= FROM identification_variable_declaration [, identification_variable_declaration]* identification_variable_declaration ::= collection_member_declaration | range_variable_declaration collection_member_declaration ::= IN (collection_valued_path_expression) [AS] identifier range_variable_declaration ::= abstract_schema_name [AS] identifier
Identifiers
An identifier is a sequence of one or more characters. The first character must be a valid first character (letter,
$,_) in an identifier of the Javaprogramming language (hereafter in this chapter called simply "Java"). Each subsequent character in the sequence must be a valid non-first character (letter, digit,
$,_) in a Java identifier. (For details, see the J2SEAPI documentation of the
isJavaIdentifierStartandisJavaIdentifierPartmethods of theCharacterclass.) The question mark (?) is a reserved character in EJB QL and cannot be used in an identifier. Unlike a Java variable, an EJB QL identifier is not case sensitive.An identifier cannot be the same as an EJB QL keyword:
AND
AS
BETWEEN
DISTINCT
EMPTY
FALSE
FROM
IN
IS
LIKE
MEMBER
NOT
NULL
OBJECT
OF
OR
SELECT
TRUE
UNKNOWN
WHERE
EJB QL keywords are also reserved words in SQL. In the future, the list of EJB QL keywords may expand to include other reserved SQL words. The Enterprise JavaBeans
Specification recommends that you not use other reserved SQL words for EJB QL identifiers.
Identification Variables
An identification variable is an identifier declared in the
FROMclause. Although theSELECTandWHEREclauses may reference identification variables, they cannot declare them. All identification variables must be declared in theFROMclause.Since an identification variable is an identifier, it has the same naming conventions and restrictions as an identifier. For example, an identification variable is not case sensitive and it cannot be the same as an EJB QL keyword. (See the previous section for more naming rules.) Also, within a given EJB JAR file, an identifier name must not match the name of any entity bean or abstract schema.
The
FROMclause may contain multiple declarations, separated by commas. A declaration may reference another identification variable that has been previously declared (to the left). In the followingFROMclause, the variabletreferences the previously declared variablep:FROM Player p, IN (p.teams) AS tEven if an identification variable is not used in the
WHEREclause, its declaration can affect the results of the query. For an example, compare the next two queries. The following query returns all players, whether or not they belong to a team:SELECT OBJECT(p) FROM Player pIn contrast, because the next query declares the
tidentification variable, it fetches all players that belong to a team:SELECT OBJECT(p) FROM Player p, IN (p.teams) AS tThe following query returns the same results as the preceding query, but the
WHEREclause makes it easier to read:SELECT OBJECT(p) FROM Player p WHERE p.teams IS NOT EMPTYAn identification variable always designates a reference to a single value, whose type is that of the expression used in the declaration. There are two kinds of declarations: range variable and collection member.
Range Variable Declarations
To declare an identification variable as an abstract schema type, you specify a range variable declaration. In other words, an identification variable can range over the abstract schema type of an entity bean. In the following example, an identification variable named
prepresents the abstract schema namedPlayer:FROM Player pA range variable declaration may include the optional
ASoperator:FROM Player AS pIn most cases, to obtain objects a query navigates through the relationships with path expressions. But for those objects that cannot be obtained by navigation, you can use a range variable declaration to designate a starting point (or root).
If the query compares multiple values of the same abstract schema type, then the
FROMclause must declare multiple identification variables for the abstract schema:FROM Player p1, Player p2For a sample of such a query, see Example 9.
Collection Member Declarations
In a one-to-many relationship, the multiple side consists of a collection of entity beans. An identification variable may represent a member of this collection. To access a collection member, the path expression in the variable's declaration navigates through the relationships in the abstract schema. (For more information on path expressions, see the following section.) Because a path expression may be based on another path expression, the navigation can traverse several relationships. See Example 6.
A collection member declaration must include the
INoperator, but it may omit the optionalASoperator.In the following example, the entity bean represented by the abstract schema named
Playerhas a relationship field calledteams. The identification variable namedtrepresents a single member of theteamscollection.FROM Player p, IN (p.teams) AS tPath Expressions
Path expressions are important constructs in the syntax of EJB QL, for several reasons. First, they define navigation paths through the relationships in the abstract schema. These path definitions affect both the scope and the results of a query. Second, they may appear in any of the three main clauses of an EJB QL query (
SELECT,WHERE,FROM). Finally, although much of EJB QL is a subset of SQL, path expressions are extensions not found in SQL.Syntax
There are two types of path expressions: single-valued and collection-valued. Here is the syntax for path expressions:
single_valued_path_expression ::= {single_valued_navigation | identification_variable}.cmp_field | single_valued_navigation single_valued_navigation ::= identification_variable.[single_valued_cmr_field.]* single_valued_cmr_field collection_valued_path_expression ::= identification_variable.[single_valued_cmr_field.]* collection_valued_cmr_fieldIn the preceding diagram, the
cmp_fieldelement represents a persistent field, and thecmr_fieldelement designates a relationship field. The termsingle_valuedqualifies the relationship field as the single side of a one-to-one or one-to-many relationship; the termcollection_valueddesignates it as the multiple (collection) side of a relationship.The period (.) in a path expression serves two functions. If a period precedes a persistent field, it is a delimiter between the field and the identification variable. If a period precedes a relationship field, it is a navigation operator.
Examples
In the following query, the
WHEREclause contains a single-valued expression. Thepis an identification variable, andsalaryis a persistent field ofPlayer.SELECT DISTINCT OBJECT(p) FROM Player p WHERE p.salary BETWEEN ?1 AND ?2The
WHEREclause of the next example also contains a single-valued expression. Thetis an identification variable,leagueis a single-valued relationship field, andsportis a persistent field ofleague.SELECT DISTINCT OBJECT(p) FROM Player p, IN (p.teams) AS t WHERE t.league.sport = ?1In the next query, the
WHEREclause contains a collection-valued expression. Thepis an identification variable, andteamsdesignates a collection-valued relationship field.SELECT DISTINCT OBJECT(p) FROM Player p WHERE p.teams IS EMPTYExpression Types
The type of an expression is the type of the object represented by the ending element, which can be one of the following:
For example, the type of the expression
p.salaryisdoublebecause the terminating persistent field (salary) is adouble.In the expression
p.teams, the terminating element is a collection-valued relationship field (teams). This expression's type is a collection of the abstract schema type namedTeam. BecauseTeamis the abstract schema name for theTeamEJBentity bean, this type maps to the bean's local interface,LocalTeam. For more information on the type mapping of abstract schemas, see the section Return Types.Navigation
A path expression enables the query to navigate to related entity beans. The terminating elements of an expression determine whether navigation is allowed. If an expression contains a single-valued relationship field, the navigation may continue to an object that is related to the field. However, an expression cannot navigate beyond a persistent field or a collection-valued relationship field. For example, the expression
p.teams.league.sportis illegal, sinceteamsis a collection-valued relationship field. To reach thesportfield, theFROMclause could define an identification variable namedtfor theteamsfield:FROM Player AS p, IN (p.teams) t WHERE t.league.sport = 'soccer'WHERE Clause
The
WHEREclause specifies a conditional expression that limits the values returned by the query. The query returns all corresponding values in the data store for which the conditional expression isTRUE. Although usually specified, theWHEREclause is optional. If theWHEREclause is omitted, then the query returns all values. The high-level syntax for theWHEREclause follows:Where_clause ::= WHERE conditional_expressionLiterals
There are three kinds of literals: string, numeric, and boolean.
String Literals
A string literal is enclosed in single quotes:
'Duke'If a string literal contains a single quote, you indicate the quote with two single quotes:
'Duke''s'Like a Java
String, a string literal in EJB QL uses the Unicode character encoding.Numeric Literals
There are two types of numeric literals: exact and approximate.
An exact numeric literal is a numeric value without a decimal point, such as 65, -233, +12. Using the Java integer syntax, exact numeric literals support numbers in the range of a Java
long.An approximate numeric literal is a numeric value in scientific notation, such as 57., -85.7, +2.1. Using the syntax of the Java floating point literal, approximate numeric literals support numbers in the range of a Java
double.Boolean Literals
A boolean literal is either
TRUEorFALSE. These keywords are not case sensitive.Input Parameters
An input parameter is designated by a question mark (
?) followed by an integer. For example, the first input parameter is?1, the second is?2, and so forth.The following rules apply to input parameters:
- They can be used only in a
WHEREclause.- Their use is restricted to a single-valued path expression within a conditional expression.
- They must be numbered, starting with the integer 1.
- The number of input parameters in the
WHEREclause must not exceed the number of input parameters in the corresponding finder or select method.- The type of an input parameter in the
WHEREclause must match the type of the corresponding argument in the finder or select method.Conditional Expressions
A
WHEREclause consists of a conditional expression, which is evaluated from left to right within a precedence level. You may change the order of evaluation with parentheses.Here is the syntax of a conditional expression:
conditional_expression ::= conditional_term | conditional_expression OR conditional_term conditional_term ::= conditional_factor | conditional_term AND conditional_factor conditional_factor ::= [ NOT ] conditional_test conditional_test :: = conditional_primary conditional_primary ::= simple_cond_expression | (conditional_expression) simple_cond_expression ::= comparison_expression | between_expression | like_expression | in_expression | null_comparison_expression | empty_collection_comparison_expression | collection_member_expressionOperators and Their Precedence
Table 8-2 lists the EJB QL operators in order of decreasing precedence.
BETWEEN Expressions
A
BETWEENexpression determines whether an arithmetic expression falls within a range of values. The syntax of theBETWEENexpression follows:between_expression ::= arithmetic_expression [NOT] BETWEEN arithmetic_expression AND arithmetic_expressionThese two expressions are equivalent:
p.age BETWEEN 15 AND 19 p.age >= 15 AND p.age <= 19The following two expressions are also equivalent:
p.age NOT BETWEEN 15 AND 19 p.age < 15 OR p.age > 19If an arithmetic expression has a
NULLvalue, then the value of theBETWEENexpression is unknown.IN Expressions
An
INexpression determines whether or not a string belongs to a set of string literals. Here is the syntax of theINexpression:in_expression ::= single_valued_path_expression [NOT] IN (string_literal [, string_literal]* )The single-valued path expression must have a
Stringvalue. If the single-valued path expression has aNULLvalue, then the value of theINexpression is unknown.In the following example, if the country is
UKthe expression isTRUE. If the country isPeruit isFALSE.o.country IN ('UK', 'US', 'France')LIKE Expressions
A
LIKEexpression determines whether a wildcard pattern matches a string. Here is the syntax:like_expression ::= single_valued_path_expression [NOT] LIKE pattern_value [ESCAPE escape-character]The single-valued path expression must have a
Stringvalue. If this value isNULL, then the value of theLIKEexpression is unknown. The pattern value is a string literal that may contain wildcard characters. The underscore (_) wildcard character represents any single character. The percent (%) wildcard character represents zero or more characters. TheESCAPEclause specifies an escape character for the wildcard characters in the pattern value.Table 8-3 shows some sample
LIKEexpressions. TheTRUEandFALSEcolumns indicate the value of theLIKEexpression for a single-valued path expression.NULL Comparison Expressions
A
NULLcomparison expression tests whether a single-valued path expression has aNULLvalue. Usually, this expression is used to test whether or not a single-valued relationship has been set. If a path expression contains aNULLvalue during evaluation, it returns aNULLvalue. Here is the syntax of aNULLcomparison expression:null_comparison_expression ::= single_valued_path_expression IS [NOT] NULLEmpty Collection Comparison Expressions
An empty collection comparison expression tests whether a collection-valued path expression has no elements. In other words, it tests whether or not a collection-valued relationship has been set. Here is the syntax:
empty_collection_comparison_expression ::= collection_valued_path_expression IS [NOT] EMPTY
If the collection-valued path expression is
NULL, then the empty collection comparison expression has aNULLvalue.Collection Member Expressions
The collection member expression determines whether a value is a member of a collection. The value and the collection members must have the same type. The expression syntax follows:
collection_member_expression ::= {single_valued_navigation | identification_variable | input_parameter} [NOT] MEMBER [OF] collection_valued_path_expressionIf the collection-valued path expression is unknown, then the collection member expression is unknown. If the collection-valued path expression designates an empty collection, then the collection member expression is
FALSE.Functional Expressions
EJB QL includes several string and arithmetic functions, which are listed in the following tables. In Table 8-4, the
startandlengtharguments are of typeint. They designate positions in theStringargument. In Table 8-5, thenumberargument may be either anint, afloat, or adouble.
Table 8-4 String Expressions Function Syntax
Return Type
CONCAT(String, String)
String
SUBSTRING(String, start, length)
String
LOCATE(String, String [, start])
int
LENGTH(String)
int
Table 8-5 Arithmetic Expressions Function Syntax
Return Type
ABS(number)
int,float, ordouble
SQRT(double)
double
NULL Values
If the target of a reference is not in the persistent store, then the target is
NULL. For conditional expressions containingNULL, EJB QL uses the semantics defined by SQL92. Briefly, these semantics are as follows:
- If a comparison or arithmetic operation has an unknown value, it yields a
NULLvalue.- If a path expression contains a
NULLvalue during evaluation, it returns aNULLvalue.- The
IS NULLtest converts aNULLpersistent field or a single-valued relationship field toTRUE. TheIS NOT NULLtest converts them toFALSE.- Boolean operators and conditional tests use the three-valued logic defined by the following tables. (In these tables, T stands for
TRUE, F forFALSE, and U for unknown.)
Table 8-6 AND Operator Logic AND
T
F
U
T
T
F
U
F
F
F
F
U
U
F
U
Table 8-7 OR Operator Logic OR
T
F
U
T
T
T
T
F
T
F
U
U
T
U
U
Table 8-8 NOT Operator Logic NOT
T
F
F
T
U
U
Table 8-9 Conditional Test Conditional Test
T
F
U
Expression IS TRUE
T
F
F
Expression IS FALSE
F
T
F
Expression is unknown
F
F
T
Equality Semantics
In EJB QL, only values of the same type can be compared. However, this rule has one exception: Exact and approximate numeric values can be compared. In such a comparison, the required type conversion adheres to the rules of Java numeric promotion.
EJB QL treats compared values as if they were Java types, not as if they represented types in the underlying data store. For example, if a persistent field could be either an integer or a
NULL, then it must be designated as anIntegerobject, not as anintprimitive. This designation is required because a Java object can beNULLbut a primitive cannot.Two strings are equal only if they contain the same sequence of characters. Trailing blanks are significant; for example, the strings
'abc'and'abc 'are not equal.Two entity beans of the same abstract schema type are equal only if their primary keys have the same value.
SELECT Clause
The
SELECTclause defines the types of the objects or values returned by the query. TheSELECTclause has the following syntax:select_clause ::= SELECT [DISTINCT] {single_valued_path_expression | OBJECT(identification_variable)}Return Types
The return type defined by the
SELECTclause must match that of the finder or select method for which the query is defined.For finder method queries, the return type of the
SELECTclause is the abstract schema type of the entity bean that defines the finder method. This abstract schema type maps to either a remote or local interface. If the bean's remote home interface defines the finder method, then the return type is the remote interface (or a collection of remote interfaces). Likewise, if the local home interface defines the finder method, the return type is the local interface (or a collection). For example, theLocalPlayerHomeinterface of thePlayerEJBentity bean defines thefindallmethod:public Collection findAll() throws FinderException;The EJB QL query of the
findallmethod returns a collection ofLocalPlayerinterface types:SELECT OBJECT(p) FROM Player pFor select method queries, the return type of the
SELECTclause may be one of the following:
- The abstract schema of the entity bean that contains the select method.
- The abstract schema of a related entity bean
- (By default, each of these abstract schema types maps to the local interface of the entity bean. Although uncommon, in the deployment descriptor you may override the default mapping by specifying a remote interface.)
- A persistent field
The
PlayerEJBentity bean, for example, implements theejbSelectSportsmethod, which returns a collection ofStringobjects forsport. Thesportis a persistent field of theLeagueEJBentity bean. See Example 11.A
SELECTclause cannot specify a collection-valued expression. For example, theSELECTclausep.teamsis invalid becauseteamsis a collection. However, theSELECTclause in the following query is valid because thetis a single element of theteamscollection:SELECT t FROM Player p, IN (p.teams) AS tDISTINCT and OBJECT Keywords
The
DISTINCTkeyword eliminates duplicate return values. If the method of the query returns ajava.util.Collection--which allows duplicates--then you must specify theDISTINCTkeyword to eliminate duplicates. However, if the method returns ajava.util.Set, theDISTINCTkeyword is redundant because ajava.util.Setmay not contain duplicates.The
OBJECTkeyword must precede a stand-alone identification variable, but it must not precede a single-valued path expression. If an identification variable is part of a single-valued path expression, it is not stand-alone.
|
Home TOC Index |
|
Search
Feedback |