Recuperando Entidades e Objetos (API de Consulta)

O WebSphere eXtreme Scale fornece um mecanismo de consulta flexível para recuperar entidades usando a API do EntityManager e objetos Java usando a API do ObjectQuery.

Recursos de Consulta do WebSphere eXtreme Scale

Com o mecanismo de consulta do eXtreme Scale, é possível executar consultas do tipo SELECT sobre uma entidade ou esquema baseado em objeto usando a linguagem de consulta do eXtreme Scale.

Esta linguagem de consulta fornece os seguintes recursos:

Interface de Consulta

Utilize a interface de consulta para controlar a execução da consulta da entidade de controle.

Utilize o método EntityManager.createQuery(String) para criar uma Query. É possível usar cada instância de consulta múltiplas vezes com a instância de EntityManager na qual ela foi recuperada.

Cada resultado da consulta produz uma entidade na qual a chave da entidade é o ID da linha (do tipo longo) e o valor da entidade contém os resultados do campo da cláusula SELECT. É possível usar cada resultado da consulta em consultas subsequentes.

Os seguintes métodos estão disponíveis na interface com.ibm.websphere.objectgrid.em.Query.

public ObjectMap getResultMap()

O método getResultMap executa uma consulta SELECT e retorna os resultados em um objeto ObjectMap com os resultados na ordem especificada pela consulta. O ObjectMap resultante é válido apenas para a transação atual.

A chave do mapa é o número de resultado, do tipo long, iniciando em 1. O valor do mapa é do tipo com.ibm.websphere.projector.Tuple, em que cada atributo e associação é nomeado com base em sua posição ordinal dentro da cláusula select da consulta. Utilize o método para recuperar o EntityMetadata para o objeto Tupla armazenado dentro do mapa.

O método getResultMap é o mais rápido para recuperar dados do resultado da consulta nas qual múltiplos resultados podem existir. É possível recuperar o nome da entidade resultante usando os métodos ObjectMap.getEntityMetadata() e EntityMetadata.getName().

Exemplo: A seguinte consulta retorna duas linhas.

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

O método getResultIterator executa uma consulta SELECT e retorna os resultados da consulta usando um Agente iterativo no qual cada resultado é um Objeto para uma consulta com valor único, ou uma matriz de Objetos para uma consulta com múltiplos valores. Os valores no resultado são armazenados na ordem da consulta. O Iterator de resultado é válido apenas para a transação atual.

Este método é preferencial para recuperar resultados da consulta dentro do contexto de EntityManager. É possível utilizar o método setResultEntityName(String) opcional para nomear a entidade resultante, para que ela possa ser utilizada em consultas adicionais.

Exemplo: A seguinte consulta retorna duas linhas.

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)

O método getResultIterator(Class resultType) executa uma consulta SELECT e retorna os resultados da consulta usando um Agente Iterativo da entidade. O tipo de entidade é determinado pelo parâmetro resultType. O Iterator de resultado é válido apenas para a transação atual.

Utilize esse método quando você quiser utilizar as APIs EntityManager para acessar as entidades resultantes.

Exemplo: A consulta a seguir retorna todos os funcionários e o departamento ao qual pertencem para uma divisão, com classificação por salário. Para imprimir os cinco funcionários com os salários mais altos e, então, selecionar o trabalho com funcionários de apenas um departamento no mesmo conjunto de trabalhos, utilize o seguinte código.

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();			
	System.out.println(curEmp);
	// Remove the employee from the resultset.
	em.remove(curEmp);
}

// 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();			
	System.out.println(curEmp);
}

public Object getSingleResult

O método getSingleResult executa uma consulta SELECT que retorna um único resultado.

Se a cláusula SELECT tiver mais de um campo definido, então o resultado é uma matriz de objetos, na qual cada elemento na matriz se baseia em sua posição original dentro da cláusula SELECT da consulta.

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)

O método setResultEntityName(String entityName) especifica o nome da entidade do resultado da consulta.

Toda vez que os métodos getResultIterator ou getResultMap são chamados, uma entidade com um ObjectMap é dinamicamente criada para manter os resultados da consulta. Se a entidade não for especificada, ou estiver nula, a entidade e o nome do ObjectMap serão automaticamente gerados.

Como todos os resultados da consulta estão disponíveis para a duração de uma transação, um nome de consulta não pode ser reutilizado em uma única transação.

public Query setPartition(int partitionId)

Configure a partição para onde é roteada a consulta.

Este método é necessário se os mapas na consulta estão particionados e se o gerenciador de entidades não tem afinidade com uma partição da entidade-raiz do esquema único.

Use a Interface PartitionManager para determinar o número de partições para o mapa de apoio de uma determinada entidade.

A tabela a seguir fornece descrições dos outros métodos que estão disponíveis por meio da interface da consulta.

Tabela 1. Outros Métodos
Método Resultado
public Query setMaxResults(int maxResult) Configure o número máximo de resultados para recuperar.
public Query setFirstResult(int startPosition) Configure a posição do primeiro resultado para recuperar.
public Query setParameter(String name, Object value) Ligue um argumento a um parâmetro nomeado.
public Query setParameter(int position, Object value) Ligue um argumento a um parâmetro posicional.
public Query setFlushMode(FlushModeType flushMode) Configure o tipo de modo de limpeza a ser utilizado quando a consulta for executada, substituindo esse tipo de modo configurado no EntityManager.

Elementos de Consulta do eXtreme Scale

Com o mecanismo de consulta do eXtreme Scale, é possível utilizar uma linguagem de consulta única para procurar o cache do eXtreme Scale. Esta linguagem de consulta pode consultar objetos Java que são armazenados em objetos ObjectMap e objetos Entity. Utilize a sintaxe a seguir para criar uma cadeia de consultas.

Uma consulta do eXtreme Scale é uma cadeia que contém os seguintes elementos:
  • Uma cláusula SELECT que especifica os objetos ou valores a retornar.
  • Uma cláusula FROM que nomeia as coletas de objeto.
  • Uma cláusula WHERE opcional que contém predicados de procura sobre as coletas.
  • Uma cláusula GROUP BY e HAVING (consulte as funções de agregação de consulta do eXtreme Scale).
  • Uma cláusula ORDER BY opcional que especifica a classificação da coleta de resultados.

Conjuntos de objetos Java são identificados em consultas por meio do uso de seu nome na cláusula FROM da consulta.

Os elementos da linguagem de consulta são discutidos em mais detalhes nos tópicos relacionados a seguir:
Os tópicos a seguir descrevem os meios para usar a API de Consulta: