W procesie tworzenia kodu aplikacji, zdarzają się sytuacje, gdy z różnych powodów nie jest możliwe lub preferowane
korzystanie z gotowych rozwiązań oferowanych przez framework. Ta kwestia może dotyczyć również tworzenia zapytań, co
jest głównym tematem niniejszego rozdziału.
Zapytanie typu SELECT
Rozpocznijmy od analizy przykładu, który ilustruje pobieranie danych z bazy danych. Zauważ, że zastosowane
zapytanie wykorzystuje klauzulę
LIKE, która służy do porównywania ciągów tekstowych przekazanych metodzie z
zewnątrz. Zapytanie to zawiera również dodatkowe funkcjonalności manipulujące datami oraz konwersję identyfikatora
na typ
String. Całość zapytania jest przekazywana do frameworka do wykonania za pomocą adnotacji
@Query.
Teraz kilka uwag dotyczących tego na co należy zwrócić uwagę podczas tworzenia takiego zapytania:
- Parametry wykorzystywane w tekście zapytania poprzedzamy dwukropkiem: :searchValue
- Domyślnie parametry metody są przyporządkowane do parametrów z treści zapytania na podstawie kolejności miejsc, więc możemy NIE oznaczać parametrów metody za pomocą adnotacji @Param.
Takie podejście bywa jednak problematyczne, w przypadku ewentualnych zmian w metodzie w przyszłości, szczególnie w przypadku refactoringu.
- Stosujemy adnotację @Param, aby przyporządkować parametry metody do parametrów z treści zapytania na podstawie nazwy przekazanej do adnotacji. Nazwa
musi zgadzać się z nazwą użytą w treści zapytania (po dwukropku). Nie jest wtedy wymagana zgodność co do kolejności parametrów.
- W przypadku gdy chcemy dodać do zapytania opcje stronicowania Pageable lub sortowania Sort, dodajemy te typy
na ostatniej pozycji wśród parametrów metody. Jeśli potrzebujemy oba, będą zajmowały one ostatnie dwie pozycje.
Zapytanie typu UPDATE lub DELETE
Załóżmy, że potrzebujemy napisać własne zapytanie operujące na JPA, którego zadaniem będzie aktualizacja danych w systemie, w przypadku gdy zostanie spełniony określony warunek.
Napiszemy więc zapytanie z użyciem adnotacji
@Query, podobnie jak to robiliśmy dla zapytania pobierającego:
Zapytanie jest odpowiedzialne za wyczyszczenie wszystkich przedawnionych tokenów, czyli de facto dla wszystkich użytkowników, którzy nie zdążyli użyć wygenerowanego tokena przed upływem określonego czasu.
Patrząc na kod zauważamy kilka interesujących rzeczy:
- Zapytanie możemy zdefiniować jako stałą w kodzie i użyć go jako parametr adnotacji @Query
- Zapytanie modyfikujące musi być oznaczone adnotacją @Modifying
- Zapytanie modyfikujące musi być wykonane w ramach aktywnej transakcji, co osiągamy wprowadzając adnotację @Transactional
Podobnie będzie to wyglądało podczas tworzenia zapytania typu DELETE.
Rekomendacja
Dobrą praktyką jest używanie stałych do przechowywania zapytań, co zostało zilustrowane w ostatnim przykładzie.
Jest to szczególnie korzystne w przypadku, gdy interfejs zawiera liczne zapytania. Dzięki temu kod jest
bardziej uporządkowany, co przekłada się na jego lepszą czytelność.
Jako programiści musimy być gotowi na nieustanne zmiany i rozwój kodu, które często prowadzą do zwiększenia jego
złożoności. W związku z tym, istnieje możliwość, że w przyszłości zapytania wbudowane
(
Spring Data JPA
- Zapytania wbudowane) okażą się niewystarczające do realizacji niektórych operacji, co skłoni nas do stworzenia
omawianego właśnie zapytania własnego (Custom Query).
W niektórych przypadkach, nawet zapytania własne mogą nie spełniać wszystkich wymagań.
Dlatego Spring Data JPA oferuje jeszcze inną
metodę tworzenia zapytań, mianowicie zapytania natywne (czysty SQL), które zostaną omówione w kolejnym
rozdziale.
Praktyka
Przykłady przytoczone w tym rozdziale pochodzą z aplikacji z naszego mega pakietu.
Autor: Jarek Klimas
Data: 03 stycznia 2024
Labele: Backend, Podstawowy, Java
Czy informacje, które otrzymałeś, były pomocne?
Jeśli tak, zapraszam Cię do podarowania mi kawy.
[TEORIA i PRAKTYKA] Strefa doładowania wiedzy
W tej strefie znajdziesz wszystko co niezbędne, aby komfortowo uczyć się Hibernate'a.
Doskonale opisany kod nie zawiera zbędnych komplikacji, tylko samą esencję w postaci praktycznych przykładów.
Tutaj odnajdziesz wszystko co jest istotne w danym temacie. Otrzymujesz pakiet złożony z kilku projektów
wraz z obszernym wytłumaczeniem kodu.
Topowe Materiały
Spring IO: JPA Query Methods
Baeldung: Spring Data JPA – Adding a Method in All Repositories
Udemy: [NEW] Spring Boot 3, Spring 6 & Hibernate for Beginners — polskie napisy