Was sind die Vor- und Nachteile der Verwendung von Kriterien oder HQL ? Die Kriterien-API ist eine nette objektorientierte Methode, um Abfragen im Ruhezustand auszudrücken. Manchmal sind Kriterienabfragen jedoch schwieriger zu verstehen / zu erstellen als HQL.
Wann verwenden Sie Kriterien und wann HQL? Was bevorzugen Sie in welchen Anwendungsfällen? Oder ist es nur Geschmackssache?
Antworten:
Ich bevorzuge hauptsächlich Kriterienabfragen für dynamische Abfragen. Zum Beispiel ist es viel einfacher, eine Reihenfolge dynamisch hinzuzufügen oder einige Teile (z. B. Einschränkungen) abhängig von bestimmten Parametern wegzulassen.
Andererseits verwende ich HQL für statische und komplexe Abfragen, weil es viel einfacher ist, HQL zu verstehen / zu lesen. Außerdem ist HQL meiner Meinung nach etwas leistungsfähiger, z. B. für verschiedene Join-Typen.
quelle
Es gibt einen Leistungsunterschied zwischen HQL und KriterienQuery. Jedes Mal, wenn Sie eine Abfrage mit KriterienQuery auslösen, wird ein neuer Alias für den Tabellennamen erstellt, der im zuletzt abgefragten Cache für eine Datenbank nicht berücksichtigt wird. Dies führt zu einem Overhead beim Kompilieren des generierten SQL, dessen Ausführung mehr Zeit in Anspruch nimmt.
In Bezug auf Abrufstrategien [http://www.hibernate.org/315.html]
quelle
Criteria ist eine objektorientierte API, während HQL die Verkettung von Zeichenfolgen bedeutet. Das heißt, alle Vorteile der Objektorientierung gelten:
Da HQL SQL sehr ähnlich ist (was die meisten Entwickler bereits sehr gut kennen), haben diese Argumente, an die man sich nicht erinnern muss, nicht so viel Gewicht. Wenn HQL anders wäre, wäre dies wichtiger.
quelle
Normalerweise verwende ich Kriterien, wenn ich nicht weiß, welche Eingaben für welche Daten verwendet werden. Wie bei einem Suchformular, bei dem der Benutzer 1 bis 50 Elemente eingeben kann und ich nicht weiß, wonach er suchen wird. Es ist sehr einfach, mehr an die Kriterien anzuhängen, während ich überprüfe, wonach der Benutzer sucht. Ich denke, es wäre etwas schwieriger, unter diesen Umständen eine HQL-Abfrage zu stellen. HQL ist großartig, wenn ich genau weiß, was ich will.
quelle
HQL ist viel einfacher zu lesen, mit Tools wie dem Eclipse Hibernate-Plugin einfacher zu debuggen und einfacher zu protokollieren. Kriterienabfragen eignen sich besser zum Erstellen dynamischer Abfragen, bei denen ein Großteil des Verhaltens zur Laufzeit bestimmt wird. Wenn Sie SQL nicht kennen, könnte ich die Verwendung von Kriterienabfragen verstehen, aber insgesamt bevorzuge ich HQL, wenn ich weiß, was ich im Voraus möchte.
quelle
Kriterien sind die einzige Möglichkeit, natürliche Schlüsselsuchen anzugeben, die die spezielle Optimierung im Abfragecache der zweiten Ebene nutzen. HQL hat keine Möglichkeit, den erforderlichen Hinweis anzugeben.
Weitere Informationen finden Sie hier:
quelle
Kriterien Api ist eines der guten Konzepte von Hibernate. Meiner Ansicht nach sind dies die wenigen Punkte, anhand derer wir zwischen HQL und Criteria Api unterscheiden können
quelle
limit offset:rows
Einige Punkte Paginierung gibt es in HQL: Sie können verwenden In HQL können Sie SQL-Injektion mitsetParameter
Um das Beste aus beiden Welten zu nutzen, sollten Querydsl , die Expressivität und Prägnanz von HQL sowie die Dynamik von Kriterien in Betracht gezogen werden .
Querydsl unterstützt JPA / Hibernate, JDO, SQL und Collections.
Ich bin der Betreuer von Querydsl, daher ist diese Antwort voreingenommen.
quelle
Für mich ist Criteria ein ziemlich leicht zu verstehendes und dynamisches Abfragen. Aber der Fehler, den ich bisher sage, ist, dass es alle Beziehungen mit vielen Einsen usw. lädt, weil wir nur drei Arten von FetchModes haben, nämlich Select, Proxy und Default, und in all diesen Fällen lädt er viele Einsen (möglicherweise irre ich mich, wenn dies hilft mich raus :))
Das zweite Problem mit Criteria ist, dass es ein vollständiges Objekt lädt. Wenn ich also nur EmpName eines Mitarbeiters laden möchte, wird es nicht mit diesem Instant angezeigt. Es wird ein vollständiges Employee-Objekt erstellt, und ich kann EmpName daraus abrufen, da es wirklich schlecht funktioniert Berichterstattung . Wo als HQL nur geladen wurde (Assoziationen / Relationen wurden nicht geladen), was Sie wollen, erhöhen Sie die Leistung um ein Vielfaches.
Ein Merkmal von Criteria ist, dass es Sie aufgrund seiner dynamischen Abfragegenerierung vor SQL Injection schützt, wobei wie in HQL Ihre Abfragen entweder fest oder parametrisiert sind und daher nicht vor SQL Injection sicher sind.
Auch wenn Sie HQL in ur aspx.cs-Dateien schreiben, sind Sie eng mit ur DAL verbunden.
Insgesamt bin ich zu dem Schluss gekommen, dass es Orte gibt, an denen Sie ohne HQL-ähnliche Berichte nicht leben können. Verwenden Sie sie daher, sonst sind die Kriterien einfacher zu verwalten.
quelle
Kriterien-API
Die Kriterien-API eignet sich besser für dynamisch generierte Abfragen. Wenn Sie also WHERE-Klauselfilter, JOIN-Klauseln oder die ORDER BY-Klausel oder die Projektionsspalten hinzufügen möchten, kann Ihnen die Kriterien-API dabei helfen, die Abfrage dynamisch so zu generieren, dass auch SQL Injection-Angriffe verhindert werden .
Auf der anderen Seite sind Kriterienabfragen weniger aussagekräftig und können sogar zu sehr komplizierten und ineffizienten SQL-Abfragen führen, wie in diesem Artikel erläutert .
JPQL und HQL
JPQL ist die Abfragesprache für JPA-Standardentitäten, während HQL JPQL erweitert und einige Hibernate-spezifische Funktionen hinzufügt.
JPQL und HQL sind sehr ausdrucksstark und ähneln SQL. Im Gegensatz zur Criteria API erleichtern JPQL und HQL die Vorhersage der zugrunde liegenden SQL-Abfrage, die vom JPA-Anbieter generiert wird. Es ist auch viel einfacher, die eigenen HQL-Abfragen zu überprüfen als die Kriterien.
Es ist erwähnenswert, dass die Auswahl von Entitäten mit JPQL- oder Kriterien-API sinnvoll ist, wenn Sie sie ändern müssen. Ansonsten ist eine DTO-Projektion eine viel bessere Wahl.
Fazit
Wenn Sie die Struktur der Entitätsabfrage nicht ändern müssen, verwenden Sie JPQL oder HQL. Wenn Sie die Filter- oder Sortierkriterien oder die Projektion ändern müssen, verwenden Sie die Kriterien-API.
Nur weil Sie JPA oder Hibernate verwenden, bedeutet dies nicht, dass Sie kein natives SQL verwenden sollten. SQL-Abfragen sind sehr nützlich und JPQL und die Kriterien-API sind kein Ersatz für SQL. In diesem Artikel finden Sie weitere Informationen zu diesem Thema.
quelle
Für mich ist der größte Gewinn bei Criteria die Beispiel-API, bei der Sie ein Objekt übergeben können und der Ruhezustand eine Abfrage basierend auf diesen Objekteigenschaften erstellt.
Abgesehen davon hat die Kriterien-API ihre Macken (ich glaube, das Hibernate-Team überarbeitet die API) wie:
Ich verwende normalerweise HQL, wenn ich Abfragen ähnlich wie SQL möchte (Löschen von Benutzern, bei denen status = 'blockiert'), und ich verwende Kriterien, wenn ich kein Anhängen von Zeichenfolgen verwenden möchte.
Ein weiterer Vorteil von HQL ist, dass Sie alle Ihre Abfragen vorab definieren und sogar in eine Datei oder so auslagern können.
quelle
Criteria API bietet eine bestimmte Funktion, die weder SQL noch HQL bieten. dh. Es ermöglicht die Überprüfung der Kompilierungszeit einer Abfrage.
quelle
Am Anfang haben wir in unserer Anwendung hauptsächlich Kriterien verwendet, aber nachdem sie aufgrund von Leistungsproblemen durch HQL ersetzt wurde.
Hauptsächlich verwenden wir sehr komplexe Abfragen mit mehreren Verknüpfungen, was zu mehreren Abfragen in Kriterien führt, aber in HQL sehr optimiert ist.
Der Fall ist, dass wir nur einige Eigenschaften für ein bestimmtes Objekt verwenden und keine vollständigen Objekte. Bei Criteria war das Problem auch die Verkettung von Zeichenfolgen.
Angenommen, Sie müssen den
(name || ' ' || surname)
Vor- und Nachnamen des Benutzers in HQL anzeigen, dies ist recht einfach , in Crteria ist dies jedoch nicht möglich.Um dies zu überwinden, verwendeten wir ResultTransormers, bei denen es Methoden gab, bei denen eine solche Verkettung für das erforderliche Ergebnis implementiert wurde.
Heute verwenden wir hauptsächlich HQL wie folgt:
In unserem Fall handelt es sich bei den zurückgegebenen Datensätzen also um Karten der benötigten Eigenschaften.
quelle
Quelle
quelle
CriteriaUpdate<T>
undCriteriaDelete<T>
als Referenz.Kriterienabfrage für dynamisch können wir eine Abfrage basierend auf unseren Eingaben erstellen. Im Fall einer Hql-Abfrage ist die statische Abfrage, sobald wir sie erstellt haben, können wir die Struktur der Abfrage nicht ändern.
quelle
Ich möchte hier kein totes Pferd treten, aber es ist wichtig zu erwähnen, dass Kriterienabfragen jetzt veraltet sind. Verwenden Sie HQL.
quelle
Ich bevorzuge auch Kriterienabfragen für dynamische Abfragen. Aber ich bevorzuge hql zum Löschen von Abfragen, zum Beispiel, wenn alle Datensätze aus der untergeordneten Tabelle für die übergeordnete ID 'xyz' gelöscht werden. Dies wird von HQL leicht erreicht, aber für die Kriterien-API müssen wir zuerst n Anzahl der Löschabfragen auslösen, wobei n die Anzahl der untergeordneten Abfragen ist Tabellendatensätze.
quelle
Die meisten Antworten hier sind irreführend und erwähnen, dass sie
Criteria Queries
langsamer sind alsHQL
, was eigentlich nicht der Fall ist.Wenn Sie tief eintauchen und einige Tests durchführen, werden Sie feststellen, dass Kriterienabfragen viel besser abschneiden als reguläres HQL .
Und auch mit Criteria Query erhalten Sie eine objektorientierte Steuerung, die mit HQL nicht vorhanden ist .
Für weitere Informationen lesen Sie diese Antwort hier .
quelle
Es geht auch anders. Am Ende habe ich einen HQL-Parser erstellt, der auf der ursprünglichen Syntax im Ruhezustand basiert, sodass zuerst der HQL analysiert und dann dynamische Parameter dynamisch eingefügt oder automatisch einige allgemeine Filter für die HQL-Abfragen hinzugefügt werden können. Es funktioniert super!
quelle
Dieser Beitrag ist ziemlich alt. Die meisten Antworten beziehen sich auf Ruhezustandskriterien, nicht auf JPA-Kriterien. JPA 2.1 fügte CriteriaDelete / CriteriaUpdate und EntityGraph hinzu, die steuern, was genau abgerufen werden soll. Die Kriterien-API ist besser, da Java OO ist. Deshalb wird JPA erstellt. Wenn JPQL kompiliert wird, wird es in den AST-Baum (OO-Modell) übersetzt, bevor es in SQL übersetzt wird.
quelle
HQL kann Sicherheitsbedenken wie SQL-Injection verursachen.
quelle