WHERE 子句中的表达式
WHERE 子句表达式的最常见类型是 SearchCondition。但是,也可以使用其他表达式。以下 API 支持 WHERE 子句中的表达式:
appendWhere(WhereExpression a_expression, int[] a_fromIndicies)
appendWhere(WhereExpression a_expression, TableExpression[] a_tableExpressions, String[] a_aliases)
以下是具体的 WhereExpression 实现:
SearchCondition
|
此类表示查询的搜索条件。附加到 QuerySpec 时,将在 SQL WHERE 子句中使用这些值。
|
ExistsExpression
|
此类表示 WHERE 子句中的 EXISTS 表达式。StatementSpec 实例用于子选择。
|
CompositeWhereExpression
|
此类表示使用逻辑运算符 (即 AND/OR) 连接的多个 WHERE 表达式。
|
NegatedExpression
|
此类表示 WHERE 子句中表达式的取反。此类包含汇总的 WhereExpression,在计算此表达式时,其前缀为 NOT。
|
fromIndices 参数用于将 WHERE 表达式运算对象与 FROM 子句中的表格相关联。与 appendSelect() 方法类似,fromIndices 数组基于 WhereExpressions 中使用的 WhereExpression 和 ColumnExpressions 的类型。例如,带有 ClassAttribute 和 ConstantExpression 的 SearchCondition 将需要单个 from 索引。包含三个 SearchConditions 的 CompositeWhereExpression 将需要 fromIndices 数组,其大小等于每个 SearchCondition 所需大小的总和。
以下示例演示了 fromIndices 的正确用法。此代码将查询部件及其关联的替换部件。与多个条件一起使用的复合 where 表达式:关联部件编号的第二到第四个字符相同,部件名称以 "E" 开头,或替换部件名称以 "E" 开头。代码的第一部分设置查询中的类、选择项以及类之间的联接。
QuerySpec qs = new QuerySpec();
int partIndex = qs.appendClassList(wt.part.WTPartMaster.class, false);
int alternatePartIndex = qs.appendClassList(wt.part.WTPartMaster.class, false);
int linkIndex = qs.appendClassList(wt.part.WTPartAlternateLink.class, false);
// Define the attributes in the query
ClassAttribute partName =
new ClassAttribute(wt.part.WTPartMaster.class,
wt.part.WTPartMaster.NAME);
ClassAttribute alternatePartName =
new ClassAttribute(wt.part.WTPartMaster.class,
wt.part.WTPartMaster.NAME);
ClassAttribute partNumber =
new ClassAttribute(wt.part.WTPartMaster.class,
wt.part.WTPartMaster.NUMBER);
ClassAttribute alternatePartNumber =
new ClassAttribute(wt.part.WTPartMaster.class,
wt.part.WTPartMaster.NUMBER);
// Define constants used in the criteria
ConstantExpression subStringStart = new ConstantExpression(new Long(2));
ConstantExpression subStringEnd = new ConstantExpression(new Long(4));
ConstantExpression wildcardExpression = new ConstantExpression("E% [ ]");
// Add items to the select and join the classes
qs.appendSelect(partName, new int[] { 0 }, false);
qs.appendSelect(alternatePartName, new int[] { 1 }, false);
qs.appendJoin(linkIndex, wt.part.WTPartAlternateLink.ALTERNATES_ROLE, partIndex);
qs.appendJoin(linkIndex, wt.part.WTPartAlternateLink.ALTERNATE_FOR_ROLE,
alternatePartIndex);
在下一部分中,构造条件并将其附加到查询中。请注意,第一个 SearchCondition 使用两个 ClassAttribute 实例。必须将相应的索引添加到 appendWhere 中使用的 fromIndices 数组中。同样,第二个 SearchCondition 参考部件类,第三个 SearchCondition 参考替换部件类。因此,需要四个 fromIndices,并且每个数组元素必须对应于适当的 SearchCondition。
CompositeWhereExpression orExpression =
new CompositeWhereExpression(LogicalOperator.OR);
orExpression.append(new SearchCondition(
SQLFunction.newSQLFunction(SQLFunction.SUB_STRING,
partNumber, subStringStart, subStringEnd),
SearchCondition.EQUAL,
SQLFunction.newSQLFunction(SQLFunction.SUB_STRING,
alternatePartNumber, subStringStart, subStringEnd)));
orExpression.append(new SearchCondition(
partName, SearchCondition.LIKE, wildcardExpression));
orExpression.append(new SearchCondition(
alternatePartName, SearchCondition.LIKE, wildcardExpression));
qs.appendWhere(orExpression, new int[] {
partIndex, alternatePartIndex, partIndex, alternatePartIndex });
最后一个 API 为 WHERE 表达式运算对象显式指定表格表达式和别名。此 API 用于相关子选择。使用子选择时,通常会使用相关列 (即外部选择中的列与子选择中的列之间的联接)。使用 appendWhere() API 对此提供了支持,其中显式传递了 TableExpressions 和别名。对于不涉及子选择的 WhereExpressions,TableExpressions 和别名是使用 QuerySpec FROM 子句和指定的索引隐式派生的。
以下示例使用 EXISTS 子句和相关子选择构建查询。查询将返回所有不存在替换 PartMaster 的 PartMasters。替换项由 WTPartAlternateLink 类表示,该类是 PartMasters 之间的多对多关联。WTPartAlternateLink 类的角色 A 指定当前的 PartMaster,角色 B 指定替换 PartMaster。以下是此查询的 SQL:
SELECT A0.*
FROM WTPartMaster A0
WHERE NOT (EXISTS (SELECT B0.ida2a2
FROM WTPartAlternateLink B0
WHERE (A0.ida2a2 = B0.ida3a5)))
以下代码将构造查询规范。外部选择将返回 PartMaster 对象。
QuerySpec select = new QuerySpec();
int partIndex = select.appendClassList(wt.part.WTPartMaster.class, true);
以下代码将构造子选择。别名前缀已更改,以避免与外部选择发生冲突。
QuerySpec subSelect = new QuerySpec();
subSelect.getFromClause().setAliasPrefix("B");
int altIndex = subSelect.appendClassList(wt.part.WTPartAlternateLink.class,
false);
subSelect.appendSelect(new ClassAttribute(
wt.part.WTPartAlternateLink.class, WTAttributeNameIfc.ID_NAME),
new int[] { altIndex }, true);
以下代码显式设置 TableExpressions 和别名,它们作为数组传递。联接将从外部选择到子选择,因此将外部选择值放置在索引为 0 的数组中,并将子选择值放置在索引为 1 的数组中。然后使用数组附加 SearchCondition。
TableExpression[] tables = new TableExpression[2];
String[] aliases = new String[2];
tables[0] = select.getFromClause().getTableExpressionAt(partIndex);
aliases[0] = select.getFromClause().getAliasAt(partIndex);
tables[1] = subSelect.getFromClause().getTableExpressionAt(altIndex);
aliases[1] = subSelect.getFromClause().getAliasAt(altIndex);
SearchCondition correlatedJoin = new SearchCondition(
wt.part.WTPartMaster.class, WTAttributeNameIfc.ID_NAME,
wt.part.WTPartAlternateLink.class,WTAttributeNameIfc.ROLEA_OBJECT_ID);
subSelect.appendWhere(correlatedJoin, tables, aliases);
最后,将取反的 EXISTS 子句附加到外部选择。
select.appendWhere(new NegatedExpression(new
ExistsExpression(subSelect)), null);