Beispiel: Lokale Schnittstelle für dynamische Abfrage verwenden
Bei der Ausführung einer dynamischen EJB-Abfrage (Enterprise JavaBeans) über die lokale Schnittstelle wird die Methode "executeQuery" in der Schnittstelle "QueryLocal" aufgerufen. Diese Schnittstelle leitet keine Transaktion für die Methode ein. Deshalb müssen Sie für die Abfrage explizit einen Transaktionskontext einrichten.
Beginnen Sie den Abfragecode mit den folgenden Importanweisungen:
import com.ibm.websphere.ejbquery.QueryLocalHome; import com.ibm.websphere.ejbquery.QueryLocal; import com.ibm.websphere.ejbquery.QueryLocalIterator; import com.ibm.websphere.ejbquery.IQueryTuple; import com.ibm.websphere.ejbquery.QueryException;
Schreiben Sie anschließend Ihre Abfrageanweisung in Form einer Zeichenfolge. Das folgende Beispiel ruft beispielsweise die Namen und EJB-Referenzen für unterbezahlte Mitarbeiter auf:
String query = "select e.name, object(e) from EmpBean e where e.salary < 50000 ";
Erstellen Sie ein QueryLocal-Objekt, indem Sie eine Referenz von der Klasse QueryLocalHome anfordern. (Diese Klasse definiert die Methode executeQuery.) Im folgenden Beispiel wird ejb/query als lokale EJB-Referenz verwendet, die auf den JNCI-Namen für dynamische Abfragen (com/ibm/websphere/ejbquery/Query) verweist:
InitialContext ic = new InitialContext(); QueryLocalHome qh = ( LocalQueryHome) ic.lookup( "java:comp/env/ejb/query" ); QueryLocal qb = qh.create();
Der letzte Teil des Codes leitet eine Transaktion ein, ruft die Methode executeQuery auf und zeigt die Abfrageergebnisse an. Die Klasse QueryLocalIterator wird instanziert, weil sie das Abfrageergebnis definiert. Diese Klasse ist im API-Paket der Klasse "QueryIterator" enthalten. Der Iterator verliert am Ende der Transaktion seine Gültigkeit. Sie müssen den Iterator im selben Transaktionsbereich wie den Aufruf executeQuery verwenden.
userTransaction.begin(); QueryLocalIterator it = qb.executeQuery(query, null, null); while (it.hasNext()) { IQueryTuple tuple = (IQueryTuple) it.next(); System.out.print( it.getFieldName(1) ); String s = (String) tuple.getObject(1); System.out.println( s); System.out.println( it.getFieldName(2) ); EmpLocal e = ( EmpLocal ) tuple.getObject(2); System.out.println( e.getPrimaryKey().toString()); } userTransaction.commit();
In den meisten Fällen ist das QueryLocalIterator-Objekt bedarfsgesteuert, d. h. die Daten werden inkrementell zurückgegeben. Für jeden Abruf eines Datensatzes aus der Datenbank muss die Methode next() für den Iterator aufgerufen werden. (Es gibt Situationen, in denen der Iterator nicht bedarfsgesteuert ist. Nähere Informationen hierzu finden Sie im Teilabschnitt "Lokale Abfrageschnittstellen" des Artikels Hinweise zur Leistung des dynamischen Abfrageservice.)
Da das vollständige Abfrageergebnis inkrementell im Speicher des Anwendungsservers abgelegt wird, können Sie die Größe problemlos steuern. Während eines Testlaufs können Sie beispielsweise feststellen, dass nur ein paar Tupel des Abfrageergebnisses erforderlich sind. In diesem Fall können Sie mit einem Aufruf der Methode "close()" für das Objekt "QueryLocalIterator" die Abfrageschleife schließen. Damit werden die vom Iterator verwendeten SQL-Ressourcen freigegeben. Andenfalls werden diese Ressourcen erst freigegeben, wenn sich die gesamte Ergebnisobjektgruppe im Speicher befindet oder die Transaktion endet.