Wprowadzenie

W tym poradniku będziemy omawiać Hibernate i Java Persistence API (JPA) – z naciskiem na różnice między nimi.

Zaczniemy od zbadania czym jest JPA, jak jest używane i jakie są podstawowe koncepcje stojące za nim.

Następnie przyjrzymy się, jak Hibernate i EclipseLink pasują do tego obrazu.

Object-Relational Mapping

Zanim zagłębimy się w JPA, ważne jest, aby zrozumieć koncepcję Object-Relational Mapping – znaną również jako ORM.

Object-relational mapping jest po prostu procesem przechowywania dowolnego obiektu Java bezpośrednio do tabeli bazy danych. Zazwyczaj nazwa obiektu staje się nazwą tabeli, a każde pole w tym obiekcie staje się kolumną. Po skonfigurowaniu tabeli każdy wiersz odpowiada rekordowi w aplikacji.

Wprowadzenie do JPA

Java Persistence API, lub JPA, jest specyfikacją, która definiuje zarządzanie relacyjnymi danymi w aplikacji Java. API odwzorowuje zestaw pojęć, które określają, które obiekty w aplikacji powinny być utrzymywane i jak powinny być utrzymywane.

Ważne jest, aby zauważyć, że JPA jest tylko specyfikacją i że potrzebuje implementacji, aby działać – ale więcej na ten temat później.

Teraz omówmy niektóre z podstawowych pojęć JPA, które musi obejmować implementacja.

3.1. Entity

Klasa javax.persistence.Entity definiuje, które obiekty powinny być persystowane do bazy danych. Dla każdej persystowanej encji JPA tworzy nową tabelę w ramach wybranej bazy danych.

Dodatkowo, wszystkie wybrane encje powinny definiować klucz główny oznaczony adnotacją @Id. Wraz z adnotacją @GeneratedValue definiujemy, że klucz główny powinien być automatycznie generowany podczas persystencji rekordu do bazy danych.

Przyjrzyjrzyjmy się szybkiemu przykładowi encji opisanej przez JPA.

@Entitypublic class Car { @GeneratedValue @Id public long id; // getters and setters}

Pamiętajmy, że obecnie nie będzie to miało żadnego wpływu na aplikację – JPA nie dostarcza żadnego kodu implementacyjnego.

3.2. Trwałość pól

Kolejną podstawową koncepcją JPA jest trwałość pól. Kiedy obiekt w Javie jest zdefiniowany jako encja, wszystkie pola w nim zawarte są automatycznie przechowywane jako różne kolumny w tabeli encji.

Jeśli istnieje pole w obrębie przechowywanego obiektu, którego nie chcemy przechowywać w bazie danych, możemy zadeklarować pole jako przejściowe za pomocą adnotacji @Transient.

3.3. Relacje

Następnie, JPA określa, jak powinniśmy zarządzać relacjami pomiędzy różnymi tabelami bazy danych w naszej aplikacji. Jak już widzieliśmy, JPA obsługuje to za pomocą adnotacji. Istnieją cztery adnotacje relacji, o których musimy pamiętać:

  1. @OneToOne
  2. @OneToMany
  3. @ManyToOne
  4. @ManyToMany

Przyjrzyjmy się, jak to działa:

@Entitypublic class SteeringWheel { @OneToOne private Car car // getters and setters}

W naszym powyższym przykładzie, klasa SteeringWheel opisuje relację jeden do jednego z naszą klasą Car z wcześniejszego przykładu.

3.4. Entity Manager

Na koniec, klasa javax.persistence.EntityManager określa operacje do i z bazy danych. EntityManager zawiera typowe operacje tworzenia, odczytu, aktualizacji i usuwania (CRUD), które są przechowywane w bazie danych.

Wdrożenia JPA

Mając specyfikację JPA określającą, jak i co powinniśmy przechowywać, musimy teraz wybrać dostawcę implementacji, który dostarczy niezbędny kod. Bez takiego dostawcy, musielibyśmy zaimplementować wszystkie odpowiednie klasy, aby być w zgodzie z JPA, a to wymaga dużo pracy!

Jest wiele dostawców do wyboru, a każdy z nich ma swoje wady i zalety. Podejmując decyzję, którego z nich użyć, powinniśmy rozważyć kilka z następujących punktów:

