
Po zabawie ze Springiem pozostajemy w tematach kodowania jednocześnie wracając do zagadnień związanych z SQL i DBMS. W tym odcinku dowiemy się czym jest ORM i jak z jego pomocą uprościć sobie pracę z bazami danych.
Uwaga! W tej serii zajmuję się opisowym przedstawieniem tematu, a celem jest zapoznanie z zagadnieniem w sposób luźny i zrozumiały dla nowicjusza. W związku z tym wiele elementów siłą rzeczy musi zostać pominiętych. Tych z was, którzy chcieliby się dowiedzieć więcej, zapraszam do źródeł na końcu artykułu.
Lato w pełni. Wakacje.
Kumpel właśnie zaprosił cię na ognisko poza miastem. Idziesz, bo co będziesz siedział w domu i czekał aż ojciec znajdzie dla ciebie jakieś „bojowe zadanie”.
Jesteście na miejscu, zaczyna się zbierać ekipa… Kurde, sporo ludzi… Myślałeś, że będzie tylko wasza paczka, a tu już całe stado i wciąż pojawiają się nowi.
Nie znasz tych osób. Koledzy zniknęli gdzieś, pewnie w poszukiwaniu gałęzi i chrustu. Zaczynasz się zastanawiać czy nie pożegnać się po angielsku i wrócić na chatę. Może jakoś uda się znaleźć ogarniętych randomów na rundkę w LoL’a.
Rozglądasz się ostatni raz przed odejściem i wtedy zauważasz Ją.
Stoi obok innej dziewczyny, chyba swojej koleżanki, zajętej rozmową z jakimś gościem. Minę ma nietęgą, najwidoczniej również myślała, że imprezka będzie miała bardziej kameralny charakter.
To co przykuwa twoją uwagę to jej koszulka – z emblematem niszowego zespołu, o którym nikt tutaj pewnie nie słyszał. Oprócz ciebie.
Byłeś na ich koncercie zeszłego lata. Spodobało ci się. Też kupiłeś ich T-shirt, który teraz właśnie masz na sobie.
Obserwowana dziewczyna rozgląda się i zauważa, że na nią patrzysz. Zerka na twoje ubranie i szczerze się uśmiecha. Ma bardzo ładny uśmiech.

Dzisiaj na tapet weźmiemy dwóch zawodników:
Hibernate & Liquibase
Co prawda to ten pierwszy jest znacznie częściej obecny w wymaganiach ofert pracy, ale tylko dlatego, że znajomość Liquibase’a jest z jednej strony tak oczywista, a z drugiej tak banalna, że HR-owcom po prostu szkoda marnować na to klawiatury.
Zacznijmy może od krótkiego przedstawienia obu rozwiązań, na potrzeby narracji nazywając ich młodymi wilkami.

Sponsorem niniejszego artykułu jest angielskie słówko:
„persistence”
które możemy tłumaczyć na polskie „trwałość„, „stałość„, czy nawet „zawziętość„, ale że żadne z nich nie oddaje poprawnego znaczenia w odniesieniu do naszego kontekstu, to jesteśmy zmuszeni spolonizować je na:
„persystencja”
utrwalenie/zachowanie czegoś (np. danych) na później
JPA czyli skrót od Java Persistence API, jest interfejsem dostępu do baz danych o którym mówiliśmy już sobie w poprzednim wpisie. To był ten kawałek o niezwykłym interfejsie któremu Spring dynamicznie buduje klasę będącą mostem pomiędzy aplikacją, a DBMS-em.
Ale to nie wszystko.
Zostaje jeszcze Hibernate. A jest to narzędzie typu ORM czyli Object Relational Mapping. Po przetłumaczeniu na polski otrzymamy „relacyjne mapowanie obiektów„, które też jest trochę jak transfunkcjoner kontinuum:

Chodzi po prostu o to, że klasa którą oddamy Hibernate’owi w zarządzanie, automatycznie staje się tabelą w bazie danych. Kluczem do tej symbiozy są tak zwane:
Encje
czyli klasy zaczynające się od adnotacji @Entity, np.
@Entity
public class Person{
@Id
int id;
String name;
double height;
LocalDate birthday;
}
Kiedy stworzymy sobie powyższą klasę* i zrobimy z niej encję za pomocą adnotacji @Entity to odpalając projekt, automatycznie powstaje nam tabela o nazwie „person” z kolumnami:
- id
- name
- height
- birthday
(*) Musimy jeszcze pamiętać o bezparametrowym konstruktorze, adnotacji @Id przy kluczu głównym, getterach i setterach, ale to detale w które tutaj nie będziemy się zagłębiać.

