WebSphere eXtreme Scale stellt eine flexible Abfragesteuerkomponente bereit, mit der Entitäten über die API "EntityManager" und Java-Objekte über die API "ObjectQuery" abgerufen werden können.
Mit der Abfragesteuerkomponente von eXtreme Scale können Sie unter Verwendung der Abfragesprache von eXtreme Scale Abfragen vom Typ SELECT für eine Entität oder ein objektbasiertes Schema durchführen.
Diese Abfragesprache hat die folgenden Leistungsmerkmale:
Verwenden Sie die Abfrageschnittstelle, um die Ausführung von Entitätsabfragen zu steuern.
Verwenden Sie die Methode "EntityManager.createQuery(String)", um eine Abfrage zu erstellen. Sie können jede Abfrageinstanz mehrfach für die EntityManager-Instanz verwenden, in der sie abgerufen wurde.
Jedes Abfrageergebnis erzeugt eine Entität, deren Entitätsschlüssel die Zeilen-ID (vom Typ "long") und deren Entitätswert die Feldergebnisse der SELECT-Klausel ist. Sie können jedes Abfrageergebnis in nachfolgenden Abfragen verwenden.
Die folgenden Methoden sind in der Schnittstelle "com.ibm.websphere.objectgrid.em.Query" verfügbar.
Die Methode "getResultMap" führt eine SELECT-Abfrage durch und gibt die Ergebnisse in einem ObjectMap-Objekt in der in der Abfrage festgelegten Reihenfolge zurück. Das ObjectMap-Objekt ist nur für die aktuelle Transaktion gültig.
Der Map-Schlüssel ist die Ergebnisnummer (vom Typ "long"), beginnend bei 1. Der Map-Wert hat den Typ "com.ibm.websphere.projector.Tuple", wobei jedes Attribut und jede Assoziation nach der Ordinalposition in der SELECT-Klausel der Abfrage benannt wird. Verwenden Sie die Methode, um das EntityMetadata-Objekt für das Tuple-Objekt abzurufen, das in der Map gespeichert ist.
Die Methode "getResultMap" ist die schnellste Methode für das Abrufen von Abfrageergebnisdaten, wenn mehrere Ergebnisse verfügbar sein können. Sie können den Namen der Entität mit den Methoden "ObjectMap.getEntityMetadata()" und "EntityMetadata.getName()" abrufen.
Die folgende Abfrage gibt beispielsweise zwei Zeilen zurück:
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) {
// Das erste Attribut ist der Name und hat den Attributnamen 1,
// aber die Ordinalposition 0.
String name = (String)tResult.getAttribute(0);
Integer id = (String)tResult.getAttribute(1);
// Dept ist eine Assoziation mit dem Namen 3, aber der
// Ordinalposition 0, da es sich um die erste Assoziation handelt.
// Die Assoziation ist immer eine 1:1-Beziehung, und deshalb
// gibt es nur einen einzigen Schlüssel.
Tuple deptKey = tResult.getAssociation(0,0);
...
++rowID;
tResult = (Tuple) resultMap.get(new Long(rowID));
}
public Iterator getResultIterator
Die Methode "getResultIterator" führt eine SELECT-Abfrage durch und gibt die Abfrageergebnisse über einen Iterator zurück. Jedes Ergebnis ist entweder ein Objekt (bei einer Abfrage mit einem einzigen Wert) oder ein Objektbereich (für eine Abfrage mit mehreren Werten). Die Werte in "Object[]" werden in der Abfragereihenfolge gespeichert. Der Ergebnisiterator ist nur für die aktuelle Transaktion gültig.
Diese Methode ist die bevorzugte Methode für das Abrufen von Abfrageergebnissen im EntityManager-Kontext. Sie können die optionale Methode "setResultEntityName(String)" verwenden, um die ermittelte Entität zu benennen, so dass sie in weiteren Abfragen verwendet werden kann.
Die folgende Abfrage gibt beispielsweise zwei Zeilen zurück:
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)
Die Methode "getResultIterator(Class resultType)" führt eine SELECT-Abfrage durch und gibt die Abfrageergebnisse über einen Entitätsiterator zurück. Der Entitätstyp wird mit dem Parameter "resultType" bestimmt. Der Ergebnisiterator ist nur für die aktuelle Transaktion gültig.
Verwenden Sie diese Methode, wenn Sie die EntityManager-APIs für den Zugriff auf die ermittelten Entitäten verwenden möchten.
Die folgende Abfrage gibt beispielsweise alle Mitarbeiter (Employees) und die Abteilung (Department), zu der sie gehören, für einen einzigen Unternehmensbereich (Division), sortiert nach Gehalt (Salary), zurück. Wenn Sie die fünf Mitarbeiter mit den höchsten Gehältern ausgeben und anschließend nur mit Mitarbeitern aus einer einzigen Abteilung in demselben Arbeitsbereich arbeiten möchten, verwenden Sie den folgenden Code:
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);
// Mitarbeiter aus der Ergebnismenge entfernen
em.remove(curEmp);
}
// Änderungen in einer Flush-Operation in die Ergebnismenge schreiben
em.flush();
// Abfrage für den lokalen Arbeitsbereich ohne die entfernten
// Mitarbeiter ausführen
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
Die Methode "getSingleResult" führt eine SELECT-Abfrage durch, die ein einziges Ergebnis zurückgibt.
Wenn in der SELECT-Klausel mehrere Felder definiert sind, ist das Ergebnis ein Objektbereich, in dem jedes Element auf der Ordinalposition in der SELECT-Klausel der Abfrage basiert.
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)
Die Methode "setResultEntityName(String entityName)" gibt den Namen der Abfrageergebnisentität an.
Jedesmal, wenn die Methode "getResultIterator" oder "getResultMap" aufgerufen wird, wird dynamisch eine Entität mit einer ObjectMap erstellt, in der die Ergebnisse der Abfrage gespeichert werden. Wenn die Entität nicht angegeben oder null ist, werden der Entitäts- und ObjectMap-Name automatisch generiert.
Da alle Abfrageergebnisse für die Dauer einer Transaktion verfügbar sind, kann ein Abfragename innerhalb einer Transaktion nicht wiederverwendet werden.
public Query setPartition(int partitionId)
Diese Methode legt die Partition fest, an die die Abfrage weitergeleitet wird.
Diese Methode ist erforderlich, wenn die Maps in der Abfrage partitioniert sind und der EntityManager keine Affinität zu einer Stammentitätspartition mit einem einzelnen Schema hat.
Verwenden Sie die Schnittstelle "PartitionManager", um die Anzahl der Partitionen für die BackingMap einer bestimmten Entität festzulegen.
Die folgende Tabelle enthält Beschreibungen weiterer Methoden, die über die Abfrageschnittstelle verfügbar sind.
Methode | Ergebnis |
---|---|
public Query setMaxResults(int maxResult) | Legt die maximale Anzahl abzurufender Ergebnisse fest. |
public Query setFirstResult(int startPosition) | Legt die Position des ersten abzurufenden Ergebnisses fest. |
public Query setParameter(String name, Object value) | Bindet ein Argument an einen benannten Parameter. |
public Query setParameter(int position, Object value) | Bindet ein Argument an einen positionsgebundenen Parameter. |
public Query setFlushMode(FlushModeType flushMode) | Legt den bei der Durchführung der Abfrage zu verwendenden Flush-Modustyp fest, der den im EntityManager festgelegten Flush-Modustyp überschreibt. |
Mit der Abfragesteuerkomponente von eXtreme Scale können Sie eine einzige Abfragesprache verwenden, um den eXtreme-Scale-Cache zu durchsuchen. Diese Abfragesprache kann Java-Objekte abfragen, die in ObjectMap-Objekten und Entity-Objekten gespeichert sind. Verwenden Sie die folgende Syntax, um eine Abfragezeichenfolge zu erstellen.
Sammlungen von eXtreme-Scale-Objekten werden in Abfragen anhand ihres in der FROM-Klausel der Abfrage angegebenen Namens identifiziert.