Wprowadzenie do interfejsu API kryteriów
Istnieją dwa sposoby pisania zapytań do bazy danych w Hibernate:
- Hibernacja języka zapytań
- API kryteriów
Pierwszą poznałeś już dawno temu, czas zapoznać się z API Criteria. To bardzo potężne narzędzie, w pewnym momencie było nawet bardziej popularne niż HQL. Teraz nie jest już tak popularny, ale do niektórych zadań na pewno będzie lepszym rozwiązaniem niż HQL.
W każdym razie nie możesz nauczyć się Hibernate bez zapoznania się z API Criteria. Napiszmy mały przykład, a następnie go przeanalizujemy. Na przykład poprosimy wszystkich pracowników (Employee) z bazy danych. Oto, co otrzymamy:
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();
Wygląda na skomplikowane. Napiszmy to samo zapytanie HQL dla porównania:
String hqlQuery = "from Employee";
Query<Employee> query = session.createQuery(hqlQuery);
List<Employee> results = query.getResultList();
Zwróć uwagę, że ostatnie dwa wiersze obu przykładów są prawie identyczne: tworzymy obiekt Query i używamy go do uzyskania listy. To sugeruje, że pozostałe linie robią coś identycznego.
Spójrz na wiersze 3 i 4 pierwszego przykładu:
Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);
Zapiszmy je w jednym wierszu:
critQuery.select(critQuery.from(Employee.class));
Czy ci to nic nie przypomina? A jeśli pokolorujesz to trochę inaczej:
critQuery.select(critQuery.from(Employee.class));
Tak, to taka skomplikowana konstrukcja zapytania SELECT FROM.
Przykłady pracy z interfejsem API kryteriów
Dla lepszego zrozumienia podam tylko kilka przykładów.
Żądanie 1 . Zdobądź wszystkich pracowników z pensją powyżej 10 tys.:
critQuery.select(critQuery.from(Employee.class)).where(builder.gt(root.get("salary"), 10000));
Żądanie 2 . Zdobądź wszystkich pracowników z pensją poniżej 50 tysięcy:
critQuery.select(critQuery.from(Employee.class)).where(builder.lt(root.get("salary"), 50000));
Żądanie 3 . Zdobądź wszystkich pracowników, których stanowisko zawiera słowo „test”:
critQuery.select(critQuery.from(Employee.class)).where(builder.like(root.get("occupation"), "%test%"));
Prośba 4 . Zdobądź wszystkich pracowników z pensją od 10 do 50 tysięcy:
critQuery.select(critQuery.from(Employee.class)).where(builder.between(root.get("salary"), 10000, 50000));
Prośba 5 . Pobierz wszystkich pracowników, których nazwa jest pusta:
critQuery.select(critQuery.from(Employee.class)).where(builder.isNull(root.get("name")));
Żądanie 6 . Uzyskaj wszystkich pracowników, których nazwa nie jest pusta:
critQuery.select(critQuery.from(Employee.class)).where(builder.isNotNull(root.get("name")));
To taki trudny sposób na zbudowanie zapytania:
- Najpierw dostajesz przedmiotCriteriaBuilder.
- Następnie użyj go do stworzenia obiektuZapytanie o kryteria.
- Następnie zaczynasz dodawać do niego części za pomocąZapytanie o kryteriaICriteriaBuilder.
W ten sposób możesz ustawić parametry dla:
- WYBIERAĆ
- Z
- GDZIE
Używając równieżCriteriaBuildermożesz skonstruować różne warunki dla GDZIE.
Zaawansowana praca z Criteria API
Za pomocą Criteria API możesz skonstruować zapytanie o dowolnej złożoności. I to jest świetna wiadomość. Na przykład potrzebujesz złożonej klauzuli WHERE. Oto jak to zrobić:
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));
Jeśli chcesz napisać AND zamiast OR, wystarczy zmienić ostatnią linię:
critQuery.select(critQuery.from(Employee.class)).where(builder.and(greaterThan, testers));
Wszystko jest właściwie bardzo proste. Podam tabelę z kilkoma porównaniami:
SQL | metoda | Pełny zapis |
---|---|---|
a<b | lt(a, b) | budowniczy.lt(a, b) |
a > b | gt(a, b) | budowniczy.gt(a, b) |
a lub B | lub (a, b) | budowniczy.or(a, b) |
a ORAZ b | i(a,b) | budowniczy.i(a,b) |
LIKE b | jak (a, b) | budowniczy.jak(a, b) |
a MIĘDZY (c, d) | pomiędzy (a, c, d) | budowniczy.między(a, c, d) |
a JEST NULL | isNull(a) | builder.isNull(a) |
a NIE JEST NULL | isNotNull(a) | builder.isNotNull(a) |
Wszystko jest proste, prawda?
A jak dodać sortowanie do zapytania? Bardzo prosta:
critQuery.select( critQuery.from(Employee.class) );
critQuery.where( builder.and(greaterThan, testers) );
critQuery.orderBy( builder.asc(root.get("salary"), builder.desc(root.get("joinDate") )
Po prostu wywołujesz obiektZapytanie o kryteriaorderBy () i przekazać do niej wymagane parametry.
Oto jak to samo zapytanie wyglądałoby w HQL. Porównywać:
select * from Employee where (…) and (…) order by 'salary' asc, 'joinDate' desc
Musisz tylko pamiętać o 3 rzeczach:
- Operatory klawiszy, takie jak SELECT, FROM, WHERE, są wywoływane na obiekcieZapytanie o kryteria.
- Operatory pomocnicze, takie jak AND, OR, DESC, są wywoływane na obiekcieCriteriaBuilder.
- Nazwy pól są pobierane z obiektu przez get()źródło.
GO TO FULL VERSION