このコンテンツは選択した言語では利用できません。
6.5. Query Object Model Extensions
The extensions in the JCR-SQL and JCR-SQL2 languages can also be used when building queries programmatically using the JCR Query Object Model API. The hierarchical database defines the
org.modeshape.jcr.api.query.qom.QueryObjectModelFactory interface that extends the standard javax.jcr.query.qom.QueryObjectModelFactory interface, and which contains methods providing ways to construct a QOM with the extended features.
6.5.1. Join Types リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
The standard
javax.jcr.query.qom.QueryObjectModelFactory interface uses a String to specify the join type:
package javax.jcr.query.qom;
public interface QueryObjectModelFactory {
...
/**
* Performs a join between two node-tuple sources.
*
* The query is invalid if 'left' is the same source as 'right'.
*
* @param left the left node-tuple source; non-null
* @param right the right node-tuple source; non-null
* @param joinType either QueryObjectModelConstants.JCR_JOIN_TYPE_INNER,
* QueryObjectModelConstants.JCR_JOIN_TYPE_LEFT_OUTER, or
* QueryObjectModelConstants.JCR_JOIN_TYPE_RIGHT_OUTER.
* @param joinCondition the join condition; non-null
* @return the join; non-null
* @throws InvalidQueryException if a particular validity test is possible on this method,
* the implemention chooses to perform that test (and not leave it until later,
* on {@link #createQuery}), and the parameters given fail that test
* @throws RepositoryException if the operation otherwise fails
*/
public Join join( Source left,
Source right,
String joinType,
JoinCondition joinCondition ) throws InvalidQueryException, RepositoryException;
...
}
In addition to the three standard constants, the hierarchical database supports two additional constant values:
javax.jcr.query.qom.QueryObjectModelConstants.JCR_JOIN_TYPE_INNERjavax.jcr.query.qom.QueryObjectModelConstants.JCR_JOIN_TYPE_LEFT_OUTERjavax.jcr.query.qom.QueryObjectModelConstants.JCR_JOIN_TYPE_RIGHT_OUTERorg.modeshape.jcr.api.query.qom.QueryObjectModelConstants.JCR_JOIN_TYPE_CROSSorg.modeshape.jcr.api.query.qom.QueryObjectModelConstants.JCR_JOIN_TYPE_FULL_OUTER
6.5.2. Set Operations リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
Creating a set query is very similar to creating a normal
SELECT type query, but instead the following on org.modeshape.jcr.api.query.qom.QueryObjectModelFactory are used:
package org.modeshape.jcr.api.query.qom;
public interface QueryObjectModelFactory {
...
/**
* Creates a query with one or more selectors.
*
* @param source the node-tuple source; non-null
* @param constraint the constraint, or null if none
* @param orderings zero or more orderings; null is equivalent to a zero-length array
* @param columns the columns; null is equivalent to a zero-length array
* @param limit the limit; null is equivalent to having no limit
* @param isDistinct true if the query should return distinct values; or false if no
* duplicate removal should be performed
* @return the select query; non-null
* @throws InvalidQueryException if a particular validity test is possible on this method,
* the implemention chooses to perform that test and the parameters given fail that
* test. See the individual QOM factory methods for the validity criteria
* of each query element.
* @throws RepositoryException if another error occurs.
*/
public SelectQuery select( Source source,
Constraint constraint,
Ordering[] orderings,
Column[] columns,
Limit limit,
boolean isDistinct ) throws InvalidQueryException, RepositoryException;
/**
* Creates a query command that effectively appends the results of the right-hand query
* to those of the left-hand query.
*
* @param left the query command that represents left-side of the set operation;
* non-null and must have columns that are equivalent and union-able to those
* of the right-side query
* @param right the query command that represents right-side of the set operation;
* non-null and must have columns that are equivalent and union-able to those
* of the left-side query
* @param orderings zero or more orderings; null is equivalent to a zero-length array
* @param limit the limit; null is equivalent to having no limit
* @param all true if duplicate rows in the left- and right-hand side results should
* be included, or false if duplicate rows should be eliminated
* @return the select query; non-null
* @throws InvalidQueryException if a particular validity test is possible on this method,
* the implemention chooses to perform that test and the parameters given fail
* that test. See the individual QOM factory methods for the validity criteria
* of each query element.
* @throws RepositoryException if another error occurs.
*/
public SetQuery union( QueryCommand left,
QueryCommand right,
Ordering[] orderings,
Limit limit,
boolean all ) throws InvalidQueryException, RepositoryException;
/**
* Creates a query command that returns all rows that are both in the result of the
* left-hand query and in the result of the right-hand query.
*
* @param left the query command that represents left-side of the set operation;
* non-null and must have columns that are equivalent and union-able to those
* of the right-side query
* @param right the query command that represents right-side of the set operation;
* non-null and must have columns that are equivalent and union-able to those
* of the left-side query
* @param orderings zero or more orderings; null is equivalent to a zero-length array
* @param limit the limit; null is equivalent to having no limit
* @param all true if duplicate rows in the left- and right-hand side results should
* be included, or false if duplicate rows should be eliminated
* @return the select query; non-null
* @throws InvalidQueryException if a particular validity test is possible on this method,
* the implemention chooses to perform that test and the parameters given fail
* that test. See the individual QOM factory methods for the validity criteria
* of each query element.
* @throws RepositoryException if another error occurs.
*/
public SetQuery intersect( QueryCommand left,
QueryCommand right,
Ordering[] orderings,
Limit limit,
boolean all ) throws InvalidQueryException, RepositoryException;
/**
* Creates a query command that returns all rows that are in the result of the left-hand
* query but not in the result of the right-hand query.
*
* @param left the query command that represents left-side of the set operation;
* non-null and must have columns that are equivalent and union-able to those
* of the right-side query
* @param right the query command that represents right-side of the set operation;
* non-null and must have columns that are equivalent and union-able to those
* of the left-side query
* @param orderings zero or more orderings; null is equivalent to a zero-length array
* @param limit the limit; null is equivalent to having no limit
* @param all true if duplicate rows in the left- and right-hand side results should
* be included, or false if duplicate rows should be eliminated
* @return the select query; non-null
* @throws InvalidQueryException if a particular validity test is possible on this method,
* the implemention chooses to perform that test and the parameters given fail
* that test. See the individual QOM factory methods for the validity criteria
* of each query element.
* @throws RepositoryException if another error occurs.
*/
public SetQuery except( QueryCommand left,
QueryCommand right,
Ordering[] orderings,
Limit limit,
boolean all ) throws InvalidQueryException, RepositoryException;
...
}
Note that the
select(...) method returns a SelectQuery while the union(...) , intersect(...) and except(...) methods return a SetQuery . The SelectQuery and SetQuery interfaces are defined by the hierarchical database and both extend the QueryCommand interface. This interface is then used in the methods to create SetQuery .
The
SetQuery object is not executable. To create the corresponding javax.jcr.Query object, pass the SetQuery to the following method on org.modeshape.jcr.api.query.qom.QueryObjectModelFactory :
package org.modeshape.jcr.api.query.qom;
public interface QueryObjectModelFactory {
...
/**
* Creates a set query.
*
* @param command set query; non-null
* @return the executable query; non-null
* @throws InvalidQueryException if a particular validity test is possible on this method,
* the implemention chooses to perform that test and the parameters given fail
* that test. See the individual QOM factory methods for the validity criteria
* of each query element.
* @throws RepositoryException if another error occurs.
*/
public SetQueryObjectModel createQuery( SetQuery command ) throws InvalidQueryException, RepositoryException;
...
}
The resulting
SetQueryObjectModel extends javax.jcr.query.Query and SetQuery and can be executed and treated similarly to the standard javax.jcr.query.qom.QueryObjectModel (that also extends javax.jcr.query.Query ).
6.5.4. Removing Duplicate Rows リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
The
org.modeshape.jcr.query.qom.QueryObjectModelFactory interface includes a variation of the standard QueryObjectModeFactory.select(...) method with an additional isDistinct flag that controls whether duplicate rows should be removed:
package org.modeshape.jcr.api.query.qom;
public interface QueryObjectModelFactory {
...
/**
* Creates a query with one or more selectors.
*
* @param source the node-tuple source; non-null
* @param constraint the constraint, or null if none
* @param orderings zero or more orderings; null is equivalent to a zero-length array
* @param columns the columns; null is equivalent to a zero-length array
* @param limit the limit; null is equivalent to having no limit
* @param isDistinct true if the query should return distinct values; or false if no
* duplicate removal should be performed
* @return the select query; non-null
* @throws InvalidQueryException if a particular validity test is possible on this method,
* the implemention chooses to perform that test and the parameters given fail
* that test. See the individual QOM factory methods for the validity criteria
* of each query element.
* @throws RepositoryException if another error occurs.
*/
public SelectQuery select( Source source,
Constraint constraint,
Ordering[] orderings,
Column[] columns,
Limit limit,
boolean isDistinct ) throws InvalidQueryException, RepositoryException;
...
}
6.5.5. Limit and Offset Results リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
The hierarchical database defines a
Limit interface as a top-level object that can be used to create queries that limit the number of rows and/or skip a number of initial rows:
public interface Limit {
/**
* Get the number of rows skipped before the results begin.
*
* @return the offset; always 0 or a positive number
*/
public int getOffset();
/**
* Get the maximum number of rows that are to be returned.
*
* @return the maximum number of rows; always positive, or equal to Integer.MAX_VALUE if there is no limit
*/
public int getRowLimit();
/**
* Determine whether this limit clause is necessary.
*
* @return true if the number of rows is not limited and there is no offset, or false otherwise
*/
public boolean isUnlimited();
/**
* Determine whether this limit clause defines an offset.
*
* @return true if there is an offset, or false if there is no offset
*/
public boolean isOffset();
}
These range constraints can be constructed using this
org.modeshape.jcr.query.qom.QueryObjectModelFactory method:
package org.modeshape.jcr.api.query.qom;
public interface QueryObjectModelFactory {
...
/**
* Evaluates to a limit on the maximum number of tuples in the results and the
* number of rows that are skipped before the first tuple in the results.
*
* @param rowLimit the maximum number of rows; must be a positive number, or Integer.MAX_VALUE if there is to be a
* non-zero offset but no limit
* @param offset the number of rows to skip before beginning the results; must be 0 or a positive number
* @return the operand; non-null
* @throws InvalidQueryException if a particular validity test is possible on this method,
* the implemention chooses to perform that test (and not leave it until later, on createQuery),
* and the parameters given fail that test
* @throws RepositoryException if the operation otherwise fails
*/
public Limit limit( int rowLimit,
int offset ) throws InvalidQueryException, RepositoryException;
...
}
The
Limit objects can then be used when creating queries using a variation of the standard QueryObjectModeFactory.select(...) defined in the org.modeshape.jcr.query.qom.QueryObjectModelFactory interface:
package org.modeshape.jcr.api.query.qom;
public interface QueryObjectModelFactory {
...
/**
* Creates a query with one or more selectors.
*
* @param source the node-tuple source; non-null
* @param constraint the constraint, or null if none
* @param orderings zero or more orderings; null is equivalent to a zero-length array
* @param columns the columns; null is equivalent to a zero-length array
* @param limit the limit; null is equivalent to having no limit
* @param isDistinct true if the query should return distinct values; or false if no
* duplicate removal should be performed
* @return the select query; non-null
* @throws InvalidQueryException if a particular validity test is possible on this method,
* the implemention chooses to perform that test and the parameters given fail
* that test. See the individual QOM factory methods for the validity criteria
* of each query element.
* @throws RepositoryException if another error occurs.
*/
public SelectQuery select( Source source,
Constraint constraint,
Ordering[] orderings,
Column[] columns,
Limit limit,
boolean isDistinct ) throws InvalidQueryException, RepositoryException;
...
}
Similarly, the
Limit objects can be passed to the hierarchical database except(...) , union(...) , intersect(...) methods, too.
6.5.6. Depth Constraints リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
The hierarchical database defines a
DepthPath interface that extends the standard javax.jcr.query.qom.DynamicOperand interface, and thus can be used as part of a WHERE clause to constrain the depth of the nodes accessed by a selector:
public interface NodeDepth extends javax.jcr.query.qom.DynamicOperand {
/**
* Get the selector symbol upon which this operand applies.
*
* @return the one selector names used by this operand; never null
*/
public String getSelectorName();
}
These range constraints can be constructed using this
org.modeshape.jcr.query.qom.QueryObjectModelFactory method:
package org.modeshape.jcr.api.query.qom;
public interface QueryObjectModelFactory {
...
/**
* Evaluates to a LONG value equal to the depth of a node in the specified selector.
*
* The query is invalid if selector is not the name of a selector in the query.
*
* @param selectorName the selector name; non-null
* @return the operand; non-null
* @throws InvalidQueryException if a particular validity test is possible on this method,
* the implemention chooses to perform that test (and not leave it until later, on createQuery),
* and the parameters given fail that test
* @throws RepositoryException if the operation otherwise fails
*/
public NodeDepth nodeDepth( String selectorName ) throws InvalidQueryException, RepositoryException;
...
}
6.5.7. Path Constraints リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
The hierarchical database defines a
NodePath interface that extends the standard javax.jcr.query.qom.DynamicOperand interface, and thus can be used as part of a WHERE clause to constrain the path of nodes accessed by a selector:
public interface NodePath extends javax.jcr.query.qom.DynamicOperand {
/**
* Get the selector symbol upon which this operand applies.
*
* @return the one selector names used by this operand; never null
*/
public String getSelectorName();
}
These range constraints can be constructed using this
org.modeshape.jcr.query.qom.QueryObjectModelFactory method:
package org.modeshape.jcr.api.query.qom;
public interface QueryObjectModelFactory {
...
/**
* Evaluates to a PATH value equal to the prefix-qualified path of a node in the specified selector.
*
* The query is invalid if selector is not the name of a selector in the query.
*
* @param selectorName the selector name; non-null
* @return the operand; non-null
* @throws InvalidQueryException if a particular validity test is possible on this method,
* the implemention chooses to perform that test (and not leave it until later, on createQuery),
* and the parameters given fail that test
* @throws RepositoryException if the operation otherwise fails
*/
public NodePath nodePath( String selectorName ) throws InvalidQueryException, RepositoryException;
...
}
6.5.8. Criteria on References From a Node リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
The hierarchical database defines a
ReferenceValue interface that extends the standard javax.jcr.query.qom.DynamicOperand interface, and thus can be used as part of a WHERE or ORDER BY clause:
public interface ReferenceValue extends DynamicOperand {
...
/**
* Get the selector symbol upon which this operand applies.
*
* @return the one selector names used by this operand; never null
*/
public String getSelectorName();
/**
* Get the name of the one reference property.
*
* @return the property name; or null if this operand applies to any reference property
*/
public String getPropertyName();
}
These reference value operand allow a query to easily place constraints on a particular REFERENCE property or (more importantly) any REFERENCE properties on the nodes. The former is a more simple alternative to using a regular comparison constraint with the REFERENCE property on one side and the
jcr:uuid property on the other. The latter effectively means "where the node references (with any property) some other nodes", and this is something that standard JCR-SQL2 cannot represent.
They are created using these
org.modeshape.jcr.query.qom.QueryObjectModelFactory methods:
package org.modeshape.jcr.api.query.qom;
public interface QueryObjectModelFactory {
...
/**
* Creates a dynamic operand that evaluates to the REFERENCE value of the any property
* on the specified selector.
*
* The query is invalid if:
* - selector is not the name of a selector in the query, or
* - property is not a syntactically valid JCR name.
*
* @param selectorName the selector name; non-null
* @return the operand; non-null
* @throws InvalidQueryException if a particular validity test is possible on this method,
* the implemention chooses to perform that test (and not leave it until later, on createQuery),
* and the parameters given fail that test
* @throws RepositoryException if the operation otherwise fails
*/
public ReferenceValue referenceValue( String selectorName ) throws InvalidQueryException, RepositoryException;
/**
* Creates a dynamic operand that evaluates to the REFERENCE value of the specified
* property on the specified selector.
*
* The query is invalid if:
* - selector is not the name of a selector in the query, or
* - property is not a syntactically valid JCR name.
*
* @param selectorName the selector name; non-null
* @param propertyName the reference property name; non-null
* @return the operand; non-null
* @throws InvalidQueryException if a particular validity test is possible on this method,
* the implemention chooses to perform that test (and not leave it until later, on createQuery),
* and the parameters given fail that test
* @throws RepositoryException if the operation otherwise fails
*/
public ReferenceValue referenceValue( String selectorName,
String propertyName ) throws InvalidQueryException, RepositoryException;
...
}
6.5.9. Range Criteria リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
The hierarchical database defines a
Between interface that extends the standard javax.jcr.query.qom.Constraint interface, and thus can be used as part of a WHERE clause:
public interface Between extends Constraint {
/**
* Get the dynamic operand specification.
*
* @return the dynamic operand; never null
*/
public DynamicOperand getOperand();
/**
* Get the lower bound operand.
*
* @return the lower bound; never null
*/
public StaticOperand getLowerBound();
/**
* Get the upper bound operand.
*
* @return the upper bound; never null
*/
public StaticOperand getUpperBound();
/**
* Return whether the lower bound is to be included in the results.
*
* @return true if the {@link #getLowerBound() lower bound} is to be included, or false otherwise
*/
public boolean isLowerBoundIncluded();
/**
* Return whether the upper bound is to be included in the results.
*
* @return true if the {@link #getUpperBound() upper bound} is to be included, or false otherwise
*/
public boolean isUpperBoundIncluded();
}
These range constraints can be constructed using this
org.modeshape.jcr.query.qom.QueryObjectModelFactory method:
package org.modeshape.jcr.api.query.qom;
public interface QueryObjectModelFactory {
...
/**
* Tests that the value (or values) defined by the supplied dynamic operand are
* within a specified range. The range is specified by a lower and upper bound,
* and whether each of the boundary values is included in the range.
*
* @param operand the dynamic operand describing the values that are to be constrained
* @param lowerBound the lower bound of the range
* @param upperBound the upper bound of the range
* @param includeLowerBound true if the lower boundary value is not be included
* @param includeUpperBound true if the upper boundary value is not be included
* @return the constraint; non-null
* @throws InvalidQueryException if a particular validity test is possible on this method,
* the implemention chooses to perform that test (and not leave it until later, on createQuery),
* and the parameters given fail that test
* @throws RepositoryException if the operation otherwise fails
*/
public Between between( DynamicOperand operand,
StaticOperand lowerBound,
StaticOperand upperBound,
boolean includeLowerBound,
boolean includeUpperBound ) throws InvalidQueryException, RepositoryException;
...
}
To create a
NOT BETWEEN ... criteria, create the Between criteria object, and then pass that into the standard QueryObjectModelFactory.not(Criteria) method.
6.5.10. Set Criteria リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
The hierarchical database defines a
SetCriteria interface that extends the standard javax.jcr.query.qom.Constraint interface, and thus can be used as part of a WHERE clause:
public interface SetCriteria extends Constraint {
/**
* Get the dynamic operand specification for the left-hand side of the set criteria.
*
* @return the dynamic operand; never null
*/
public DynamicOperand getOperand();
/**
* Get the static operands for this set criteria.
*
* @return the static operand; never null and never empty
*/
public Collection<? extends StaticOperand> getValues();
}
These set constraints can be constructed using this
org.modeshape.jcr.query.qom.QueryObjectModelFactory method:
package org.modeshape.jcr.api.query.qom;
public interface QueryObjectModelFactory {
...
/**
* Tests that the value (or values) defined by the supplied dynamic operand are
* found within the specified set of values.
*
* @param operand the dynamic operand describing the values that are to be constrained
* @param values the static operand values; may not be null or empty
* @return the constraint; non-null
* @throws InvalidQueryException if a particular validity test is possible on this method,
* the implemention chooses to perform that test (and not leave it until later, on createQuery),
* and the parameters given fail that test
* @throws RepositoryException if the operation otherwise fails
*/
public SetCriteria in( DynamicOperand operand,
StaticOperand... values ) throws InvalidQueryException, RepositoryException;
...
}
To create a
NOT IN criteria, create the IN criteria to get a SetCriteria object, and then pass that into the standard QueryObjectModelFactory.not(Criteria) method.
6.5.11. Arithmetic Operands リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
The hierarchical database defines an
ArithmeticOperand interface that extends the javax.jcr.query.qom.DynamicOperand , and thus can be used anywhere a DynamicOperand can be used.
public interface ArithmeticOperand extends DynamicOperand {
/**
* Get the operator for this binary operand.
*
* @return the operator; never null
*/
public String getOperator();
/**
* Get the left-hand operand.
*
* @return the left-hand operator; never null
*/
public DynamicOperand getLeft();
/**
* Get the right-hand operand.
*
* @return the right-hand operator; never null
*/
public DynamicOperand getRight();
}
These can be constructed using additional
org.modeshape.jcr.query.qom.QueryObjectModelFactory methods:
package org.modeshape.jcr.api.query.qom;
public interface QueryObjectModelFactory {
...
/**
* Create an arithmetic dynamic operand that adds the numeric value of the two supplied operand(s).
*
* @param left the left-hand-side operand; not null
* @param right the right-hand-side operand; not null
* @return the dynamic operand; non-null
* @throws InvalidQueryException if a particular validity test is possible on this method,
* the implemention chooses to perform that test (and not leave it until later, on createQuery),
* and the parameters given fail that test
* @throws RepositoryException if the operation otherwise fails
*/
public ArithmeticOperand add( DynamicOperand left,
DynamicOperand right ) throws InvalidQueryException, RepositoryException;
/**
* Create an arithmetic dynamic operand that subtracts the numeric value of the second operand from the numeric value of the
* first.
*
* @param left the left-hand-side operand; not null
* @param right the right-hand-side operand; not null
* @return the dynamic operand; non-null
* @throws InvalidQueryException if a particular validity test is possible on this method,
* the implemention chooses to perform that test (and not leave it until later, on createQuery),
* and the parameters given fail that test
* @throws RepositoryException if the operation otherwise fails
*/
public ArithmeticOperand subtract( DynamicOperand left,
DynamicOperand right ) throws InvalidQueryException, RepositoryException;
/**
* Create an arithmetic dynamic operand that multplies the numeric value of the first operand by the numeric value of the
* second.
*
* @param left the left-hand-side operand; not null
* @param right the right-hand-side operand; not null
* @return the dynamic operand; non-null
* @throws InvalidQueryException if a particular validity test is possible on this method,
* the implemention chooses to perform that test (and not leave it until later, on createQuery),
* and the parameters given fail that test
* @throws RepositoryException if the operation otherwise fails
*/
public ArithmeticOperand multiply( DynamicOperand left,
DynamicOperand right ) throws InvalidQueryException, RepositoryException;
/**
* Create an arithmetic dynamic operand that divides the numeric value of the first operand by the numeric value of the
* second.
*
* @param left the left-hand-side operand; not null
* @param right the right-hand-side operand; not null
* @return the dynamic operand; non-null
* @throws InvalidQueryException if a particular validity test is possible on this method,
* the implemention chooses to perform that test (and not leave it until later, on createQuery),
* and the parameters given fail that test
* @throws RepositoryException if the operation otherwise fails
*/
public ArithmeticOperand divide( DynamicOperand left,
DynamicOperand right ) throws InvalidQueryException, RepositoryException;
...
}