jako Specyfikacja, Java Persistence API dotyczy persistence, co luźno oznacza każdy mechanizm, za pomocą którego obiekty Java przetrwają proces aplikacji, który je utworzył. Nie wszystkie obiekty Java muszą być utrzymywane, ale większość aplikacji utrzymuje kluczowe obiekty biznesowe. Specyfikacja JPA pozwala określić, które obiekty powinny być przechowywane i w jaki sposób powinny być przechowywane w aplikacjach Java.
sam w sobie JPA nie jest narzędziem ani frameworkiem; definiuje raczej zestaw pojęć, które mogą być zaimplementowane przez dowolne narzędzie lub framework. Chociaż model mapowania obiektowo-relacyjnego (ORM) JPA był pierwotnie oparty na Hibernate, od tego czasu ewoluował. Podobnie, podczas gdy JPA był pierwotnie przeznaczony do użytku z relacyjnymi/SQL bazami danych, niektóre implementacje JPA zostały rozszerzone do użytku z magazynami danych NoSQL. Popularnym frameworkiem obsługującym JPA z NoSQL jest EclipseLink, implementacja referencyjna dla JPA 2.2.
JPA i Hibernate
ze względu na ich splecioną historię, Hibernate i JPA są często ze sobą powiązane. Jednak, podobnie jak Java Servlet specification, JPA stworzyło wiele kompatybilnych narzędzi i frameworków; Hibernate jest tylko jednym z nich.
opracowany przez Gavina Kinga i wydany na początku 2002 roku, Hibernate jest biblioteką ORM dla Javy. King opracował Hibernate jako alternatywę dla entity beans for persistence. Ramy były tak popularne i tak potrzebne w tym czasie, że wiele z ich pomysłów zostało przyjętych i skodyfikowanych w pierwszej specyfikacji WZP.
Hibernate ORM jest obecnie jedną z najbardziej dojrzałych implementacji JPA i nadal popularną opcją dla ORM w Javie. Hibernate ORM 5.3.8 (obecna wersja tego zapisu) implementuje JPA 2.2. Ponadto rodzina narzędzi Hibernate rozszerzyła się o popularne narzędzia, takie jak Hibernate Search, Hibernate Validator i Hibernate OGM, które obsługują trwałość modelu domeny dla NoSQL.
Co To jest Java ORM?
chociaż różnią się one wykonaniem, każda implementacja JPA dostarcza jakąś warstwę ORM. Aby zrozumieć narzędzia JPA i kompatybilne z JPA, musisz dobrze zrozumieć ORM.
mapowanie obiektowo-relacyjne jest zadaniem, którego deweloperzy mają dobry powód, aby unikać ręcznego wykonywania. Framework taki jak Hibernate ORM lub EclipseLink koduje to zadanie w bibliotekę lub framework, warstwę ORM. W ramach architektury aplikacji warstwa ORM jest odpowiedzialna za zarządzanie konwersją obiektów oprogramowania w celu interakcji z tabelami i kolumnami w relacyjnej bazie danych. W języku Java warstwa ORM konwertuje klasy i Obiekty Java, aby mogły być przechowywane i zarządzane w relacyjnej bazie danych.
Domyślnie nazwa przechowywanego obiektu staje się nazwą tabeli, a pola kolumnami. Po skonfigurowaniu tabeli każdy wiersz tabeli odpowiada obiektowi w aplikacji. Mapowanie obiektów jest konfigurowalne, ale domyślne zwykle działają dobrze.
Rysunek 1 ilustruje rolę JPA i warstwy ORM w tworzeniu aplikacji.
Konfigurowanie warstwy Java ORM
podczas konfigurowania nowego projektu do korzystania z JPA należy skonfigurować magazyn danych i dostawcę JPA. Skonfigurujesz łącznik magazynu danych, aby połączyć się z wybraną bazą danych (SQL lub NoSQL). Dołączysz również i skonfigurujesz dostawcę JPA, który jest frameworkiem takim jak Hibernate lub EclipseLink. Chociaż możesz skonfigurować JPA ręcznie, wielu programistów decyduje się na użycie gotowej do użycia pomocy technicznej Spring. Zobacz „Instalacja i konfiguracja JPA” poniżej, aby uzyskać demonstrację zarówno ręcznej, jak i sprężynowej instalacji i konfiguracji JPA.
trwałość danych w Javie
z punktu widzenia programowania warstwa ORM jest warstwą adaptera: dostosowuje język Wykresów obiektowych do języka SQL i tabel relacyjnych. Warstwa ORM umożliwia deweloperom zorientowanym obiektowo tworzenie oprogramowania, które utrzymuje dane bez opuszczania paradygmatu zorientowanego obiektowo.
gdy używasz JPA, tworzysz mapę z magazynu danych do obiektów modelu danych aplikacji. Zamiast definiować sposób zapisywania i pobierania obiektów, definiujesz mapowanie między obiektami a bazą danych, a następnie wywołujesz JPA, aby je zachować. Jeśli używasz relacyjnej bazy danych, Większość rzeczywistego połączenia między kodem aplikacji a bazą danych będzie następnie obsługiwana przez JDBC, interfejs API Java Database Connectivity API.
jako spec, JPA dostarcza adnotacje metadanych, których używasz do definiowania mapowania między obiektami a bazą danych. Każda implementacja JPA zapewnia własny silnik adnotacji JPA. Specyfikacja JPA zawiera również PersistanceManager
lub EntityManager
, które są kluczowymi punktami kontaktu z systemem JPA (w których kod logiki biznesowej mówi systemowi, co zrobić z zmapowanymi obiektami).
aby to wszystko było bardziej konkretne, rozważ Listing 1, który jest prostą klasą danych do modelowania muzyka.
Lista 1. Prosta klasa danych w Javie
Musician
klasa w liście 1 jest używana do przechowywania danych. Może zawierać prymitywne dane, takie jak pole nazwa. Może również utrzymywać relacje z innymi klasami, takimi jakmainInstrument
Iperformances
.
Musician
powodem istnienia jest zawieranie danych. Ten typ klasy jest czasami znany jako Dto lub obiekt transmisji danych. Dto są wspólną cechą rozwoju oprogramowania. Chociaż przechowują wiele rodzajów danych, nie zawierają żadnej logiki biznesowej. Utrzymywanie się obiektów danych jest powszechnym wyzwaniem w rozwoju oprogramowania.
trwałość danych z JDBC
jednym ze sposobów zapisania instancji klasyMusician
do relacyjnej bazy danych byłoby użycie biblioteki JDBC. JDBC jest warstwą abstrakcji, która pozwala aplikacji wydawać polecenia SQL bez myślenia o podstawowej implementacji bazy danych.
Listing 2 pokazuje, w jaki sposób można utrzymywać klasęMusician
używając JDBC.
Lista 2. JDBC wstawianie rekordu
kod w liście 2 jest dość samokontroli. ObiektgeorgeHarrison
może pochodzić z dowolnego miejsca (front-end submit, usługa zewnętrzna itp.) i ma ustawione pola ID i name. Pola w obiekcie są następnie wykorzystywane do podawania wartości polecenia SQLinsert
. (KlasaPreparedStatement
jest częścią JDBC, oferując sposób bezpiecznego stosowania wartości do zapytania SQL.)
chociaż JDBC pozwala na sterowanie, które jest dostarczane z ręczną konfiguracją, jest to kłopotliwe w porównaniu do JPA. Aby zmodyfikować bazę danych, należy najpierw utworzyć zapytanie SQL, które mapuje obiekt Java do tabel w relacyjnej bazie danych. Następnie musisz zmodyfikować SQL za każdym razem, gdy zmieni się podpis obiektu. W JDBC utrzymywanie SQL staje się zadaniem samym w sobie.
trwałość danych z JPA
rozważmy teraz Listing 3, gdzie utrzymujemy klasęMusician
używającą JPA.
Lista 3. Utrzymywanie George ’ a Harrisona za pomocą JPA
Musician georgeHarrison = new Musician(0, "George Harrison");musicianManager.save(georgeHarrison);
Listing 3 zastępuje ręczny SQL z listy 2 pojedynczą linią, session.save()
, który instruuje JPA, aby utrzymywał obiekt. Od tego momentu konwersją SQL zajmuje się framework, więc nigdy nie musisz opuszczać paradygmatu zorientowanego obiektowo.
adnotacje metadanych w JPA
Magia w liście 3 jest wynikiem konfiguracji, która jest tworzona przy użyciu adnotacji JPA. Programiści używają adnotacji, aby informować JPA, które obiekty powinny być utrzymywane i w jaki sposób powinny być utrzymywane.
Listing 4 pokazuje klasę Musician
z pojedynczą adnotacją JPA.
notowanie 4. Adnotacja JPA @Entity
@Entitypublic class Musician { // ..class body}
trwałe obiekty są czasami nazywane encjami. Dołączenie @Entity
do klasy takiej jak Musician
informuje JPA, że ta klasa i jej obiekty powinny być utrzymywane.
Konfigurowanie JPA
podobnie jak większość nowoczesnych frameworków, JPA obejmuje kodowanie zgodnie z konwencją (znaną również jako Konwencja nad konfiguracją), w której framework zapewnia domyślną konfigurację opartą na najlepszych praktykach branżowych. Jako przykład, klasa o nazwie Musician
będzie domyślnie mapowana do tabeli bazy danych o nazwie Musician.
konwencjonalna konfiguracja oszczędza czas i w wielu przypadkach działa wystarczająco dobrze. Możliwe jest również dostosowanie konfiguracji JPA. Jako przykład, możesz użyć adnotacji JPA @Table
, aby określić tabelę, w której powinna być przechowywana Klasa Musician
.
notowanie 5. Adnotacja JPA @Table
@Entity@Table(name="musician")public class Musician { // ..class body}
Listing 5 mówi JPA, aby utrzymywał encję (Musician
Klasa) domusician
tabela.
klucz podstawowy
w JPA klucz podstawowy jest polem używanym do jednoznacznej identyfikacji każdego obiektu w bazie danych. Klucz podstawowy jest przydatny do odwoływania się do obiektów i nawiązywania ich do innych podmiotów. Za każdym razem, gdy przechowujesz obiekt w tabeli, określasz również pole, które ma być używane jako jego klucz podstawowy.
w liście 6 mówimy JPA, którego pola użyć jako klucza podstawowegoMusician
.
notowanie 6. Określenie klucza podstawowego
@Entitypublic class Musician { @Id private Long id;
w tym przypadku użyliśmy adnotacji JPA @Id
, aby określić pole id
jako klucz podstawowy Musician
. Domyślnie, ta konfiguracja zakłada, że klucz podstawowy będzie ustawiony przez bazę danych-na przykład, gdy pole jest ustawione na automatyczne zwiększanie w tabeli.
JPA obsługuje inne strategie generowania klucza podstawowego obiektu. Posiada również adnotacje do zmiany poszczególnych nazw pól. Ogólnie rzecz biorąc, JPA jest wystarczająco elastyczny, aby dostosować się do wszelkich map trwałości, których możesz potrzebować.
operacje CRUD
Po zmapowaniu klasy do tabeli bazy danych i ustanowieniu jej klucza podstawowego masz wszystko, czego potrzebujesz, aby utworzyć, pobrać, usunąć i zaktualizować tę klasę w bazie danych. Wywołanie session.save()
utworzy lub zaktualizuje podaną klasę, w zależności od tego, czy pole klucza podstawowego ma wartość null, czy ma zastosowanie do istniejącej encji. Wywołanie entityManager.remove()
spowoduje usunięcie podanej klasy.
Entity relationships in JPA
Po prostu utrzymywanie obiektu z prymitywnym polem to tylko połowa równania. JPA ma również możliwość zarządzania podmiotami w stosunku do siebie. Możliwe są cztery rodzaje relacji encji zarówno w tabelach, jak i w obiektach:
- jeden do wielu
- wiele do jednego
- wiele do wielu
- jeden do jednego
każdy rodzaj relacji opisuje, jak jednostka odnosi się do innych jednostek. Na przykład jednostka Musician
może mieć relację jeden do wielu z Performance
, jednostką reprezentowaną przez kolekcję, taką jak List
lub Set
.
JeśliMusician
zawiera poleBand
, relacja między tymi jednostkami może być wiele-do-jednego, co sugeruje, że zbiórMusician
s na pojedynczej klasieBand
. (Zakładając, że każdy muzyk występuje tylko w jednym zespole.)
Jeśli Musician
zawiera pole BandMates
, które może reprezentować wiele-do-wielu relacji z innymi podmiotami Musician
.
wreszcieMusician
może mieć relację jeden do jednego zQuote
entity, używany do reprezentowania słynnego cytatu:Quote famousQuote = new Quote()
.
Definiowanie typów relacji
JPA ma adnotacje dla każdego z typów mapowania relacji. Listing 7 pokazuje, jak można adnotować relację jeden do wielu pomiędzyMusician
IPerformance
s.
Listing 7. Opisywanie relacji jeden do wielu
należy zauważyć, że@JoinColumn
informuje JPA, która kolumna w tabeli wydajności zostanie odwzorowana naMusician
. Każda wydajność będzie powiązana z pojedynczym Musician
, który jest śledzony przez tę kolumnę. Gdy JPA załaduje Musician
lub Performance
do bazy danych, użyje tych informacji do odtworzenia wykresu obiektu.
pobieranie strategii w JPA
oprócz wiedzy, gdzie umieścić powiązane podmioty w bazie danych, JPA musi wiedzieć, jak chcesz je załadować. Strategie pobierania mówią JPA, jak ładować powiązane podmioty. Podczas ładowania i zapisywania obiektów framework JPA musi zapewniać możliwość dopracowania sposobu obsługi Wykresów obiektów. Na przykład, jeśli KlasaMusician
ma polebandMate
(jak pokazano w liście 7), Ładowaniegeorge
może spowodować załadowanie całej tabeli muzyka z bazy danych!
potrzebna jest umiejętność definiowania leniwego ładowania powiązanych jednostek-uznając, oczywiście, że relacje w JPA mogą być chętne lub leniwe. Możesz użyć adnotacji, aby dostosować strategie pobierania, ale domyślna konfiguracja JPA często działa po wyjęciu z pudełka, bez zmian:
- One-to-many: Lazy
- Many-To-one: Eager
- Many-to-many: Lazy
- One-to-one: Eager
instalacja i konfiguracja JPA
zakończymy szybkim spojrzeniem na instalację i konfigurację JPA JPA dla Twoich aplikacji Java. Do tej demonstracji użyję EclipseLink, implementacji referencyjnej JPA.
powszechnym sposobem instalacji JPA jest włączenie dostawcy JPA do projektu. Lista 8 pokazuje, w jaki sposób włączyłbyś EclipseLink jako zależność do swojego pliku pom.xml
.
notowanie 8. Dołącz EclipseLink jako zależność Maven
org.eclipse.persistenceeclipselink2.5.0-RC1
będziesz również musiał dołączyć sterownik dla swojej bazy danych, jak pokazano w liście 9.
notowanie 9. Zależność Mavena dla konektora MySql
mysqlmysql-connector-java5.1.32
następnie musisz poinformować system o swojej bazie danych i dostawcy. Odbywa się to w pliku persistence.xml
, jak pokazano na liście 10.
notowanie 10. Wytrwałość.xml
istnieją inne sposoby dostarczania tych informacji do systemu, w tym programowo. Zalecam użycie pliku persistence.xml
, ponieważ przechowywanie zależności w ten sposób ułatwia aktualizację aplikacji bez modyfikowania kodu.
konfiguracja Sprężyny dla JPA
używanie sprężyny znacznie ułatwi integrację JPA z Twoją aplikacją. Na przykład umieszczenie adnotacji@SpringBootApplication
w nagłówku aplikacji instruuje Spring, aby automatycznie skanowała w poszukiwaniu klas i wstrzykiwałaEntityManager
zgodnie z wymaganiami, w oparciu o określoną konfigurację.
Listing 11 pokazuje zależności, które należy uwzględnić, jeśli chcesz, aby Spring obsługiwał JPA dla Twojej aplikacji.
notowanie 11. Dodanie Spring JPA support w Maven
wniosek
każda aplikacja, która zajmuje się bazą danych, powinna zdefiniować warstwę aplikacji, której jedynym celem jest izolowanie kodu trwałości. Jak widać w tym artykule, interfejs API Java Persistence wprowadza szereg możliwości i obsługi Java object persistence. Proste aplikacje mogą nie wymagać wszystkich możliwości JPA, a w niektórych przypadkach koszty ogólne związane z konfiguracją frameworka mogą nie być zasługiwane. Jednak wraz z rozwojem aplikacji struktura i hermetyzacja JPA naprawdę zarabiają na sobie. Korzystanie z JPA sprawia, że kod obiektowy jest prosty i zapewnia konwencjonalny framework dostępu do danych w aplikacjach Java.
dowiedz się więcej o Java Persistence API i powiązanych technologiach
- co to jest JDBC? Wprowadzenie do Java Database Connectivity: poznaj niskopoziomowe API Javy do łączenia się z bazą danych, wysyłania zapytań SQL i nie tylko.
- trwałość Javy z JPA i Hibernate, Część 1: encje i relacje: rozpocznij modelowanie encji i Relacji z Java 8 i Hibernate ORM.
- Java z JPA i Hibernate, Cz. 2: Praktyczna praktyka modelowania relacji wielu do wielu i relacji dziedziczenia w Javie 8 i Hibernate ORM.
- implementacja zachowania zależnego od stanu: Klasyczne wprowadzenie do wzorca stanu i zależności stanu w Javie.
- Eager / Lazy Loading w Hibernate: jak zastosować eager i lazy loading w Hibernate.
- JPA 2.2 wprowadza kilka oczekiwanych zmian: przegląd aktualizacji specyfikacji w JPA 2.2, w tym ulepszenia CDI, lepsze dostosowanie do API daty i czasu oraz wsparcie dla adnotacji
@Repeatable
. - czy powinieneś użyć JPA do następnego projektu?: Kluczowe pytania, które mogą pomóc w podjęciu decyzji.