Este conteúdo não está disponível no idioma selecionado.
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 Copiar o linkLink copiado para a área de transferência!
Copiar o linkLink copiado para a área de transferência!
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 Copiar o linkLink copiado para a área de transferência!
Copiar o linkLink copiado para a área de transferência!
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 Copiar o linkLink copiado para a área de transferência!
Copiar o linkLink copiado para a área de transferência!
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 Copiar o linkLink copiado para a área de transferência!
Copiar o linkLink copiado para a área de transferência!
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 Copiar o linkLink copiado para a área de transferência!
Copiar o linkLink copiado para a área de transferência!
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 Copiar o linkLink copiado para a área de transferência!
Copiar o linkLink copiado para a área de transferência!
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 Copiar o linkLink copiado para a área de transferência!
Copiar o linkLink copiado para a área de transferência!
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 Copiar o linkLink copiado para a área de transferência!
Copiar o linkLink copiado para a área de transferência!
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 Copiar o linkLink copiado para a área de transferência!
Copiar o linkLink copiado para a área de transferência!
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 Copiar o linkLink copiado para a área de transferência!
Copiar o linkLink copiado para a área de transferência!
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;
...
}