Enterprise JavaBeans Überblick 1. Überblick Komponententechnologien 2. Einführung 3. Enterprise JavaBeans Architektur 4. Ressourcen Management und Primäre Services 5. Java Persistence: Entity Manager 6. Objekt-Relationales Mapping 7. Entity Bean Beziehungen 8. Test-Driven Development 9. Architektur der Web-Schicht 9a. JavaServer Faces mit JBoss und Eclipse 11. Value Objects 12. Session Facade 13. Transaktionen und Concurrency 14. Ergänzungen zu EJBs 15. UML Modellierung und EJBs 16. Session Beans 17. Enterprise Information System Schicht Prof. Dr. Björn Dreher Liste V Enterprise JavaBeans 427 Enterprise JavaBeans Überblick: 10.3 Named Queries Prof. Dr. Björn Dreher Liste V Enterprise JavaBeans 428
Finden von einzelnen Entity Beans oder Ergebnismengen von Entity Beans Beispiel Customer cust = null; try { Query query = entitymanager.createquery( "SELECT c FROM customer c WHERE c.firstname='bill' AND c.lastname='burke'"); cust = (Customer)query.getSingleResult(); catch (NoResultException notfound) {... catch (NonUniqueResultException nonunique) {... Exceptions hier sind Nachfahren von java.lang.runtimeexception Daher müssen sie nicht gefangen werden Prof. Dr. Björn Dreher Liste V Enterprise JavaBeans 429 Beispiel für Ergebnismenge Alle "Bill"s Query query = entitymanager.createquery( "SELECT c FROM customer c WHERE c.firstname='bill'"); java.util.list bills = query.getresultlist(); Hier keine Exceptions außer IllegalStateException, falls EJB QL UPDATE oder DELETE Statement Prof. Dr. Björn Dreher Liste V Enterprise JavaBeans 430
Parameter public List findbyname(string first, String last) { Query query = entitymanager.createquery( SELECT c FROM Customer c WHERE c.firstname=:first AND c.lastname=:last"); query.setparameter("first", first); query.setparameter("last", last); return query.getresultlist(); Auch Positionsparameter (nicht empfohlen) public List findbyname(string first, String last) { Query query = entitymanager.createquery( SELECT c FROM Customer c WHERE c.firstname=?1 AND c.lastname=?2"); query.setparameter(1, first); query.setparameter(2, last); return query.getresultlist(); Prof. Dr. Björn Dreher Liste V Enterprise JavaBeans 431 Datum- und Zeit-Parameter Konversion von java.util.date java.util.calendar in SQL Datentypen java.sql.date java.sql.time java.sql.timestamp java.util.date datum; java.util.date zeit; java.util.calendar zeitpunkt; query.setparameter("datum", datum, TemporalType.DATE); // java.sql.date query.setparameter("zeit", zeit, TemporalType.TIME); // java.sql.time query.setparameter("zeitpunkt", zeitpunkt, TemporalType.TIMESTAMP); // java.sql.timestamp Prof. Dr. Björn Dreher Liste V Enterprise JavaBeans 432
Paging Nur Ausschnitt aus Ergebnismenge public List getcustomers(int max, int index) { Query query = entitymanager.createquery(select c FROM Customer c); return query.setmaxresults(max). setfirstresult(index). getresultlist(); FlushMode Erst nach Commit in Datenbank speichern Hier würde vor Ausführung der Query nicht in die Datenbank geflushed Query query = entitymanager.createquery(select c FROM Customer c); query.setflushmode(flushmodetype.commit); Prof. Dr. Björn Dreher Liste V Enterprise JavaBeans 433 Wichtigste Ausnahmebedingungen getsingleresult() javax.persistence.noresultexception javax.persistence.noneuniqueresultexception java.lang.illegalstateexception getresultlist() java.lang.illegalstateexception Keine Bean gefunden: Leere Collection Alle Exceptions sind Runtime Exceptions Daher fangen formal nicht notwendig Prof. Dr. Björn Dreher Liste V Enterprise JavaBeans 434
Enterprise JavaBeans Überblick: 10.3 Named Queries Prof. Dr. Björn Dreher Liste V Enterprise JavaBeans 435 EJB QL neu auch: JPQL (Java Persistence Query Language) Deklarative Abfragesprache Ähnlich SQL Angepasst an das Persistenz Schema der Entity Beans unter EJB 2.0 Unabhängig von der darunter liegenden Datenbankstruktur Portabel unter verschiedenen Datenbanken Deploy-Vorgang: EJB QL wird in Abfragesprache der Datenbank übersetzt Zur Laufzeit wird diese spezifische Sprache ausgeführt Bean Hersteller Abstrakte Formulierung der Queries Prof. Dr. Björn Dreher Liste V Enterprise JavaBeans 436
EJB QL definieren Über Query Objekte Einige einfache Beispiele schon besprochen Immer Entity Bean als Rückgabetyp Andere Möglichkeit Einzelne Properties der Entity Bean Query query entitymanager.createquery( "SELECT c.firstname, c.lastname FROM Customer AS c"); List results = query.getresultlist(); Iterator it = results.iterator(); while (it.hasnext()) { Object[] result = (Object[]) it.next(); String first = (String) result[0]; String first = (String) result[1]; Prof. Dr. Björn Dreher Liste V Enterprise JavaBeans 437 Navigation über einwertige Relationen SELECT c.creditcard FROM Customer AS c WHERE... Alle city Properties der Kreditkartenfirmen, die zuständig für die Kreditkarten der Kunden von Titan Cruises sind SELECT c.creditcard.creditcompany.address.city FROM Customer AS c Prof. Dr. Björn Dreher Liste V Enterprise JavaBeans 438
Konstruktor Ausdrücke Erzeuge als Resultat der Query ein normales Java Objekt, das durch die Abfrage initialisiert wird public class Name { private String first; private String last; public Name(String first, String last) { this.first = first; this.last = last; public String getfirst() { return first; public String getlast() { return last; Abfrage SELECT new Name(c.firstName, c.lastname) FROM Customer c Prof. Dr. Björn Dreher Liste V Enterprise JavaBeans 439 Navigation über mehrwertige Relationen Mit Hilfe des IN Operators SELECT r FROM Customer AS c, IN (c.reservations) r Von da aus kann man weiter navigieren SELECT r.cruise FROM Customer AS c, IN (c.reservations) r Äquivalent zur Formulierung als Inner Join SELECT r.cruise FROM Customer AS c INNER JOIN c.reservations r Schlüsselwort INNER kann entfallen Prof. Dr. Björn Dreher Liste V Enterprise JavaBeans 440
Navigation über leere Relationen Left Join SELECT c.firstname, c.lastname, p.number FROM Customer c LEFT JOIN c.phonenumbers p Kunden ohne Phonenumber erhalten null für die Telefonnummer Entspricht LEFT OUTER JOIN in SQL 92 Prof. Dr. Björn Dreher Liste V Enterprise JavaBeans 441 Fetch Joins Laden einer Beziehung, selbst wenn FetchType auf LAZY gesetzt ist @OneToMany(fetch=FetchType.LAZY) public Collection<Phone> getphones() { return phones; Verwendung Query query entitymanager.createquery("select c FROM Customer c"); List results = query.getresultlist(); Iterator it = results.iterator(); Nur Customer while (it.hasnext()) { geladen Customer c = (Customer) it.next(); System.out.print(c.getFirstName() + " " + c.getlastname()); for (Phone p : c.getphonenumbers()) { System.out.print(p.getNumber() + " "); System.out.println(""); Zusätzlicher DB-Zugriff: N+1-Problem Prof. Dr. Björn Dreher Liste V Enterprise JavaBeans 442
Fetch Joins Vorausschauender Preload Query query entitymanager.createquery( "SELECT c FROM Customer c LEFT JOIN FETCH c.phones"); List results = query.getresultlist(); Auch phones Iterator it = results.iterator(); werden while (it.hasnext()) { geladen Customer c = (Customer) it.next(); System.out.print(c.getFirstName() + " " + c.getlastname()); for (Phone p : c.getphonenumbers()) { System.out.print(p.getNumber() + " "); System.out.println(""); Kein zusätzlicher DB-Zugriff Prof. Dr. Björn Dreher Liste V Enterprise JavaBeans 443 Enterprise JavaBeans Überblick: 10.3 Named Queries Prof. Dr. Björn Dreher Liste V Enterprise JavaBeans 444
10.3 Named Queries Vordefinition von Queries Analog zu Konstanten @NamedQueries({ @NamedQuery(name="getAverageReservation", query= "SELECT AVG(r.amountPaid) FROM Cruise AS c, JOIN c.reservations r WHERE c.id = :cruiseid"), @NamedQuery(name="findFullyPaidCruises", query= "SELECT c FROM Cruise As c WHERE 0 < ALL ( SELECT res.amountpaid FROM c.reservations res )") ) @Entity public class Cruise {... Aufruf Alle Elemente der Subquery erfüllen Bedingung: amountpaid > 0 Query query = em.createnamedquery("getaveragereservation"); query.setparameter("cruiseid", id); Prof. Dr. Björn Dreher Liste V Enterprise JavaBeans 445