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ă.