  1. Dojrzałość projektu – jak długo dostawca istnieje i jak dobrze jest udokumentowany?
  2. Podprojekty – czy dostawca ma jakieś przydatne podprojekty dla naszej nowej aplikacji?
  3. Wsparcie społeczności – czy jest ktoś, kto nam pomoże, gdy trafimy na krytyczny błąd?
  4. Benchmarking – jak wydajna jest implementacja?

Chociaż nie będziemy się zagłębiać w benchmarkowanie różnych dostawców JPA, JPA Performance Benchmark (JPAB) zawiera cenny wgląd w tę kwestię.

With that out of the way, let’s take a brief look at some of the top providers of JPA.

Hibernate

At its core, Hibernate is an object-relational mapping tool that provides an implementation of JPA. Hibernate jest jedną z najbardziej dojrzałych implementacji JPA, z ogromną społecznością wspierającą projekt.

Implementuje wszystkie klasy javax.persistence, którym przyglądaliśmy się wcześniej w artykule, jak również zapewnia funkcjonalność wykraczającą poza JPA – narzędzia Hibernate, walidację i wyszukiwanie. Chociaż te API specyficzne dla Hibernate mogą być użyteczne, nie są one potrzebne w aplikacjach, które wymagają tylko podstawowej funkcjonalności JPA.

Przyjrzyjrzyjmy się szybko temu, co Hibernate oferuje z adnotacją @Entity.

Podczas gdy spełnia kontrakt JPA, @org.hibernate.annotations.Entity dodaje dodatkowe metadane, które wykraczają poza specyfikację JPA. Pozwala to na precyzyjne dostrojenie trwałości encji. Dla przykładu, przyjrzyjmy się kilku adnotacjom oferowanym przez Hibernate, które rozszerzają funkcjonalność @Entity:

  1. @Table – pozwala nam określić nazwę tabeli utworzonej dla encji
  2. @BatchSize – określa rozmiar partii podczas pobierania encji z tabeli

Warto również zwrócić uwagę na kilka dodatkowych funkcji, których JPA nie określa, a które mogą okazać się przydatne w większych aplikacjach:

  1. Dostosowywalne instrukcje CRUD z adnotacjami @SQLInsert, @SQLUpate i @SQLDelete
  2. Wsparcie dla miękkiego usuwania
  3. Immutowalne encje z adnotacją @Immutable

Dla głębszego zanurzenia się w Hibernate i persystencji w Javie – przejdź do naszej serii tutoriali na temat persystencji w Spring.

EclipseLink

EclipseLink, zbudowany przez Eclipse Foundation, dostarcza otwartą implementację JPA. Dodatkowo, EclipseLink wspiera wiele innych standardów persystencji, takich jak Java Architecture for XML Binding (JAXB).

Po prostu, zamiast utrzymywać obiekt w wierszu bazy danych, JAXB mapuje go do reprezentacji XML.

Następnie, porównując tę samą implementację adnotacji @Entity, widzimy, że EclipseLink oferuje ponownie różne rozszerzenia. Podczas gdy nie ma adnotacji dla @BatchSize, jak widzieliśmy wcześniej, EclipseLink oferuje inne opcje, których Hibernate nie oferuje.

Na przykład:

  1. @ReadOnly – określa, że encja, która ma być przechowywana jest tylko do odczytu
  2. @Struct – definiuje klasę do mapowania do bazy danych typu 'struct’

Aby przeczytać więcej o tym, co EclipseLink ma do zaoferowania, przejdź do naszego przewodnika po EclipseLink ze Springiem.

Zakończenie

W tym artykule przyjrzeliśmy się Java Persistence API, czyli JPA.

Na koniec zbadaliśmy, czym różni się od Hibernate i EclipseLink.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.