Frage

Was sind die Vor- und Nachteile der Verwendung? Kriterien oder HQL?Die Kriterien-API ist eine nette objektorientierte Möglichkeit, Abfragen in Hibernate auszudrücken, aber manchmal sind Kriterienabfragen 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 eine Frage des Geschmacks?

War es hilfreich?

Lösung

Ich ziehe es vor allem Kriterien Abfragen für dynamische Abfragen. Zum Beispiel ist es viel einfacher, etwas Ordnung dynamisch hinzuzufügen, oder einige Teile (zum Beispiel Einschränkungen) aus, je nach gewissen Parametern zu verlassen.

Auf der anderen Seite ich HQL für statische und komplexe Abfragen bin mit, denn es ist viel einfacher zu verstehen / lesen HQL. Auch HQL ist ein bisschen stärker, glaube ich, zum Beispiel für verschiedene Join-Typen.

Andere Tipps

Es gibt einen Leistungsunterschied zwischen HQL und CriteriaQuery. Jedes Mal, wenn Sie eine Abfrage mit CriteriaQuery auslösen, wird ein neuer Alias ​​für den Tabellennamen erstellt, der sich im zuletzt abgefragten Cache für keine Datenbank widerspiegelt.Dies führt zu einem Mehraufwand beim Kompilieren des generierten SQL, wodurch die Ausführung mehr Zeit in Anspruch nimmt.

