Inleiding tot de Criteria-API

Er zijn twee manieren om databasequery's in Hibernate te schrijven:

  • Hibernate Query-taal
  • Criteria-API

De eerste heb je al een hele tijd geleden ontmoet, het is tijd om kennis te maken met de Criteria API. Dit is een zeer krachtige tool, op een gegeven moment was het zelfs populairder dan HQL. Nu is het niet meer zo populair, maar voor sommige taken zal het zeker een betere oplossing zijn dan HQL.

In ieder geval kun je Hibernate niet leren zonder vertrouwd te raken met de Criteria API. Laten we een klein voorbeeld schrijven, en dan zullen we het analyseren. Zo zullen we alle medewerkers (Employee) uit de database opvragen. Dit is wat we zullen krijgen:

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();

Ziet er ingewikkeld uit. Laten we dezelfde HQL-query schrijven ter vergelijking:

String hqlQuery = "from Employee";

Query<Employee> query = session.createQuery(hqlQuery);
List<Employee> results = query.getResultList();

Merk op dat de laatste twee regels van beide voorbeelden bijna identiek zijn: we maken een Query-object en gebruiken het om een ​​Lijst te krijgen. Dit geeft aan dat de rest van de regels iets identieks aan het doen is.

Kijk naar regels 3 en 4 van het eerste voorbeeld:

Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);

Laten we ze op één regel schrijven:

critQuery.select(critQuery.from(Employee.class));

Herinnert het je nergens aan? En als je het een beetje anders kleurt:

critQuery.select(critQuery.from(Employee.class));

Ja, dit is zo'n lastige constructie van de SELECT FROM-query.

Voorbeelden van het werken met de Criteria API

Voor een beter begrip zal ik slechts enkele voorbeelden geven.

Verzoek 1 . Krijg alle werknemers met een salaris boven de 10 duizend:

critQuery.select(critQuery.from(Employee.class)).where(builder.gt(root.get("salary"), 10000));

Verzoek 2 . Krijg alle werknemers met een salaris van minder dan 50 duizend:

critQuery.select(critQuery.from(Employee.class)).where(builder.lt(root.get("salary"), 50000));

Verzoek 3 . Krijg alle werknemers van wie de functietitel het woord "test" bevat:

critQuery.select(critQuery.from(Employee.class)).where(builder.like(root.get("occupation"), "%test%"));

Verzoek 4 . Krijg alle werknemers met een salaris van 10 tot 50 duizend:

critQuery.select(critQuery.from(Employee.class)).where(builder.between(root.get("salary"), 10000, 50000));

Verzoek 5 . Krijg alle werknemers van wie de naam null is:

critQuery.select(critQuery.from(Employee.class)).where(builder.isNull(root.get("name")));

Verzoek 6 . Krijg alle werknemers van wie de naam niet null is:

critQuery.select(critQuery.from(Employee.class)).where(builder.isNotNull(root.get("name")));

Het is gewoon zo'n lastige manier om een ​​query te construeren:

  • Eerst krijg je het voorwerpCriteriaBuilder.
  • Gebruik het dan om een ​​object te makenCriteriaQuery.
  • Dan begin je er onderdelen aan toe te voegenCriteriaQueryEnCriteriaBuilder.

Zo kunt u parameters instellen voor:

  • SELECTEER
  • VAN
  • WAAR

Ook gebruikenCriteriaBuilderje kunt verschillende voorwaarden construeren voor WHERE.

Geavanceerd werken met Criteria API

Met behulp van de Criteria API kunt u een query van elke complexiteit maken. En dit is geweldig nieuws. U wilt bijvoorbeeld een complexe WHERE-component. Hier is hoe het te doen:

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));

Als je AND wilt schrijven in plaats van OR, hoef je alleen de laatste regel te wijzigen:

critQuery.select(critQuery.from(Employee.class)).where(builder.and(greaterThan, testers));

Alles is eigenlijk heel eenvoudig. Laat me je een tabel geven met een paar vergelijkingen:

SQL Methode Volledige opname
een<b Het(a,b) bouwer.lt(a, b)
een > b gt(a, b) bouwer.gt(a, b)
een OF b of(a,b) bouwer.of(a, b)
een EN b en(a,b) bouwer.en(a,b)
een LIKE b zoals (a,b) bouwer.like(a, b)
a TUSSEN (c, d) tussen(a, c, d) bouwer.between(a, c, d)
a IS NUL isNull(a) bouwer.isNull(a)
a IS NIET NULL isNotNull(a) bouwer.isNotNull(a)

Alles is eenvoudig, nietwaar?

En hoe voegen we sortering toe aan de query? Erg makkelijk:

critQuery.select( critQuery.from(Employee.class) );
critQuery.where( builder.and(greaterThan, testers) );
critQuery.orderBy( builder.asc(root.get("salary"), builder.desc(root.get("joinDate") )

Je roept gewoon het object aanCriteriaQueryorderBy () en geef de vereiste parameters door.

Zo ziet dezelfde query eruit in HQL. Vergelijken:

select * from Employee
where (…) and (…)
order by 'salary' asc, 'joinDate' desc

Je hoeft alleen maar 3 dingen te onthouden:

  • Key-operators zoals SELECT, FROM, WHERE worden op een object aangeroepenCriteriaQuery.
  • Hulpoperatoren zoals AND, OR, DESC worden op het object aangeroepenCriteriaBuilder.
  • Veldnamen worden via get() uit het object gehaaldwortel.