Introduksjon til Criteria API

Det er to måter å skrive databasespørringer på i Hibernate:

  • Hibernate Query Language
  • Kriterier API

Du har allerede møtt den første for lenge siden, det er på tide å bli kjent med Criteria API. Dette er et veldig kraftig verktøy, på et tidspunkt var det enda mer populært enn HQL. Nå er det ikke så populært lenger, men for noen oppgaver vil det definitivt være en bedre løsning enn HQL.

Uansett kan du ikke lære Hibernate uten å bli kjent med Criteria API. La oss skrive et lite eksempel, og så skal vi analysere det. For eksempel vil vi be om alle ansatte (Ansatt) fra databasen. Her er hva vi får:

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

Ser komplisert ut. La oss skrive det samme HQL-spørsmålet for sammenligning:

String hqlQuery = "from Employee";

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

Merk at de to siste linjene i begge eksemplene er nesten identiske: vi lager et spørreobjekt og bruker det til å få en liste. Dette antyder at resten av replikkene gjør noe identisk.

Se på linje 3 og 4 i det første eksemplet:

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

La oss skrive dem på én linje:

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

Minner det deg ikke om noe? Og hvis du farger det litt annerledes:

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

Ja, dette er en så vanskelig konstruksjon av SELECT FROM-spørringen.

Eksempler på arbeid med Criteria API

For en bedre forståelse vil jeg bare gi noen få eksempler.

Forespørsel 1 . Få alle ansatte med lønn over 10 tusen:

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

Forespørsel 2 . Få alle ansatte med lønn under 50 tusen:

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

Forespørsel 3 . Få alle ansatte hvis stillingstittel inneholder ordet "test":

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

Forespørsel 4 . Få alle ansatte med en lønn på 10 til 50 tusen:

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

Forespørsel 5 . Få alle ansatte hvis navn er null:

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

Forespørsel 6 . Få alle ansatte hvis navn ikke er null:

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

Det er bare en så vanskelig måte å lage en spørring på:

  • Først får du objektetCriteriaBuilder.
  • Bruk den deretter til å lage et objektCriteriaQuery.
  • Så begynner du å legge til deler til den medCriteriaQueryOgCriteriaBuilder.

Slik kan du angi parametere for:

  • PLUKKE UT
  • FRA
  • HVOR

Bruker ogsåCriteriaBuilderdu kan konstruere ulike forhold for HVOR.

Avansert arbeid med Criteria API

Ved å bruke Criteria API kan du lage en spørring av hvilken som helst kompleksitet. Og dette er gode nyheter. For eksempel vil du ha en kompleks WHERE-klausul. Slik gjør du det:

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

Hvis du vil skrive AND i stedet for OR, trenger du bare å endre den siste linjen:

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

Alt er faktisk veldig enkelt. La meg gi deg en tabell med noen sammenligninger:

SQL Metode Full rekord
a<b lt(a, b) byggherre.lt(a, b)
a > b gt(a, b) builder.gt(a, b)
a ELLER b eller(a,b) byggherre.eller(a,b)
a OG b og (a,b) byggherre.og(a,b)
a LIKER b som (a,b) builder.like(a, b)
a MELLOM (c, d) mellom (a, c, d) builder.between(a, c, d)
a ER NULL erNull(a) builder.isNull(a)
a ER IKKE NULL isNotNull(a) builder.isNotNull(a)

Alt er enkelt, er det ikke?

Og hvordan legger vi til sortering i spørringen? Veldig enkelt:

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

Du bare kaller på objektetCriteriaQueryorderBy() -metoden og send de nødvendige parameterne til den.

Slik ser det samme søket ut i HQL. Sammenligne:

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

Du trenger bare å huske 3 ting:

  • Nøkkeloperatorer som SELECT, FROM, WHERE kalles på et objektCriteriaQuery.
  • Hjelpeoperatorer som AND, OR, DESC kalles på objektetCriteriaBuilder.
  • Feltnavn hentes fra objektet via get()rot.