I tyle. Już znasz Hibernate’a, możemy iść dalej.
Poważnie. To co opisałem powyżej to esencja mapowania relacyjnego, które powstało aby zredukować tłuste linie boilerplate’owego kodu do zaledwie kilku adnotacji. Gdybyśmy to samo chcieli pisać w czystej Javie to najpierw musielibyśmy otworzyć połączenie, potem przygotować tzw. Statement (a raczej obiekt tej klasy) z odpowiednim wyrażeniem SQL, dodać do tego instancję PreparedStatement w celu edycji w/w tabeli, a na koniec zamknąć połączenie*.
(*) Czego byśmy zaraz żałowali, bo takie swobodne otwieranie/zamykanie połączenia z bazą spowalnia działanie programu. Spring Boot rozwiązuje ten problem tzw. pulą połączeń z bazą, która ładuje się przy starcie („HikariPool„) i działa podobnie do puli wątków.
Migracje baz danych
Mam nadzieję, że pamiętacie czym jest Git. To to narzędzie do „sejwowania” stanu naszego projektu i swobodnego przechodzenia z jednego zapisu do drugiego.
Odpowiednikiem Gita w świecie SQL-a są narzędzia do migracji, takie jak Liquibase czy Flyway.

Ten pierwszy jest bardziej popularny komercyjnie i częściej pojawia się w ofertach zatrudnienia. Po pierwsze oferuje więcej możliwości, po drugie – użytkownicy chwalą sobie jego prostotę.
Ale jak to działa?
Właśnie trochę tak jak Git. Każdą zmianę w bazie danych notujecie w przygotowanym do tego pliku (xml/json/yml/sql) – dzięki temu można w jednym miejscu sprawdzić wszelkie zmiany jakie się dokonywały, co np. pomaga w debugowaniu. No i przede wszystkim ułatwia przenosiny z jednego DBMS-a na inny, jeśli chcemy przetestować różne rozwiązania.

Musimy zdać sobie sprawę, że dużych programów nie tworzy się od razu mając 100% pewność jak będą one wyglądać na końcu procesu developmentu. W trakcie rozwoju pojawiają się nowe pomysły, zmiany w architekturze, tworzone są agregaty i zwykłe encje, ustalane są relacje pomiędzy nimi, zmieniane są nazwy kolumn czy typy danych, które są w nich zawarte.
Dzięki Liquibase możemy prześledzić tę ewolucję od samego początku aż do stanu obecnego.

Spring i Hibernate to bardzo podobne do siebie rozwiązania problemów trapiących programistów Javy. Oba zdejmują z nich masę niewdzięcznej roboty, oba robią to za pomocą prostych adnotacji. Świetnie się uzupełniają, nic więc dziwnego, że spotkawszy się na wakacyjnym ognisku Spring z miejsca zauroczył się w Hibernate jak tylko ich spojrzenia się spotkały.
Owszem, nic nie stoi na przeszkodzie aby korzystać ze Springa bez żadnego ORM-a i osobiście przejąć kontrolę nad DBMS-em.

Nikt nam również nie zabroni użycia konkurencyjnych rozwiązań takich jak MyBatis, Ebean czy ActiveJDBC. Też są dobre i nawet od czasu do czasu można je obczaić w jakichś projektach. Jednak to Hibernate jest najpopularniejszym frameworkiem do zarządzania bazami danych z poziomu Springa:
- bo ich współpraca trwa już od 10 lat (Hibernate dołączył do Spring Boota w 2014 roku) czyli przeszła próbę czasu i ma doskonałe wsparcie społeczności
- bo ma wiele przydatnych funkcji/ustawień (tj. caching, transactions, lazy/eager loading, optimistic locking) jak również dodatkowych bibliotek uzupełniających braki
No i oczywiście dlatego, że gładko integruje się ze springowym JPA. Ową integrację możemy zobaczyć w interfejsach dostępu do bazy (tzw. JPQL: Java Persistence Query Language), w ustanawianiu relacji między tabelami, w rozwiązywaniu problemów związanych z jednymi klasami-encjami dziedziczącymi po innych klasach-encjach. Raz nawet przyłapałem ich jak się intensywnie integrowali na moim biurku! Z początku chciałem rozgonić towarzystwo, ale ech, co mi tam
Niech się młodzi sobą nacieszą.
Tak udane związki ten Springa z Hibernate’m nie zdarzają się codziennie.
Źródła:
ORM, JPA, Hibernate, Spring Data JPA – wyjaśnienie YT/POL
Blog Przemka Bykowskiego: Kurs Hibernate (POL)
Blog Przemka Bykowskiego: Flyway (POL)
Blog Przemka Bykowskiego: Liquibase (POL)
Liquibase ze Spring Boot YT/POL