Am 14. September 2017 haben wir eine überarbeitete Fassung unserer Datenschutzrichtlinie veröffentlicht. Wenn Sie video2brain.com weiterhin nutzen, erklären Sie sich mit diesem überarbeiteten Dokument einverstanden. Bitte lesen Sie es deshalb sorgfältig durch.

Java EE 7 Grundkurs

Benannte und native Abfragen

LinkedIn Learning kostenlos und unverbindlich testen!

Jetzt testen Alle Abonnements anzeigen
Die Verwendung von benannten sowie nativen Abfragen dient dazu, Probleme bei der Wartbarkeit von datenbankbetriebenen Applikationen zu verringern und Änderungen an einer Abfrage oder an der Struktur der Tabellen durchzuführen.

Transkript

In diesem Video werden wir uns mit benannten und nativen Abfragen befassen. Wir werden klären, was das ist und wie wir es verwenden können. Benannte Abfragen sind Abfragen, die genau wie normale JPQL-Statements funktionieren. Allerdings werden sie über einen symbolischen Namen referenziert. Dies erlaubt es uns, sie auf Ebene von Entitäten vorzudefinieren und damit zentraler zu verwalten. Letztlich sind benannte Abfragen ein Aspekt, der der Wartbarkeit zu Gute kommt. Wenn wir benannte Abfragen deklarieren wollen, machen wir das mit Hilfe von NamedQuery und NamedQueries-Annotationen. Die eigentliche Abfrage wird dann nicht mehr über die createQuery-Methode aufgerufen, sondern wir verwenden hier die Methode "createNamedQuery". Es gibt ebenfalls die Möglichkeit, dass wir mit der JPA native, also SQL-Abfragen ausführen können. Das sind dann sogenannte native queries. Bei diesen native queries kann sogar ein O/R-Mapping stattfinden. Das bedeutet, dass ich in der Lage bin, ein normales SQL-Statement abzusetzen. Und die JPA gibt mir dann eine voll instanzierte, mit den entsprechenden Werten befüllte Objektinstanz zurück, ohne dass ich händisch noch Tätigkeiten vornehmen müsste. Native Abfragen können übrigens auch benannt sein. Sie werden dann über NativeQuery oder NativeQueries-Annotationen deklariert. Abfragen geschehen dann entweder über die createNativeQuery-Methode des EntityManagers oder über die bereits erwähnte createNamedQuery-Methode. Letztere ist natürlich nur für die benannten Abfragen zuständig. Ebenfalls gibt es seit der JPA 2.1 eine Unterstützung für Stored Procedures, das heißt Funktionalitäten, die in der Datenbank hinterlegt sind. Diese Unterstützung kann über die Methode "createStoredProcedureQuery" der EntityManager-Instanz abgerufen werden. Die Ergebniswerte können wir dann ebenfalls erreichen. Und zwar gibt es dafür die Methode "getOutputParameterValue". In diese Methode muss ich einen Index hineingeben. Der Hintergrund ist der, dass bei einer Stored Procedure mehr als eine Rückgabe erfolgen kann und wir diese Rückgabe, die uns interessiert, natürlich adressieren müssen. Sehen wir uns einfach einmal an, wie wir mit named queries und mit native queries arbeiten können. Wir befinden uns hier in der Initialisierungsmethode einer Applikation. Innerhalb dieser Initialisierungsmethode wird als Erstes eine Abfrage auf die Datenbank ausgeführt, und zwar eine SQL-Abfrage. Und zwar wird hier in dieser SQL-Abfrage die Anzahl der Datensätze in einer bestimmten Tabelle bestimmt. Uns interessiert an dieser Stelle weniger, wie die Initialisierung weitergeht, sondern erstens, dass wir diese Abfrage über die Methode "createNativeQuery" erzeugen, und zweitens, dass wir uns, anders als bisher, nur noch einen einzelnen Datensatz zurückgeben lassen. Dies erreichen wir, indem wir die Methode "getSingleResult" des Query-Objektes aufrufen. Diese Methode "getSingleResult" steht dann sowohl für native queries als auch für JPQL-Queries zur Verfügung. Aber Vorsicht beim Einsatz: "getSingleResult" gibt Ihnen nämlich fast immer eine Exception, nämlich jedes Mal dann, wenn Sie weniger als einen Datensatz oder mehr als einen Datensatz gefunden haben. Setzen Sie diese Methode also wirklich nur dann ein, wenn Sie wissen, dass es genau nur einen Datensatz geben kann. Etwas weiter unten in dieser Klasse gibt es noch die Verwendung einer normalen JPQL-Abfrage. Das machen wir mit der Methode "createQuery" und, im Gegensatz zu getSingleResult, hier mit der Methode "getResultList", die uns eine Liste von Ergebnissen zurückgibt. An dieser Methode ist grundsätzlich nichts auszusetzen, das heißt sie funktioniert. Allerdings gibt es einen gewaltigen Nachteil. Und das ist die Wartbarkeit. Diese Methode befindet sich irgendwo in Zeile 71 einer Klasse. Genauso wie sich die Abfrage auf die Anzahl der Datensätze in einer Datenbanktabelle irgendwo mitten in einer Klasse befindet. Wenn ich nun diese Abfragen anpassen möchte, dann habe ich eine Menge zu tun, erstmal die richtigen Stellen zu suchen. Das ist der Grund, warum es named queries gibt, und zwar in der Ausprägung named native query für native Abfragen und named query für JPQL-Statements. Wie bereits erwähnt, werden diese Abfragen auf Ebene von JPA-Entitäten deklariert. Ich habe das schon einmal vorgenommen, auf Ebene der Book-Entität. Sie erkennen das hieran, dass hier oben die Entity-Annotation definiert ist. Auf Ebene dieser Book-Klasse kann ich nun mit Hilfe von named-native-queries-Elementen und named-queries-Elementen jeweils die von mir gewünschten Abfragen deklarieren. Named native queries nimmt dabei intern ein Array von named-native-query-Elementen entgegen. Und jedes dieser named-native-query-Elemente verfügt über eine Eigenschaft "Name", das ist der symbolische Name, über den ich die Abfrage dann ansprechen kann, und über eine Eigenschaft "query". Das ist das auszuführende SQL-Statement. Analoges gilt für die named-queries-Annotation. Diese verfügt intern über ein Array von named-query-Annotationen. Auch jede named query verfügt über einen symbolischen Namen und über das auszuführende JPQL-Statement. Wir merken uns einmal die Namen, die uns hier interessieren könnten, nämlich "find_all_books" und "publisher_count", und werden nun in der BookManager-Klasse diese Funktionalitäten einsetzen. Zu diesem Zweck ersetzen wir einfach die bisherigen Statements, die per createQuery erzeugt worden sind, durch ihre entsprechenden Gegenstücke, und zwar durch createNamedQuery. Hier übergeben wir den symbolischen Namen und gegebenenfalls den Namen der Klasse, damit die Typ-Konvertierung schneller und leichter vonstatten gehen kann. Das gleiche machen wir bei der native query. Auch hier merken wir uns den symbolischen Namen und rufen diese native query auf, indem wir aus dem Aufruf "createNativeQuery" ein createNamedQuery machen, das ist der gleiche Aufruf, wie wir ihn auch bei JPQL-Statements haben, und den symbolischen Namen übergeben. Weitere Änderungen sind nicht nötig. Die native Abfrage beziehungsweise die JPQL-Abfrage sind nun sofort einsatzfähig. Der große Vorteil ist wirklich, dass die Wartbarkeit gesteigert wird, denn die Abfragen sind nunmehr außerhalb der jeweiligen Klassen, wo sie verwendet werden, deklariert. Und ich kann sie halt auch sehr, sehr einfach ändern. Wenn ich also der Meinung bin, ich möchte nicht die Anzahl der ersten Spalte haben, sondern aller Spalten haben oder ähnliche Dinge, dann kann ich das an einer zentralen Stelle tun, und es wird überall dort, wo diese Abfrage eingesetzt wird, sofort Gültigkeit erlangen. Sie sehen: Named queries und native queries und named native queries sind ein interessantes Konstrukt, um die Wartbarkeit auf der einen Seite zu steigern, und auf der anderen Seite, um native Abfragen auszuführen.

Java EE 7 Grundkurs

Lernen Sie die Grundlagen der Programmierung mit Java EE 7 verstehen und anwenden.

6 Std. 4 min (44 Videos)
Derzeit sind keine Feedbacks vorhanden...
 

Dieser Online-Kurs ist als Download und als Streaming-Video verfügbar. Die gute Nachricht: Sie müssen sich nicht entscheiden - sobald Sie das Training erwerben, erhalten Sie Zugang zu beiden Optionen!

Der Download ermöglicht Ihnen die Offline-Nutzung des Trainings und bietet die Vorteile einer benutzerfreundlichen Abspielumgebung. Wenn Sie an verschiedenen Computern arbeiten, oder nicht den ganzen Kurs auf einmal herunterladen möchten, loggen Sie sich auf dieser Seite ein, um alle Videos des Trainings als Streaming-Video anzusehen.

Wir hoffen, dass Sie viel Freude und Erfolg mit diesem Video-Training haben werden. Falls Sie irgendwelche Fragen haben, zögern Sie nicht uns zu kontaktieren!