Extraction d'entités et d'objets (API Query)

WebSphere eXtreme Scale fournit un moteur de requête flexible permettant d'extraire des entités à l'aide de l'API EntityManager et les objets Java utilisant l'API ObjectQuery.

Fonctions de requête WebSphere eXtreme Scale

Avec le moteur de requête eXtreme Scale, vous pouvez exécuter des requêtes de type SELECT sur une entité ou un schéma basé sur un objet à l'aide du langage de requête de l'eXtreme Scale.

Ce langage de requête inclut les fonctions suivantes :

Interface de requête

Utilisez l'interface de requête pour contrôler l'exécution des requêtes d'entité.

La méthode EntityManager.createQuery(String) permet de créer une requête. Vous pouvez faire appel à chaque instance de requête plusieurs fois à l'aide de l'instance EntityManager dans laquelle elle a été extraite.

Chaque résultat de requête produit une entité où la clé d'entité correspond à l'ID de ligne (de type long) et la valeur d'entité contient les résultats de zone de la clause SELECT. Vous pouvez utiliser chaque résultat de requête dans les requêtes ultérieures.

Les méthodes suivantes sont disponibles dans l'interface com.ibm.websphere.objectgrid.em.Query.

public ObjectMap getResultMap()

La méthode getResultMap exécute une requête SELECT et renvoie les résultats dans un objet ObjectMap avec les résultats classés dans l'ordre spécifié dans la requête. L'ObjectMap résultante est valide uniquement pour la transaction en cours.

La clé de mappe correspond au chiffe de résultat, de type long, débutant à 1. La valeur de mappe est de type com.ibm.websphere.projector.Tuple où chaque attribut et association est nommée en fonction de sa position ordinale dans la clause select de la requête. Utilisez la méthode pour extraire l'EntityMetadata pour l'objet Tuple stocké dans la mappe.

La méthode getResultMap est la méthode la plus rapide pour extraire les données de résultat de requête incluant plusieurs résultats. Vous pouvez extraire le nom de l'entité résultante à l'aide des méthodes ObjectMap.getEntityMetadata() et EntityMetadata.getName().

Exemple : la requête suivante renvoie deux lignes.

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; // démarre avec l'index 1
 Tuple tResult = (Tuple) resultMap.get(new Long(rowID));
 while(tResult != null) {
     // Le premier attribut est nom et possède un nom d'attribut 1
     // mais présente une position ordinale de 0.
     String name = (String)tResult.getAttribute(0);
     Integer id = (String)tResult.getAttribute(1);

     // Dept est une association avec un nom 3 mais
     // présente une position ordinale de 0 car il s'agit de la première association.
     // L'association est toujours une relation un à un,
     // il y existe donc uniquement une clé.
     Tuple deptKey = tResult.getAssociation(0,0);
     ...
     ++rowID;
     tResult = (Tuple) resultMap.get(new Long(rowID));

 }

public Iterator getResultIterator

La méthode getResultIterator exécute une requête SELECT et renvoie les résultats de la requête à l'aide d'un itérateur où chaque résultat est un objet pour une requête à valeur unique ou un tableau Objet pour une requête à plusieurs valeurs. Les valeurs du résultat Object[] sont stockées dans l'ordre de la requête. L'itérateur de résultat est valide pour la transaction en cours uniquement.

Cette méthode est privilégiée pour extraire les résultats de requête dans le contexte EntityManager. Vous pouvez utiliser la méthode facultative setResultEntityName(String) pour nommer l'entité résultant de façon à ce qu'elle soit utilisée dans des requêtes ultérieures.

Exemple : La requête suivante renvoie deux lignes.

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)

La méthode getResultIterator(Class resultType) exécute une requête SELECT et renvoie les résultats de la requête à l'aide d'un itérateur d'entité. Le type d'entité est déterminé par le paramètre resultType. L'itérateur de résultat est valide uniquement pour la transaction en cours.

Faites appel à la méthode lorsque vous voulez utiliser les API EntityManager pour accéder aux entités résultantes.

Exemple : la requête suivante renvoie tous les employés et le service auquel ils appartiennent pour une division donnée, dans l'ordre de leur salaire. Pour imprimer les cinq employés qui ont le salaire le plus élevé, puis sélectionner le travail des employés d'un seul service dans le même ensemble de travail, utilisez le code suivant.

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);
	// Supprimez l'employé de l'ensemble de résultats.
	em.remove(curEmp);
}

// Videz les modifications dans la mappe de résultats.
em.flush();

// Exécutez une requête avec le jeu de documents local sans les employés qui ont été
// supprimés
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

La méthode getSingleResult exécute une requête SELECT qui renvoie un seul résultat.

Si plusieurs zones ont été définies pour la clause SELECT, il en résulte un tableau d'objets où chaque élément du tableau repose sur sa position ordinale au sein de la clause 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)

La méthode setResultEntityName(String entityName) spécifie le nom de l'entité de résultats de la requête.

A chaque appel des méthodes getResultIterator ou getResultMap, une entité associée à une ObjectMap est dynamiquement créée pour contenir les résultats de la requête. Si l'entité n'est pas spécifiée ou égale à null, le nom de l'entité et le nom de l'ObjectMap sont automatiquement générés.

Etant donné que tous les résultats de requête sont disponibles pour la durée d'une transaction, un nom de requête ne peut pas être réutilisé au sein d'une même transaction.

public Query setPartition(int partitionId)

Définition la partition vers laquelle la requête s'achemine.

Cette méthode est requise si les mappes de la requête sont partitionnées et si le gestionnaire d'entité n'a pas d'affinité avec une seule partition d'entité racine de schéma.

Utilisez l'interface PartitionManager pour déterminer le nombre de partitions pour la mappe de sauvegarde d'une entité donnée.

Le tableau ci-dessous décrit les autres méthodes disponibles dans l'interface de requête.

Tableau 1. Autres méthodes.
Méthode Résultat
public Query setMaxResults(int maxResult) Définit le nombre maximal de résultats à extraire.
public Query setFirstResult(int startPosition) Définit la position du premier résultat à extraire.
public Query setParameter(String name, Object value) Lie un argument à un paramètre nommé.
public Query setParameter(int position, Object value) Lie un argument à un paramètre positionnel.
public Query setFlushMode(FlushModeType flushMode) Définit le type Mode de vidage à utiliser lors de l'exécution de la requête, remplaçant le type Mode de vidage défini sur l'EntityManager.

Eléments de requête eXtreme Scale

Avec le moteur de requêteeXtreme Scale, vous pouvez utiliser un langage de requête unique pour effectuer des recherches dans le cache eXtreme Scale. Ce langage de requête peut interroger les objets Java stockés dans les objets ObjectMap et les objets Entity. Utilisez la syntaxe suivante pour créer une chaîne de requête.

Une requête eXtreme Scale consiste en une chaîne qui contient les éléments suivants :
  • une clause SELECT qui indique les objets ou les valeurs à renvoyer ;
  • une clause FROM qui nomme les collections d'objets ;
  • une clause WHERE facultative qui contient des prédicats de recherche sur les collections ;
  • une clause GROUP BY et HAVING facultative (voir la rubrique eXtreme Scale Fonctions d'agrégation de requête).
  • une clause ORDER BY facultative qui indique l'ordre de la collecte des résultats.

Les collections d'objets Java sont identifiées dans des requêtes via leur nom dans la clause FROM de la requête.

Les éléments du langage de requête sont présentés plus en détail dans les rubriques connexes suivantes :
Les rubriques ci-dessous décrivent les modes d'utilisation de l'API de requête :