Introducere în API-ul Criteria

Există două moduri de a scrie interogări de baze de date în Hibernate:

  • Limbajul de interogare Hibernate
  • Criterii API

L-ați întâlnit deja pe primul cu mult timp în urmă, este timpul să vă familiarizați cu API-ul Criteria. Acesta este un instrument foarte puternic, la un moment dat a fost chiar mai popular decât HQL. Acum nu mai este atât de popular, dar pentru unele sarcini va fi cu siguranță o soluție mai bună decât HQL.

În orice caz, nu poți învăța Hibernate fără să te familiarizezi cu API-ul Criteria. Să scriem un mic exemplu, apoi îl vom analiza. De exemplu, vom solicita toți angajații (Angajați) din baza de date. Iată ce vom obține:

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

Pare complicat. Să scriem aceeași interogare HQL pentru comparație:

String hqlQuery = "from Employee";

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

Rețineți că ultimele două rânduri ale ambelor exemple sunt aproape identice: creăm un obiect Query și îl folosim pentru a obține o Listă. Acest lucru sugerează că restul liniilor fac ceva identic.

Priviți rândurile 3 și 4 din primul exemplu:

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

Să le scriem într-un singur rând:

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

Nu-ți aduce aminte de nimic? Și dacă îl colorați puțin diferit:

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

Da, aceasta este o construcție atât de complicată a interogării SELECT FROM.

Exemple de lucru cu API-ul Criteria

Pentru o mai bună înțelegere, voi da doar câteva exemple.

Cerere 1 . Obțineți toți angajații cu un salariu peste 10 mii:

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

Cerere 2 . Obțineți toți angajații cu un salariu mai mic de 50 de mii:

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

Cerere 3 . Obțineți toți angajații al căror titlu de post conține cuvântul „test”:

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

Cerere 4 . Obțineți toți angajații cu un salariu de la 10 la 50 de mii:

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

Cerere 5 . Obțineți toți angajații al căror nume este nul:

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

Cerere 6 . Obțineți toți angajații al căror nume nu este nul:

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

Este o modalitate atât de dificilă de a construi o interogare:

  • Mai întâi primești obiectulCriteriaBuilder.
  • Apoi folosiți-l pentru a crea un obiectCriteriaQuery.
  • Apoi începeți să adăugați părți la elCriteriaQueryȘiCriteriaBuilder.

Iată cum puteți seta parametrii pentru:

  • SELECTAȚI
  • DIN
  • UNDE

De asemenea, folosindCriteriaBuilderpoti construi conditii diferite pentru UNDE.

Lucru avansat cu API-ul Criteria

Folosind API-ul Criteria, puteți construi o interogare de orice complexitate. Și aceasta este o veste grozavă. De exemplu, doriți o clauză WHERE complexă. Iată cum să o faci:

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

Dacă doriți să scrieți ȘI în loc de SAU, atunci trebuie să schimbați doar ultima linie:

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

Totul este de fapt foarte simplu. Permiteți-mi să vă dau un tabel cu câteva comparații:

SQL Metodă Înregistrare completă
a<b lt(a, b) builder.lt(a, b)
a > b gt(a, b) builder.gt(a, b)
a SAU b sau (a,b) constructor.sau (a, b)
a ȘI b și (a, b) constructor.și(a,b)
un LIKE b ca(a,b) constructor.like(a, b)
a INTRE (c, d) între (a, c, d) constructor.between(a, c, d)
a ESTE NUL este Null(a) constructor.isNull(a)
a NU ESTE NUL isNotNull(a) builder.isNotNull(a)

Totul este simplu, nu-i așa?

Și cum adăugăm sortarea la interogare? Foarte simplu:

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

Doar apelezi la obiectCriteriaQueryorderBy () și transmiteți-i parametrii necesari.

Iată cum ar arăta aceeași interogare în HQL. Comparaţie:

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

Trebuie doar să vă amintiți 3 lucruri:

  • Operatorii cheie precum SELECT, FROM, WHERE sunt apelați pe un obiectCriteriaQuery.
  • Operatori auxiliari precum AND, OR, DESC sunt apelați pe obiectCriteriaBuilder.
  • Numele câmpurilor sunt preluate din obiect prin intermediul get()rădăcină.