Spring Data JPA vs Spring JDBC Template
Tworząc współcześnie aplikacje webowe mamy do wyboru mnogość języków, standardów, frameworków itp. Nawet w obrębie samej Javy podjąć musimy wiele decyzji, dotyczących tego, które narzędzia będą najbardziej pasować do naszego projektu.
Jedną z takich decyzji jest wybór technologii, z wykorzystaniem której pobierać będziemy dane z baz danych. Jednym z najczęściej wybieranych narzędzi w tym zakresie jest Spring Data JPA, który w bardzo szerokim zakresie eliminuje złożoność dostępu do danych, ilość kodu, który trzeba napisać, by dostęp ten uzyskać, itp. Nie odbywa się to jednak całkowicie bezkosztowo. W niektórych przypadkach wartą uwagi alternatywą będzie narzędzie Spring JDBC Template – co do zasady lżejsze i prostsze, choć wymagające większego zaangażowania ze strony programisty. W niniejszym artykule omówimy krótko oba podejścia, wskazując na wady i zalety każdego z nich.
Spring Data JPA a Spring JDBC Template
Spring Data JPA jest częścią projektu Spring Data opracowaną w celu zapewnienia abstrakcji wyższego poziomu dla JPA (Java Persistance API), które z kolei jest specyfikacją wykorzystywaną do mapowania obiektów (wykorzystywanych w programowaniu obiektowym) do struktur właściwych dla relacyjnych baz danych (mapowanie obiektowo-relacyjne; ORM). Do funkcji Spring Data JPA (poza implementowaniem ORM) należy automatyczne generowanie zapytań, obsługa repozytoriów itp. Narzędzie to eliminuje złożoność dostępu do danych pomagając programistom mapować obiekty Javy na jednostki bazy danych i odwrotnie, przy konieczności wytworzenia niewielkiej ilości kodu. Zapytania bazodanowe tworzące, odczytujące czy aktualizujące dane generowane mogą być automatycznie przez Spring Data JPA na podstawie nazw metod Javy.
Spring JDBC Template jest narzędziem umożliwiającym uzyskanie dostępu do bazy danych z wykorzystaniem Java Database Connectivity (JDBC) – kolejnego API Javy, które pozwala na łączenie się z bazami danych oraz wykonywanie zapytań. Narzędzie to jest lżejsze, prostsze i bardziej elastyczne w porównaniu z wcześniej omawianym, ponieważ nie zawiera tak złożonych i skomplikowanych abstrakcji jak Spring Data JPA, w szczególności nie wspiera ORM. Zapytania bazodanowe nie są generowane automatycznie, ale tworzone ręcznie przez programistów.
Mając za sobą krótką prezentację obu narzędzi możemy przejść do najistotniejszej części, czyli zestawienia ze sobą obu technologii w kontekście różnych aspektów.
Przekazywanie zapytania SQL
Jako pierwsze kryterium porównania przyjmiemy sposób przekazania zapytania SQL do bazy danych. W przypadku Spring Data JPA odbywa się ono automatycznie – zapytanie generowane jest na podstawie nazw metod przez samo narzędzie. JDBC Template prezentuje w tym zakresie odmienne podejście – zapytanie bazodanowe tworzone musi być każdorazowo ręcznie przez programistę. Oba podejścia mają swoje dobre i słabe strony, a wybór odpowiedniego zależy od potrzeb konkretnej aplikacji. Spring Data JPA pozwala na sprawniejsze i czytelniejsze wykonywanie standardowych zapytań bazodanowych (zapis, odczyt i modyfikacja relatywnie prostych obiektów). Z drugiej strony, jeżeli w ramach warstwy repository dokonać musimy np. odczytu danych pochodzących z wielu tablic, a przy tym wykorzystać wiele złożonych złączeń, podzapytań itp., lepszym rozwiązaniem będzie JDBC Template, w ramach którego samodzielnie stworzymy i przekażemy do bazy danych zapytanie, mając pewność, że jest ono właściwe, a przy tym omijając narzut wynikający z automatycznego generowania przez Spring Data JPA.
Rozwijając powyższy akapit przyjąć można za kryterium porównania także kontrolę nad zapytaniem oraz możliwość jego dostosowywania do swoich potrzeb. Co do zasady są one znacznie szersze w przypadku JDBC Template. W przypadku Spring Data JPA z założenia przekazujemy narzędziu kompetencje w zakresie wygenerowania SQLa, zyskując w zamian prostotę i czytelność kodu.
Mapowanie obiektu
Z wcześniejszymi różnicami wiąże się kolejna, czyli sposób mapowania obiektu. Spring Data JPA dokonuje tego zasadniczo za programistę, wspierając ORM. W przypadku JDBC Template to twórca aplikacji musi ręcznie wskazać, w jaki sposób poszczególne jednostki bazy danych przełożone mają zostać na obiekty Javy (w szczególności – wartości z których kolumn zasilić mają poszczególne pola). Podobnie, jak w poprzednim przypadku, oba mają swoje plusy i minusy, które uzasadniają ich użycie w konkretnych sytuacjach. Konieczność zapisywania, modyfikowania i pobierania wielu standardowych obiektów Javy, które w bazie danych odzwierciedlone są jako tablice w stosunku niemal jeden do jednego uzasadnia użycie Spring Data JPA, zwalniając programistę nie tylko od każdorazowego tworzenia zapytań, ale także od każdorazowego wskazywania, która jednostka bazodanowa ma zostać przełożona na konkretny obiekt. Jeżeli jednak mamy do czynienia z przeciwną sytuacją – koniecznością pobrania złożonego zestawu danych, to automatyczne mapowanie tworzyć może duży i zbędny narzut związany nie tylko z koniecznością samego przemapowania, ale także utrzymywania zarzązanych przez Spring Data JPA encji javowych. W takim przypadku zasadne staje się użycie JDBC Template, utworzenie zwykłej klasy posiadającej niezbędne pola i ręczne wskazanie, jak należy przenieść poszczególne dane z bazy do aplikacji Javy.
Rozwijając poprzedni akapit przyjąć możemy za kolejne kryterium porównania obsługę mapowania obiektowo-relacyjnego (ORM) przez poszczególne narzędzia. Spring Data JPA oferuje takie wsparcie w pełnym zakresie, przez co możliwe jest opisane wyżej automatyczne mapowanie, wraz ze wskazanymi konsekwencjami. JDBC Template ponownie znajduje się po przeciwnej stronie barykady, nie zapewniając w ogóle wsparcia dla ORM, co jednak – jak wykazano w poprzednim akapicie – nie zawsze musi być interpretowane negatywnie.
Wydajność no właśnie
Oba narzędzia porównać możemy także pod względem wydajności. W tym kontekście zwycięzcą jest Spring JDBC Template, który bezpośrednio integruje się z bazą danych. W przypadku Spring Data JPA dochodzi narzut związany przede wszystkim ze wsparciem dla ORM. Co do zasady spadek wydajności nie jest jednak znaczący i można go pominąć, biorąc pod uwagę korzyści wynikające z zastosowania tego narzędzia (vide: wcześniejsze przykłady).
Buforowanie?
Kolejnym kryterium porównania Spring Data JPA oraz JDBC Tempate może być możliwość buforowania. Pierwsze z narzędzi ma w tym zakresie wbudowane wsparcie, drugie z nich takiej funkcjonalności nie posiada. Brak wsparcie dla buforowania nie musi jednak eliminować JDBC Tempate – możliwe jest skorzystanie z innych narzędzi dostarczających tę funkcjonalność.
W końcu – wspomnieć należy, że choć oba narzędzia dostosowane są do użytkowania z większością popularnych baz danych, to jednak jeżeli zależy nam na naprawdę szerokiej kompatybilności, wybrać należy JDBC Tempate, które może współpracować z każdą bazą, dla której istnieje sterownik JDBC. W przypadku Spring Data JPA zakres ten jest nieco węższy.
A zatem
Podsumowując, oba opisane narzędzia należą do tego samego frameworka, którym jest Spring i bez problemu integrują się z jego pozostałymi komponentami. Oba posiadają obszerną dokumentację, wsparcie, rozbudowaną społeczność itp. Realizują one tożsamy cel, którym jest umożliwienie wymiany danych z bazą danych, przy czym reprezentują w tym zakresie zasadniczo odmienne podejścia. Mając na uwadze fakt, że zmiana narzędzia dostępu do danych w działającym projekcie nie jest trywialna, warto zastanowić się już na etapie tworzenia, które z nich będzie bardziej adekwatne dla naszych potrzeb.