WebSphere® eXtreme Scale 提供了一个灵活的查询引擎,用于使用 EntityManager API 检索实体,以及使用 ObjectQuery API 检索 Java™ 对象。
借助 eXtreme Scale 查询引擎,您可以使用 eXtreme Scale 查询语言对基于实体或基于对象的模式执行 SELECT 类型查询。
此查询语言提供了以下功能:
使用查询接口以控制实体查询执行。
使用 EntityManager.createQuery(String) 方法来创建查询。您可以将每个查询实例多次与在其中检索此实例的 EntityManager 实例配合使用。
每个查询结果生成实体,其中实体键为行标识(长整型),实体值包含 SELECT 子句的字段结果。您可以在后续查询中使用每个查询结果。
以下方法可用于 com.ibm.websphere.objectgrid.em.Query 接口。
getResultMap 方法运行 SELECT 查询,并以指定查询的顺序在 ObjectMap 对象中返回结果。生成的 ObjectMap 仅对当前事务有效。
映射键是结果数,长整型,且以 1 开始。映射值类型为 com.ibm.websphere.projector.Tuple,其中,基于其在查询的 SELECT 子句中的有序位置命名每个属性和关联。使用此方法来检索存储在映射中的 Tuple 对象的 EntityMetadata。
getResultMap 方法是检索其中可能存在多个结果的查询结果数据的最快方法。您可以使用 ObjectMap.getEntityMetadata() 和 EntityMetadata.getName() 方法检索生成的实体的名称。
示例:以下查询返回两行。
String ql = SELECT e.name, e.id, d from Employee e join e.dept d WHERE d.number=5
Query q = em.createQuery(ql);
ObjectMap resultMap = q.getResultMap();
long rowID = 1; // starts with index 1
Tuple tResult = (Tuple) resultMap.get(new Long(rowID));
while(tResult != null) {
// The first attribute is name and has an attribute name of 1
// But has an ordinal position of 0.
String name = (String)tResult.getAttribute(0);
Integer id = (String)tResult.getAttribute(1);
// Dept is an association with a name of 3, but
// an ordinal position of 0 since it's the first association.
// The association is always a OneToOne relationship,
// so there is only one key.
Tuple deptKey = tResult.getAssociation(0,0);
...
++rowID;
tResult = (Tuple) resultMap.get(new Long(rowID));
}
public Iterator getResultIterator
getResultIterator 方法运行 SELECT 查询并使用 Iterator 返回查询结果,其中,每个结果为单值查询的对象或多值查询的对象数组。 Object[] 结果中的值以查询顺序进行存储。结果 Iterator 仅对于当前事务有效。
此方法是在 EntityManager 上下文中检索查询结果的首选方法。您可以使用可选的 setResultEntityName(String) 方法来命名生成的实体,以便可以在将来查询中使用。
示例:以下查询返回两行。
String ql = SELECT e.name, e.id, e.dept from Employee e WHERE e.dept.number=5
Query q = em.createQuery(ql);
Iterator results = q.getResultIterator();
while(results.hasNext()) {
Object[] curEmp = (Object[]) results.next();
String name = (String) curEmp[0];
Integer id = (Integer) curEmp[1];
Dept d = (Dept) curEmp[2];
...
}
public Iterator getResultIterator(Class resultType)
getResultIterator(Class resultType) 方法运行 SELECT 查询并使用 Iterator 返回查询结果。实体类型由 resultType 参数确定。结果 Iterator 仅对于当前事务有效。
当您希望使用 EntityManager API 来访问生成的实体时,使用此方法。
示例:以下查询返回所有员工及其在一个分公司中所属的部门,且按薪水排序。要打印五位具有最高薪水的员工,然后选择仅与来自一个部门的相同工作集中的员工一起工作,请使用以下代码。
String string_ql = "SELECT e.name, e.id, e.dept from Employee e WHERE
e.dept.division='Manufacturing' ORDER BY e.salary DESC";
Query query1 = em.createQuery(string_ql);
query1.setResultEntityName("AllEmployees");
Iterator results1 = query1.getResultIterator(EmployeeResult.class);
int curEmployee = 0;
System.out.println("Highest paid employees");
while (results1.hasNext() && curEmployee++ < 5) {
EmployeeResult curEmp = (EmployeeResult) results1.next();
connSpec.setWriteToMultiplePartitions(true);
// Remove the employee from the resultset.
connSpec.setWriteToMultiplePartitions(true);
}
// Flush the changes to the result map.
em.flush();
// Run a query against the local working set without the employees we
// removed
String string_q2 = "SELECT e.name, e.id, e.dept from AllEmployees e
WHERE e.dept.name='Hardware'";
Query query2 = em.createQuery(string_q2);
Iterator results2 = query2.getResultIterator(EmployeeResult.class);
System.out.println("Subset list of Employees");
while (results2.hasNext()) {
EmployeeResult curEmp = (EmployeeResult) results2.next();
connSpec.setWriteToMultiplePartitions(true);
}
public Object getSingleResult
getSingleResult 方法运行 SELECT 查询,此查询返回单个结果。
如果 SELECT 子句定义了多个字段,那么结果为对象数组,其中,数组中的每个元素基于其在查询的 SELECT 子句中的有序位置。
String ql = SELECT e from Employee e WHERE e.id=100"
Employee e = em.createQuery(ql).getSingleResult();
String ql = SELECT e.name, e.dept from Employee e WHERE e.id=100"
Object[] empData = em.createQuery(ql).getSingleResult();
String empName= (String) empData[0];
Department empDept = (Department) empData[1];
public Query setResultEntityName(String entityName)
setResultEntityName(String entityName) 方法指定查询结果实体的名称。
每次调用 getResultIterator 或 getResultMap 方法时,会动态创建具有 ObjectMap 的实体来保存查询的结果。如果未指定实体,或实体为空,那么会自动生成实体和 ObjectMap 名称。
由于所有查询结果在事务期间均可用,因此查询名称不能在单个事务中复用。
public Query setPartition(int partitionId)
将分区设置为查询路由的位置。
如果查询中的映射进行了分区,且实体管理器不具有对单个模式根实体分区的亲缘关系,那么此方法为必需。
使用 PartitionManager 接口来确定给定实体的备份映射的分区数。
下表提供通过查询接口可用的其他方法的描述。
| Method | 结果 |
|---|---|
| public Query setMaxResults(int maxResult) | 设置要检索的最大结果数。 |
| public Query setFirstResult(int startPosition) | 设置要检索的第一个结果的位置。 |
| public Query setParameter(String name, Object value) | 将参数绑定至指定的参数。 |
| public Query setParameter(int position, Object value) | 将参数绑定至位置参数。 |
| public Query setFlushMode(FlushModeType flushMode) | 设置在查询运行时要使用的刷新方式类型,同时覆盖在 EntityManager 上设置的刷新方式类型。 |
借助 eXtreme Scale 查询引擎,您可以使用单个查询语言来搜索 eXtreme Scale 高速缓存。此查询语言可查询在 ObjectMap 对象和实体对象中存储的 Java 对象。使用以下语法来创建查询字符串。
Java 对象的集合是通过在查询 FROM 子句中使用其名称在查询中进行标识的。