1.1 Mapowanie klas na tabele
Po zapoznaniu się z JDBC najprawdopodobniej masz wrażenie, że praca z bazą danych z aplikacji Java to nadal przyjemność. A gdybym ci powiedział, że całą tę pracę można wykonać 10 razy łatwiej?
Jaka jest główna zaleta języka SQL? Jest to język deklaratywny - opisuje, co chcemy uzyskać, i nie mówi nic o tym, jak to zrobić. Jak - to jest problem serwera SQL.
To samo podejście można zastosować podczas pracy z bazami danych.
W idealnym świecie moglibyśmy po prostu pisać zapytania SQL do bazy danych, aw odpowiedzi otrzymywalibyśmy gotowe obiekty Java lub kolekcje obiektów Java, gdybyśmy zażądali kilku sztuk.
Cóż mogę powiedzieć, w 2000 roku kilku facetów pomyślało i zdecydowało się napisać własny framework ORM.
ORM to skrót od Object-Relational Mapping i jest zasadniczo mapowaniem obiektów Java na zapytania SQL.
Chłopaki wymyślili bardzo prostą rzecz - każda tabela w bazie danych musi odpowiadać jakiejś klasie w aplikacji Java . W aplikacji Java operujemy obiektami, a te obiekty już wiedzą, jak zapisać się do bazy danych.
Były trzy podejścia do rozwiązania tego problemu i wyglądały one mniej więcej tak:
- Obiekt zapisuje się do bazy danych i aktualizuje swoje pola na podstawie informacji z bazy danych.
- Obiekt jest w stanie zapisać się do bazy danych, ale nigdy nie inicjuje tej sprawy.
- Obiekt zawiera tylko dane, a ktoś zapisuje je do bazy danych i ładuje z bazy danych.
Początkowo dominowało to pierwsze podejście, potem popularne były serwery aplikacyjne i Enterprise Java Beans. Istniała nawet cała klasa komponentów bean zwanych Persistence EJB, które same mogły zapisywać się w bazie danych.
Ale pewnego dnia wszystko się zmieniło...
1.2 Pojawienie się hibernacji
W 2001 roku ukazała się pierwsza wersja frameworka Hibernate. Był to bardzo prosty framework, ale pozwalał na użycie zwykłych „głupich obiektów”, które nie wiedziały nic o tym, jak powinny być przechowywane w bazie danych lub stamtąd ładowane.
Mapowanie pól klas Javy i kolumn w tabeli w bazie danych zostało ustawione za pomocą pliku XML. A czasami były dość masywne. Dobra, kogo ja oszukuję. Były to potężne płótna kodu XML. A sytuację ratował tylko fakt, że 20 lat temu nie było tak gigantycznych baz danych jak teraz.
Ale tak naprawdę najpotężniejszą decyzją było ostateczne oddzielenie obiektu, który ma zostać zapisany w bazie danych, od kodu, który go tam zapisał . To rozwiązanie nie jest do końca oczywiste. Ponieważ zasada enkapsulacji mówi, że obiekt wie najlepiej, jak należy go zapisać i załadować.
A podejście ORM naprawdę łamie tę koncepcję. Klasa danych ujawnia swoją wewnętrzną strukturę, ale operowanie na grupach obiektów różnych typów stało się znacznie łatwiejsze.
Wielki przełom nastąpił po wydaniu Javy 5 , kiedy w JDK pojawiły się dwie rzeczy:
- Adnotacje
- pełnomocnik
AdnotacjeXML został szybko wyparty, a teraz łatwo było określić wszystkie niezbędne ustawienia do mapowania klasy Java na tabelę w bazie danych bezpośrednio w klasie Java.
Pełnomocniknie tak zauważalne dla użytkownika Hibernate, ale ich wkład był jeszcze poważniejszy. Kiedy żądasz określonego obiektu lub obiektów z Hibernate, po prostu zwraca ci kod pośredniczący (proxy) i przechwytuje wszystkie wywołania swoich metod.
Umożliwiło to zaimplementowanie różnych mechanizmów Lazy Loading oraz podniosło szybkość i wydajność Hibernate do zupełnie kosmicznego poziomu jak na tamte czasy. Hibernate stał się de facto standardem branżowym – zaczął być tłumaczony na inne języki. I tak na przykład dla C# pojawił się Framework NHibernate.
1.3 Pojawienie się WZP
Po de facto następuje uznanie de iure. Twórcy JDK postanowili stworzyć specyfikację dotyczącą poprawnego mapowania obiektów na tabele w bazie danych. Ta specyfikacja nazywa sięWZP- API trwałości Javy.
To jest właśnie specyfikacja. Opisuje, jak wszystko powinno działać i jakich adnotacji potrzebujemy, aby zaznaczyć różne części klasy, jeśli chcemy, aby jej obiekty zostały zapisane w bazie danych.
Wygląda na to, że chłopaki po prostu wzięli Hibernate jako podstawę i zmienili z niego nazwy pakietów. Ponieważ wszystkie adnotacje, które były w Hibernate, zostały przeniesione do JPA prawie jedna po drugiej.
Dziś Hibernate w pełni implementuje całą specyfikację JPA, a także kilka dodatkowych funkcji, dzięki którym praca z nim jest jeszcze wygodniejsza. Dlatego, jeśli chodzi o standaryzację, możemy powiedzieć, że Hibernate ma dwa zestawy funkcji:
- norma JPA
- Hibernate Native API (dodatkowa funkcjonalność)
Oficjalna dokumentacja Hibernate opisuje to w ten sposób:
Ale zarówno na podstawie mojego doświadczenia, jak i po ponownym przeczytaniu dokumentacji Hibernate, mogę powiedzieć, że JPA i Hibernate API są w 95% takie same. To są po prostu identyczne pojęcia.
1.4 Maven dla hibernacji
Ponieważ tak bardzo chwaliłem Hibernate, myślę, że nadszedł czas, aby przejść do trochę cięższej pracy z nim.
Po pierwsze, istnieje oficjalna strona, na której znajduje się tylko garść dokumentacji w języku angielskim. Ona, oczywiście, ma stronniczość w informacjach referencyjnych, a nie w szkoleniu. Ale to wciąż lepsze niż debugowanie źródeł, prawda? :)
Instrukcja:
- Otwierasz łącze .
- Patrzysz na nią długo.
- Wracając do CodeGym.
- Czytasz moje dalsze wykłady.
Moim zadaniem jest upraszczanie skomplikowanych rzeczy i wyjaśnianie ich w prosty sposób. A jeśli osiągnąłeś ten poziom, to mogę to zrobić.
Cóż, aby zacząć korzystać z Hibernate, musisz dodać go do pliku pom.xml. Na razie dostępna jest już 6. wersja Hibernate, a raczej 6.1.1, więc nauczymy się pracować z najnowszą wersją.
Po prostu dodaj te linie do pliku pom.xml:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>6.1.1.Final</version>
</dependency>
Jeśli czytasz ten wykład poza oknem 2023+, to nową wersję możesz pobrać tutaj .
Ważny! Niektóre biblioteki używane przez Hibernate zostały wycofane z JDK 11 i JDK 17, więc jeśli masz problemy z uruchomieniem projektu, dodaj do niego następujące zależności:
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.29.0-GA</version>
</dependency>
GO TO FULL VERSION