Einführung in die Kriterien-API
Es gibt zwei Möglichkeiten, Datenbankabfragen in Hibernate zu schreiben:
- Abfragesprache für den Ruhezustand
- Kriterien-API
Den ersten haben Sie schon vor langer Zeit kennengelernt, jetzt ist es an der Zeit, sich mit der Criteria API vertraut zu machen. Dies ist ein sehr leistungsfähiges Tool, irgendwann war es sogar beliebter als HQL. Mittlerweile ist es nicht mehr so beliebt, aber für manche Aufgaben wird es definitiv eine bessere Lösung als HQL sein.
Auf jeden Fall können Sie Hibernate nicht erlernen, ohne sich mit der Criteria API vertraut zu machen. Schreiben wir ein kleines Beispiel und analysieren es dann. Beispielsweise werden wir alle Mitarbeiter (Employee) aus der Datenbank abfragen. Das bekommen wir:
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Employee> critQuery = builder.createQuery(Employee.class);
Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);
Query<Employee> query = session.createQuery(critQuery);
List<Employee> results = query.getResultList();
Sieht kompliziert aus. Schreiben wir zum Vergleich dieselbe HQL-Abfrage:
String hqlQuery = "from Employee";
Query<Employee> query = session.createQuery(hqlQuery);
List<Employee> results = query.getResultList();
Beachten Sie, dass die letzten beiden Zeilen beider Beispiele nahezu identisch sind: Wir erstellen ein Query-Objekt und verwenden es, um eine Liste abzurufen. Dies deutet darauf hin, dass die restlichen Zeilen etwas Ähnliches tun.
Schauen Sie sich die Zeilen 3 und 4 des ersten Beispiels an:
Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);
Schreiben wir sie in eine Zeile:
critQuery.select(critQuery.from(Employee.class));
Erinnert es dich an nichts? Und wenn Sie es etwas anders färben:
critQuery.select(critQuery.from(Employee.class));
Ja, das ist eine so knifflige Konstruktion der SELECT FROM-Abfrage.
Beispiele für die Arbeit mit der Criteria API
Zum besseren Verständnis werde ich nur einige Beispiele nennen.
Anfrage 1 . Erhalten Sie alle Mitarbeiter mit einem Gehalt über 10.000:
critQuery.select(critQuery.from(Employee.class)).where(builder.gt(root.get("salary"), 10000));
Anfrage 2 . Erhalten Sie alle Mitarbeiter mit einem Gehalt von weniger als 50.000:
critQuery.select(critQuery.from(Employee.class)).where(builder.lt(root.get("salary"), 50000));
Anfrage 3 . Holen Sie sich alle Mitarbeiter, deren Berufsbezeichnung das Wort „test“ enthält:
critQuery.select(critQuery.from(Employee.class)).where(builder.like(root.get("occupation"), "%test%"));
Anfrage 4 . Erhalten Sie alle Mitarbeiter mit einem Gehalt von 10 bis 50.000:
critQuery.select(critQuery.from(Employee.class)).where(builder.between(root.get("salary"), 10000, 50000));
Anfrage 5 . Holen Sie sich alle Mitarbeiter, deren Name null ist:
critQuery.select(critQuery.from(Employee.class)).where(builder.isNull(root.get("name")));
Anfrage 6 . Rufen Sie alle Mitarbeiter ab, deren Name nicht null ist:
critQuery.select(critQuery.from(Employee.class)).where(builder.isNotNull(root.get("name")));
Es ist einfach eine knifflige Art, eine Abfrage zu erstellen:
- Zuerst erhalten Sie das ObjektCriteriaBuilder.
- Verwenden Sie es dann, um ein Objekt zu erstellenCriteriaQuery.
- Dann beginnen Sie mit dem Hinzufügen von TeilenCriteriaQueryUndCriteriaBuilder.
So können Sie Parameter einstellen für:
- WÄHLEN
- AUS
- WO
Wird auch verwendetCriteriaBuilderSie können verschiedene Bedingungen für WHERE konstruieren.
Fortgeschrittene Arbeit mit der Kriterien-API
Mithilfe der Kriterien-API können Sie eine Abfrage beliebiger Komplexität erstellen. Und das sind großartige Neuigkeiten. Sie benötigen beispielsweise eine komplexe WHERE-Klausel. So geht's:
Predicate greaterThan = builder.gt(root.get("salary"), 1000);
Predicate testers = builder.like(root.get("occupation"), "test%");
critQuery.select(critQuery.from(Employee.class)).where(builder.or(greaterThan, testers));
Wenn Sie AND statt OR schreiben möchten, müssen Sie nur die letzte Zeile ändern:
critQuery.select(critQuery.from(Employee.class)).where(builder.and(greaterThan, testers));
Eigentlich ist alles ganz einfach. Lassen Sie mich Ihnen eine Tabelle mit einigen Vergleichen geben:
SQL | Methode | Vollständige Aufzeichnung |
---|---|---|
a<b | lt(a, b) | builder.lt(a, b) |
a > b | gt(a, b) | builder.gt(a, b) |
A oder B | oder(a,b) | builder.or(a, b) |
A und B | und(a,b) | builder.and(a,b) |
a LIKE b | wie(a,b) | builder.like(a, b) |
a ZWISCHEN (c, d) | zwischen(a, c, d) | builder.between(a, c, d) |
a IST NULL | isNull(a) | builder.isNull(a) |
a IST NICHT NULL | isNotNull(a) | builder.isNotNull(a) |
Alles ist einfach, nicht wahr?
Und wie fügen wir der Abfrage eine Sortierung hinzu? Sehr einfach:
critQuery.select( critQuery.from(Employee.class) );
critQuery.where( builder.and(greaterThan, testers) );
critQuery.orderBy( builder.asc(root.get("salary"), builder.desc(root.get("joinDate") )
Sie rufen einfach das Objekt aufCriteriaQueryorderBy()- Methode und übergeben Sie ihr die erforderlichen Parameter.
So würde dieselbe Abfrage in HQL aussehen. Vergleichen:
select * from Employee
where (…) and (…)
order by 'salary' asc, 'joinDate' desc
Sie müssen sich nur drei Dinge merken:
- Schlüsseloperatoren wie SELECT, FROM, WHERE werden für ein Objekt aufgerufenCriteriaQuery.
- Hilfsoperatoren wie AND, OR, DESC werden für das Objekt aufgerufenCriteriaBuilder.
- Feldnamen werden per get() vom Objekt übernommenWurzel.