In Bezug auf Abrufstrategien [http://www.hibernate.org/315.html]

  • Criteria respektiert die Laziness-Einstellungen in Ihren Zuordnungen und garantiert, dass das geladen wird, was Sie laden möchten.Dies bedeutet, dass eine Kriterienabfrage zu mehreren sofortigen SQL-SELECT-Anweisungen führen kann, um den Untergraphen mit allen nicht verzögert zugeordneten Zuordnungen und Sammlungen abzurufen.Wenn Sie das „Wie“ und sogar das „Was“ ändern möchten, verwenden Sie setFetchMode(), um den Outer-Join-Abruf für eine bestimmte Sammlung oder Zuordnung zu aktivieren oder zu deaktivieren.Kriterienabfragen respektieren auch vollständig die Abrufstrategie (Join vs. Select vs. Subselect).
  • HQL respektiert die Laziness-Einstellungen in Ihren Zuordnungen und garantiert, dass das geladen wird, was Sie laden möchten.Dies bedeutet, dass eine HQL-Abfrage zu mehreren sofortigen SQL-SELECT-Anweisungen führen kann, um den Untergraphen mit allen nicht verzögert zugeordneten Zuordnungen und Sammlungen abzurufen.Wenn Sie das „Wie“ und sogar das „Was“ ändern möchten, verwenden Sie LEFT JOIN FETCH, um den Outer-Join-Abruf für eine bestimmte Sammlung oder eine nullbare Viele-zu-Eins- oder Eins-zu-Eins-Zuordnung zu aktivieren, oder JOIN FETCH, um dies zu aktivieren Inner-Join-Abruf für eine nicht nullbare Viele-zu-Eins- oder Eins-zu-Eins-Zuordnung.HQL-Abfragen berücksichtigen keine im Zuordnungsdokument definierten fetch="join".

Kriterien ist eine objektorientierte API, während HQL String-Verkettung bedeutet. Das bedeutet, dass alle Vorteile der Objektorientierung gelten:

  1. alles andere gleich ist, ist die OO-Version etwas weniger fehleranfällig. Jede alte Zeichenfolge könnte get in die HQL-Abfrage angehängt, während nur gültige Kriterien Objekte, die es in einen Kriterienbaum machen können. Effektiv sind die Kriterien Klassen eingeschränkteren.
  2. Mit auto-complete ist die OO mehr auffindbar (und damit einfacher zu bedienen, zumindest für mich). Sie müssen nicht unbedingt merken müssen, welche Teile der Abfrage gehen, wohin; die IDE können Sie
  3. Hilfe
  4. Sie brauchen auch nicht die Einzelheiten der Syntax zu erinnern (wie die Symbole gehen, wo). Alles, was Sie wissen müssen, ist, wie Methoden aufrufen und Objekte erstellen.

Da HQL sehr ähnlich wie SQL ist (die meisten Entwickler wissen schon sehr gut), dann diese „müssen sich nicht erinnern“ Argumente tragen nicht so viel Gewicht. Wenn HQL mehr anders ist, dann wäre dies mehr importatnt sein.

Ich verwende in der Regel Kriterien, wenn ich weiß nicht, was die Eingänge auf, welche Teile der Daten verwendet werden. Wie auf ein Suchformular, wo der Benutzer jeden von 1 bis 50 Artikeln eingeben und weiß nicht ich, was sie für sein zu suchen. Es ist sehr einfach, nur mehr die Kriterien anfügen, wie ich durch die Überprüfung für das, was die Nutzer suchen. Ich denke, es wäre ein wenig mehr lästig sein, eine HQL-Abfrage in diesem Umstand zu setzen. HQL ist aber groß, wenn ich weiß genau, was ich will.

HQL ist viel einfacher zu lesen, einfacher zu debuggen Tools wie Eclipse Hibernate-Plugin und einfacher zu protokollieren. Kriterien Abfragen sind besser für die Entwicklung dynamische Abfragen, wo viel über das Verhalten zur Laufzeit bestimmt wird. Wenn Sie nicht über SQL wissen, konnte ich verstehen Kriterien Abfragen mit, aber alles in allem ziehe ich HQL, wenn ich weiß, was ich im Voraus möchten.

Kriterien sind die einzige Möglichkeit, natürliche Schlüssel-Lookups zu spezifizieren, die die Vorteile der speziellen Optimierung in der zweiten Ebene Abfrage-Cache nehmen. HQL hat keine Möglichkeit, den notwendigen Hinweis angeben.

Sie können einige weitere Informationen finden Sie hier:

Kriterien Api ist eine der guten Konzept von Hibernate. nach meiner Ansicht das ist der wenige Punkt, mit dem wir Unterschied zwischen HQL machen und Kriterien Api

  1. HQL ist sowohl wählen und Nicht-Auswahl-Operationen auf den Daten durchzuführen, sondern Kriterien sind nur die Daten für die Auswahl, können wir nicht Nicht-Auswahl-Operationen unter Verwendung von Kriterien erfüllen.
  2. ist HQL geeignet für statische Abfragen ausführen, wobei als Kriterien für die Ausführung dynamische Abfragen
  3. geeignet ist
  4. HQL nicht unterstützt Paginierung Konzept, aber wir können Paginierung mit Kriterien erreichen.
  5. Kriterien verwendet, um mehr Zeit in Anspruch nehmen als HQL auszuführen.
  6. Mit Criteria wir sind sicher mit SQL Injection wegen seiner dynamischen Abfrage Generation, sondern in HQL als Ihre Anfragen entweder fest oder parametrisiert, gibt es keinen Schutz vor SQL-Injection

Für mich Criteria ist ein recht einfach zu verstehen und dynamische Abfragen machen. Aber der Fehler sagen, dass ich so weit ist, dass es lädt alle many-one etc Beziehungen, weil wir nur drei Arten von FetchModes dh Select haben, Proxy und Standard und in all diesen Fällen ist es many-one lädt (kann ich falsch bin, wenn so helfen me out:))

2. Ausgabe mit Kriterien ist, dass es komplettes Objekt dh lädt, wenn ich möchte nur EmpName eines Mitarbeiters lädt es wird nicht damit kommen insted es mit komplettem Employee-Objekt kommt, und ich kann aufgrund dieser EmpName von ihm bekommen es wirklich schlecht arbeitet in der Berichterstattung . wo als HQL nur Last (did't Last Verband / Beziehungen), was u so Leistung wollen viele Male erhöhen.

Ein Merkmal von Kriterien ist, dass es sicher u von SQL-Injection wegen seiner dynamischen Abfrage Generation, wo, wie in HQL als ur-Abfragen entweder fest oder parametriert, so ist nicht sicher vor SQL-Injection.

Auch wenn Sie HQL in ur aspx.cs Dateien schreiben, dann sind Sie eng gekoppelt mit ur DAL.

Insgesamt meine Schlussfolgerung ist, dass es Orte gibt, wo u nicht ohne HQL leben können wie Berichte so sie sonst Kriterien verwenden leichter zu verwalten ist.

, um das Beste aus beiden Welten zu nutzen, die Expressivität und Prägnanz von HQL und der dynamischen Natur von Kriterien prüfen, mit Querydsl .

Querydsl unterstützt JPA / Hibernate, JDO, SQL und Sammlungen.

Ich bin der Maintainer von Querydsl, so dass diese Antwort ist voreingenommen.

Der größte Vorteil von Criteria ist für mich die Beispiel-API, mit der Sie ein Objekt übergeben können und der Ruhezustand eine Abfrage basierend auf diesen Objekteigenschaften erstellt.

Abgesehen davon hat die Kriterien-API ihre Eigenheiten (ich glaube, das Hibernate-Team überarbeitet die API), wie zum Beispiel:

  • a Kriterien.createAlias("obj") erzwingt einen inneren Join anstelle eines möglichen äußeren Joins
  • Sie können denselben Alias ​​nicht zweimal erstellen
  • Einige SQL-Klauseln haben kein Gegenstück zu einfachen Kriterien (z. B. eine Unterauswahl).
  • usw.

Ich neige dazu, HQL zu verwenden, wenn ich SQL-ähnliche Abfragen möchte (aus Benutzern löschen, bei denen der Status = „blockiert“ ist), und ich verwende eher Kriterien, wenn ich das Anhängen von Zeichenfolgen nicht verwenden möchte.

Ein weiterer Vorteil von HQL besteht darin, dass Sie alle Ihre Abfragen vorab definieren und sie sogar in eine Datei oder ähnliches auslagern können.

Kriterien API ist besser geeignet für dynamisch generierten Abfragen, wenn die Abfragefilter dynamisch zur Laufzeit angewendet werden. Deshalb, um zu verhindern Injection-Angriffe wenn dynamische Abfragen erstellen, Criteria API ist eine sehr gute Wahl.

Kriterien Abfragen sind weniger ausdrucksvoll und man kann leicht mit einem sehr komplizierten und ineffizienten SQL generierte Abfrage . Ich kam einmal eine große Enterprise-Anwendung, wo Criteria API der Standardabfragemethode war und nicht einmal umfangreiche Code-Reviewing den Schrecken nicht zu wissen, welche SQL-Abfragen, mit denen wir gehen, um am Ende überwinden konnte.

JPQL oder HQL ist viel ausdrucksvoller, und es ist viel einfacher, die zugehörige generierten SQL-Abfrage zu prognostizieren. Es ist auch viel einfacher zu jemandes HQL-Abfragen als Kriterien diejenigen zu überprüfen.

Die meisten Unternehmen anfragende Anwendungsfälle erfordern keine dynamischen where-Klauseln so können Sie die meisten Abfragen mit JPQL implementieren, während Kriterien für die dynamisch diejenigen zu verlassen.

Es ist erwähnenswert, dass die Auswahl Einheiten mit JPQL oder Criteria API Sinn machen, wenn Sie sie ändern müssen. Andernfalls führt eine DTO Projektion besser. Schauen Sie sich diesem Artikel für weitere Informationen .

Kriterien api bietet ein besonderes Merkmal, dass weder SQL oder HQL bietet. dh. es erlaubt Zeit Überprüfung einer Abfrage kompilieren.

Wir haben in erster Linie Kriterien in unserer Anwendung am Anfang, aber nachdem es mit HQL aufgrund der Performance-Probleme ersetzt.
Hauptsächlich verwenden wir sehr komplexe Abfragen mit mehreren Verbindungen, bei denen in Kriterien zu mehreren Abfragen führt aber in HQL sehr optimiert ist.
Der Fall ist, dass wir nur einige propeties auf bestimmtes Objekt und nicht die kompletten Objekte verwenden. Mit Kriterien war das Problem auch String-Verkettung.
Lassen Sie sagen, wenn Sie Vor- und Nachname des Benutzers in HQL angezeigt werden müssen es ist ganz einfach (name || ' ' || surname) aber in Crteria dies nicht möglich ist.
Um dies zu überwinden wir verwendet ResultTransormers, wo es Methoden waren, wo solche Verkettung wurde benötigt Ergebnis realisiert.
Heute sind wir in erster Linie HQL verwenden wie folgt aus:

String hql = "select " +
            "c.uuid as uuid," +
            "c.name as name," +
            "c.objective as objective," +
            "c.startDate as startDate," +
            "c.endDate as endDate," +
            "c.description as description," +
            "s.status as status," +
            "t.type as type " +
            "from " + Campaign.class.getName() + " c " +
            "left join c.type t " +
            "left join c.status s";

Query query =  hibernateTemplate.getSessionFactory().getCurrentSession().getSession(EntityMode.MAP).createQuery(hql);
query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
return query.list();

so in unserem Fall die zurückgegebenen Datensätze sind Karten der benötigten Eigenschaften.

  • HQL ist sowohl wählen und Nicht-Auswahl-Operationen auf den Daten durchzuführen, sondern Kriterien sind nur die Daten für die Auswahl, können wir nicht Nicht-Auswahl-Operationen Kriterien erfüllen mit
  • ist HQL geeignet für statische Abfragen ausführen, wobei als Kriterien für die Ausführung dynamische Abfragen
  • geeignet ist
  • HQL nicht Paginierung Konzept unterstützen, aber wir können Paginierung mit Kriterien erreichen
  • Kriterien verwendet, um mehr Zeit in Anspruch nimmt dann HQL auszuführen
  • Mit Criteria wir mit SQL Injection sicher sind wegen ihrer dynamischen Abfrage Generation, sondern in HQL als Ihre Anfragen entweder fest oder parametrisiert, gibt es keinen Schutz vor SQL-Injection.

Quelle

Kriterien Abfrage dynamisch wir Abfrage auf der Grundlage unseres inputs..In Fall von HQL-Abfrage erstellen können, ist die statische Abfrage einmal konstruieren wir, dass wir nicht die Struktur der Abfrage ändern.

Ich will nicht ein totes Pferd hier treten, aber es ist wichtig, dass die Kriterien Abfragen zu erwähnen, jetzt veraltet sind. Verwenden HQL.

Ich habe auch lieber Kriterien Abfragen für dynamische Abfragen. Aber ich hql für Löschanfragen bevorzugen, zum Beispiel löschen, wenn alle Datensätze aus untergeordneter Tabelle für Eltern id ‚xyz‘ wird es leicht von HQL erreicht, sondern nach Kriterien API zuerst müssen wir n die Anzahl der Löschabfrage abfeuern, wo n die Anzahl des Kindes Tabelleneinträge.

Die meisten Antworten hier sind irreführend und erwähnen, dass Criteria Queries sind langsamer als HQL, was tatsächlich nicht der Fall ist.

Wenn Sie tauchen tief und einige Tests durchführen, die Sie sehen, Kriterien Abfragen durchführen viel besser, dass regelmäßiger HQL .

Und auch mit Kriterien Abfrage Sie erhalten Objektorientierte Steuerung , die mit nicht da ist HQL .

Für weitere Informationen lesen Sie diese Antwort hier .

Es gibt eine andere Art und Weise. I endete mit einem HQL-Parser auf Hibernate ursprünglichen Syntax basierend Schaffung also zuerst die HQL parsen dann könnte es dynamisch dynamische Parameter injizieren oder automatisch einige gemeinsame Filter für die HQL Abfragen hinzugefügt wird. Es funktioniert großartig!

Dieser Beitrag ist ziemlich alt. Die meisten Antworten sprechen über Hibernate Kriterien, nicht JPA Kriterien. JPA 2.1 hinzugefügt CriteriaDelete / CriteriaUpdate und EntityGraph, der steuert, was genau zu holen. Criteria API ist besser, da Java ist OO. Deshalb JPA erstellt wird. Wenn JPQL kompiliert wird, wird es an AST Baum (OO-Modell) zu SQL übersetzt, bevor übersetzt werden.

HQL kann dazu führen, Sicherheit Bedenken wie SQL-Injection.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top