[Java programming language only]

检索实体和对象(查询 API)

WebSphere® eXtreme Scale 提供了一个灵活的查询引擎,用于使用 EntityManager API 检索实体,以及使用 ObjectQuery API 检索 Java™ 对象。

WebSphere eXtreme Scale 查询功能

借助 eXtreme Scale 查询引擎,您可以使用 eXtreme Scale 查询语言对基于实体或基于对象的模式执行 SELECT 类型查询。

此查询语言提供了以下功能:

查询接口

使用查询接口以控制实体查询执行。

使用 EntityManager.createQuery(String) 方法来创建查询。您可以将每个查询实例多次与在其中检索此实例的 EntityManager 实例配合使用。

每个查询结果生成实体,其中实体键为行标识(长整型),实体值包含 SELECT 子句的字段结果。您可以在后续查询中使用每个查询结果。

以下方法可用于 com.ibm.websphere.objectgrid.em.Query 接口。

public ObjectMap getResultMap()

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 接口来确定给定实体的备份映射的分区数。

下表提供通过查询接口可用的其他方法的描述。

表 1. 其他方法。
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 查询引擎,您可以使用单个查询语言来搜索 eXtreme Scale 高速缓存。此查询语言可查询在 ObjectMap 对象和实体对象中存储的 Java 对象。使用以下语法来创建查询字符串。

eXtreme Scale 查询是字符串,包含以下元素:
  • 指定要返回的对象或值的 SELECT 子句。
  • 指定对象集合的 FROM 子句。
  • 包含集合中搜索谓词的可选 WHERE 子句。
  • 可选 GROUP BY 和 HAVING 子句(请参阅 eXtreme Scale 查询聚集函数)。
  • 指定结果集合的顺序的可选 ORDER BY 子句。

Java 对象的集合是通过在查询 FROM 子句中使用其名称在查询中进行标识的。

在以下相关主题中,对查询语言的元素进行了更详细的讨论:
以下主题描述使用查询 API 的方法: