Cyfroteka.pl

klikaj i czytaj online

Cyfro
Czytomierz
00039 008870 11221859 na godz. na dobę w sumie
Hibernate w akcji - książka
Hibernate w akcji - książka
Autor: , Liczba stron: 408
Wydawca: Helion Język publikacji: polski
ISBN: 83-246-0527-4 Data wydania:
Lektor:
Kategoria: ebooki >> komputery i informatyka >> programowanie >> inne - programowanie
Porównaj ceny (książka, ebook, audiobook).

Szukasz rozwiązania problemów związanych z korzystaniem z relacyjnych baz danych w połączeniu z programowaniem obiektowym? Chcesz poprawić wydajność i jakość aplikacji bazodanowych? A może rozwiązania, które stosowałeś dotychczas, okazują się niewystarczające przy dużych projektach? Sięgnij po Hibernate, czyli rewolucyjne narzędzie stanowiące warstwę pośredniczącą pomiędzy aplikacją i bazą danych, umożliwiające utrwalanie i odczyt obiektów Javy w bazie. Hibernate eliminuje konieczność ręcznego tworzenia kodu odwzorowującego obiekty na model relacyjny i odwrotnie, a także znacząco poprawia wydajność i stabilność aplikacji. Nie bez znaczenia również jest fakt, iż Hibernate dostępne jest na licencji open-source.

Książka 'Hibernate w akcji', napisana przez twórców tego narzędzia, to wyczerpujący podręcznik dla programistów, którzy planują zastosować je w swoich projektach. Czytając ją, dowiesz się, na czym polega odwzorowanie obiektowo-relacyjne i w jaki sposób implementuje je Hibernate. Poznasz zasady tworzenia i stosowania obiektów trwałych, zarządzania transakcjami i buforowania danych. Znajdziesz także informacje o optymalizowaniu wydajności aplikacji stosujących Hibernate oraz procesie projektowania takich aplikacji.

W książce poruszono m.in.:

Poznaj Hibernate i przekonaj się,
jak dzięki niemu usprawnisz swoją pracę.

Znajdź podobne książki Ostatnio czytane w tej kategorii

Darmowy fragment publikacji:

Hibernate w akcji Autorzy: Christian Bauer, Gavin King T³umaczenie: Rafa³ Joñca ISBN: 83-246-0527-4 Tytu³ orygina³u: Hibernate in Action Format: B5, stron: 410 Szukasz rozwi¹zania problemów zwi¹zanych z korzystaniem z relacyjnych baz danych w po³¹czeniu z programowaniem obiektowym? Chcesz poprawiæ wydajnoœæ i jakoœæ aplikacji bazodanowych? A mo¿e rozwi¹zania, które stosowa³eœ dotychczas, okazuj¹ siê niewystarczaj¹ce przy du¿ych projektach? Siêgnij po Hibernate, czyli rewolucyjne narzêdzie stanowi¹ce warstwê poœrednicz¹c¹ pomiêdzy aplikacj¹ i baz¹ danych, umo¿liwiaj¹ce utrwalanie i odczyt obiektów Javy w bazie. Hibernate eliminuje koniecznoœæ rêcznego tworzenia kodu odwzorowuj¹cego obiekty na model relacyjny i odwrotnie, a tak¿e znacz¹co poprawia wydajnoœæ i stabilnoœæ aplikacji. Nie bez znaczenia równie¿ jest fakt, i¿ Hibernate dostêpne jest na licencji open-source. Ksi¹¿ka „Hibernate w akcji”, napisana przez twórców tego narzêdzia. To wyczerpuj¹cy podrêcznik dla programistów, którzy planuj¹ zastosowaæ je w swoich projektach. Czytaj¹c j¹, dowiesz siê, na czym polega odwzorowanie obiektowo-relacyjne i w jaki sposób implementuje je Hibernate. Poznasz zasady tworzenia i stosowania obiektów trwa³ych, zarz¹dzania transakcjami i buforowania danych. Znajdziesz tak¿e informacje o optymalizowaniu wydajnoœci aplikacji stosuj¹cych Hibernate oraz procesie projektowania takich aplikacji. W ksi¹¿ce poruszono m.in.: (cid:129) Odwzorowania obiektowo-relacyjne (cid:129) Konfiguracja i uruchomienie Hibernate (cid:129) Odwzorowywanie danych w klasach (cid:129) Stosowanie obiektów trwa³ych (cid:129) Transakcje i buforowanie (cid:129) Wydajne pobieranie obiektów z bazy (cid:129) Projektowanie aplikacji wykorzystuj¹cych Hibernate (cid:129) Narzêdzia wspomagaj¹ce dzia³anie Hibernate Poznaj Hibernate i przekonaj siê, jak dziêki niemu usprawnisz swoj¹ pracê Wydawnictwo Helion ul. Koœciuszki 1c 44-100 Gliwice tel. 032 230 98 63 e-mail: helion@helion.pl Spis treści Przedmowa Wstęp Podziękowania O książce i autorach O Hibernate 3 i EJB 3 9 11 13 15 19 1. Trwałość dzięki odwzorowaniu obiektowo-relacyjnemu 21 1.1. Czym jest trwałość? .............................................................................................................. 23 1.1.1. Relacyjne bazy danych ............................................................................................. 23 1.1.2. Język SQL ................................................................................................................. 24 1.1.3. Korzystanie z SQL w Javie ....................................................................................... 24 1.1.4. Trwałość w aplikacjach obiektowych ....................................................................... 25 1.2. Niedopasowanie paradygmatów ......................................................................................... 27 1.2.1. Problem szczegółowości ........................................................................................... 28 1.2.2. Problem podtypów .................................................................................................... 29 1.2.3. Problem identyczności ............................................................................................. 30 1.2.4. Problemy dotyczące asocjacji ................................................................................... 32 1.2.5. Problem nawigacji po grafie obiektów ..................................................................... 33 1.2.6. Koszt niedopasowania ............................................................................................... 34 1.3. Warstwy trwałości i alternatywy ........................................................................................ 35 1.3.1. Architektura warstwowa ........................................................................................... 35 1.3.2. Ręczne tworzenie warstwy trwałości za pomocą SQL i JDBC .............................. 37 1.3.3. Wykorzystanie serializacji ........................................................................................ 38 1.3.4. A może ziarenka encyjne EJB? ................................................................................ 39 4 Spis treści 2. Wprowadzenie i integracja Hibernate 1.3.5. Obiektowe systemy bazodanowe ............................................................................. 40 1.3.6. Inne rozwiązania ....................................................................................................... 41 1.4. Odwzorowanie obiektowo-relacyjne .................................................................................. 41 1.4.1. Czym jest ORM? ....................................................................................................... 42 1.4.2. Ogólne problemy ORM ............................................................................................ 44 1.4.3. Dlaczego ORM? ........................................................................................................ 45 1.5. Podsumowanie ...................................................................................................................... 47 49 2.1. „Witaj świecie” w stylu Hibernate ...................................................................................... 50 2.2. Podstawy architektury Hibernate ...................................................................................... 55 2.2.1. Interfejsy podstawowe .............................................................................................. 56 2.2.2. Interfejsy wywołań zwrotnych ................................................................................. 58 2.2.3. Typy ........................................................................................................................... 58 2.2.4. Interfejsy rozszerzeń ................................................................................................ 59 2.3. Konfiguracja podstawowa .................................................................................................... 59 2.3.1. Tworzenie obiektu SessionFactory .......................................................................... 60 2.3.2. Konfiguracja w środowisku niezarządzanym .......................................................... 62 2.3.3. Konfiguracja w środowisku zarządzanym ................................................................ 66 2.4. Zaawansowane ustawienia konfiguracyjne ........................................................................ 68 2.4.1. Konfiguracja bazująca na pliku XML ...................................................................... 69 2.4.2. Obiekt SessionFactory dowiązany do JNDI ........................................................... 70 2.4.3. Dzienniki ................................................................................................................... 71 2.4.4. Java Management Extensions .................................................................................. 73 2.5. Podsumowanie ...................................................................................................................... 75 77 3.1. Aplikacja CaveatEmptor ..................................................................................................... 78 3.1.1. Analiza dziedziny biznesowej .................................................................................. 79 3.1.2. Model dziedzinowy CaveatEmptor ......................................................................... 79 3.2. Implementacja modelu dziedzinowego .............................................................................. 82 3.2.1. Kwestia przesiąkania zadań ...................................................................................... 82 3.2.2. Trwałość automatyczna i przezroczysta ................................................................... 83 3.2.3. Tworzenie klas POJO ............................................................................................... 84 3.2.4. Implementacja asocjacji POJO ................................................................................. 86 3.2.5. Dodanie logiki do metod dostępowych ................................................................... 90 3.3. Definicja metadanych odwzorowujących .......................................................................... 92 3.3.1. Metadane w pliku XML ........................................................................................... 92 3.3.2. Podstawowe odwzorowania właściwości i klas ........................................................ 95 3.3.3. Programowanie zorientowane na atrybuty ............................................................ 101 3.3.4. Modyfikacja metadanych w trakcie działania aplikacji ......................................... 102 3.4. Identyczność obiektów ....................................................................................................... 104 3.4.1. Identyczność a równość .......................................................................................... 104 3.4.2. Tożsamość bazodanowa w Hibernate .................................................................... 104 3.4.3. Wybór kluczy głównych ......................................................................................... 106 3.5. Szczegółowe modele obiektów .......................................................................................... 108 3.5.1. Encje i typy wartości .............................................................................................. 109 3.5.2. Stosowanie komponentów ...................................................................................... 109 3.6. Odwzorowanie dziedziczenia klas .................................................................................... 113 3.6.1. Tabela na klasę konkretną ...................................................................................... 113 3.6.2. Tabela na każdą hierarchię klas ............................................................................. 115 3. Odwzorowanie klas trwałości danych Spis treści 5 4. Stosowanie obiektów trwałych 3.6.3. Tabela na każdą podklasę ....................................................................................... 117 3.6.4. Wybór strategii ........................................................................................................ 120 3.7. Asocjacje .............................................................................................................................. 121 3.7.1. Asocjacje zarządzane? ............................................................................................. 121 3.7.2. Krotność .................................................................................................................. 122 3.7.3. Najprostsza możliwa asocjacja ............................................................................... 122 3.7.4. Tworzenie asocjacji dwukierunkowej .................................................................... 123 3.7.5. Związek rodzic-potomek ........................................................................................ 126 3.8. Podsumowanie .................................................................................................................... 127 129 4.1. Cykl życia obiektu trwałego .............................................................................................. 130 4.1.1. Obiekty ulotne ........................................................................................................ 131 4.1.2. Obiekty trwałe ......................................................................................................... 132 4.1.3. Obiekt odłączony .................................................................................................... 133 4.1.4. Zasięg identyczności obiektów ............................................................................... 134 4.1.5. Poza zasięgiem identyczności ................................................................................ 135 4.1.6. Implementacja equals() i hashCode() .................................................................... 136 4.2. Zarządca trwałości .............................................................................................................. 140 4.2.1. Czynienie obiektu trwałym .................................................................................... 140 4.2.2. Aktualizacja stanu trwałego obiektu odłączonego ................................................. 141 4.2.3. Pobranie obiektu trwałego ..................................................................................... 142 4.2.4. Aktualizacja obiektu trwałego ................................................................................ 143 4.2.5. Zmiana obiektu trwałego na ulotny ....................................................................... 143 4.2.6. Zmiana obiektu odłączonego na ulotny ................................................................. 144 4.3. Trwałość przechodnia w Hibernate ................................................................................. 144 4.3.1. Przechodniość przez osiągalność ........................................................................... 145 4.3.2. Trwałość kaskadowa w Hibernate ......................................................................... 146 4.3.3. Zarządzanie kategoriami przedmiotów .................................................................. 147 4.3.4. Rozróżnienie obiektów ulotnych i odłączonych .................................................... 151 4.4. Pobieranie obiektów ........................................................................................................... 152 4.4.1. Pobieranie obiektów na podstawie identyfikatora ................................................ 153 4.4.2. Wprowadzenie do HQL ......................................................................................... 154 4.4.3. Zapytania przez określenie kryteriów .................................................................... 155 4.4.4. Zapytanie przez przykład ....................................................................................... 155 4.4.5. Strategie sprowadzania danych .............................................................................. 156 4.4.6. Wybór strategii sprowadzania w odwzorowaniach ............................................... 158 4.4.7. Optymalizacja pobierania obiektów ....................................................................... 163 4.5. Podsumowanie .................................................................................................................... 164 167 5.1. Transakcje bazodanowe ..................................................................................................... 169 5.1.1. Transakcje JDBC i JTA .......................................................................................... 170 5.1.2. Interfejs Transaction ............................................................................................... 171 5.1.3. Opróżnianie sesji ..................................................................................................... 173 5.1.4. Poziomy izolacji ...................................................................................................... 174 5.1.5. Wybór poziomu izolacji .......................................................................................... 176 5.1.6. Ustawianie poziomu izolacji ................................................................................... 177 5.1.7. Blokada pesymistyczna ........................................................................................... 177 5.2. Transakcje aplikacyjne ...................................................................................................... 180 5.2.1. Wersjonowanie zarządzane .................................................................................... 181 5. Transakcje, współbieżność i buforowanie 6 Spis treści 7. Wydajne pobieranie obiektów 6. Zaawansowane zagadnienia odwzorowań 5.2.2. Szczegółowość sesji ................................................................................................ 184 5.2.3. Inne sposoby implementacji blokady optymistycznej .......................................... 185 5.3. Buforowanie — teoria i praktyka ..................................................................................... 186 5.3.1. Strategie i zasięgi buforowania ............................................................................... 187 5.3.2. Architektura buforów Hibernate ............................................................................ 190 5.3.3. Buforowanie w praktyce ......................................................................................... 195 5.4. Podsumowanie .................................................................................................................... 204 205 6.1. System typów Hibernate .................................................................................................... 206 6.1.1. Wbudowane typy odwzorowań .............................................................................. 207 6.1.2. Zastosowania typów odwzorowań .......................................................................... 210 6.2. Odwzorowywanie kolekcji typów wartości ...................................................................... 220 6.2.1. Zbiory, pojemniki, listy i odwzorowania ................................................................ 220 6.3. Odwzorowanie asocjacji encyjnych .................................................................................. 228 6.3.1. Asocjacja jeden-do-jednego .................................................................................... 229 6.3.2. Asocjacje wiele-do-wielu ........................................................................................ 232 6.4. Odwzorowanie asocjacji polimorficznych ....................................................................... 241 6.4.1. Polimorficzna asocjacja wiele-do-jednego ............................................................. 241 6.4.2. Kolekcje polimorficzne ........................................................................................... 243 6.4.3. Asocjacje polimorficzne i jedna tabela na klasę konkretną ................................... 244 6.5. Podsumowanie .................................................................................................................... 246 247 7.1. Wykonywanie zapytań ....................................................................................................... 249 7.1.1. Interfejsy zapytań ................................................................................................... 249 7.1.2. Dowiązywanie parametrów .................................................................................... 251 7.1.3. Zapytania nazwane .................................................................................................. 254 7.2. Proste zapytania dotyczące obiektów ............................................................................... 255 7.2.1. Najprostsze zapytanie ............................................................................................. 256 7.2.2. Zastosowanie aliasów .............................................................................................. 256 7.2.3. Zapytania polimorficzne ......................................................................................... 257 7.2.4. Ograniczenia ........................................................................................................... 257 7.2.5. Operatory porównań ............................................................................................... 258 7.2.6. Dopasowywanie tekstów ........................................................................................ 260 7.2.7. Operatory logiczne .................................................................................................. 261 7.2.8. Kolejność wyników zapytań ................................................................................... 262 7.3. Złączanie asocjacji .............................................................................................................. 262 7.3.1. Złączenia w Hibernate ............................................................................................ 264 7.3.2. Pobieranie asocjacji ................................................................................................ 265 7.3.3. Aliasy i złączenia ..................................................................................................... 266 7.3.4. Złączenia niejawne .................................................................................................. 270 7.3.5. Złączenia w stylu theta ........................................................................................... 271 7.3.6. Porównywanie identyfikatorów .............................................................................. 272 7.4. Tworzenie zapytań raportujących .................................................................................... 273 7.4.1. Projekcja .................................................................................................................. 274 7.4.2. Agregacja ................................................................................................................. 276 7.4.3. Grupowanie ............................................................................................................. 277 7.4.4. Ograniczanie grup klauzulą having ........................................................................ 278 7.4.5. Poprawa wydajności zapytań raportujących .......................................................... 279 Spis treści 7 9. Narzędzia Hibernate 8. Tworzenie aplikacji stosujących Hibernate 7.5. Techniki tworzenia zaawansowanych zapytań ................................................................ 279 7.5.1. Zapytania dynamiczne ............................................................................................ 280 7.5.2. Filtry kolekcji .......................................................................................................... 282 7.5.3. Podzapytania ........................................................................................................... 284 7.5.4. Zapytania SQL ........................................................................................................ 286 7.6. Optymalizacja pobierania obiektów ................................................................................. 288 7.6.1. Rozwiązanie problemu n+1 pobrań danych ......................................................... 288 7.6.2. Zapytania iterate() ................................................................................................... 291 7.6.3. Buforowanie zapytań .............................................................................................. 292 7.7. Podsumowanie .................................................................................................................... 294 295 8.1. Projektowanie aplikacji warstwowych ............................................................................. 296 8.1.1. Użycie Hibernate w systemie serwletowym ......................................................... 297 8.1.2. Stosowanie Hibernate w kontenerze EJB ............................................................. 311 8.2. Implementacja transakcji aplikacyjnych ......................................................................... 319 8.2.2. Trudny sposób ......................................................................................................... 321 8.2.3. Odłączone obiekty trwałe ....................................................................................... 322 8.2.4. Długa sesja .............................................................................................................. 323 8.2.5. Wybór odpowiedniej implementacji transakcji aplikacyjnych ............................ 327 8.3. Obsługa specjalnych rodzajów danych ............................................................................ 328 8.3.1. Starsze schematy baz danych i klucze złożone ..................................................... 328 8.3.2. Dziennik audytowy ................................................................................................. 337 8.4. Podsumowanie .................................................................................................................... 343 345 9.1. Procesy tworzenia aplikacji ............................................................................................... 346 9.1.1. Podejście z góry na dół ........................................................................................... 347 9.1.2. Podejście z dołu do góry ......................................................................................... 347 9.1.3. Podejście od środka ................................................................................................ 347 9.1.4. Spotkanie w środku ................................................................................................. 347 9.1.5. Ścieżka przejścia ..................................................................................................... 348 9.2. Automatyczne generowanie schematu bazy danych ....................................................... 348 9.2.1. Przygotowanie metadanych odwzorowania ........................................................... 349 9.2.2. Utworzenie schematu ............................................................................................. 351 9.2.3. Aktualizacja schematu bazy danych ....................................................................... 353 9.3. Generowanie kodu klas POJO ........................................................................................... 354 9.3.1. Wprowadzenie metaatrybutów .............................................................................. 355 9.3.2. Metody odnajdujące ............................................................................................... 357 9.3.3. Konfiguracja hbm2java ........................................................................................... 358 9.3.4. Uruchamianie narzędzia hbm2java ........................................................................ 359 9.4. Istniejące schematy i Middlegen ...................................................................................... 360 9.4.1. Uruchomienie Middlegen ...................................................................................... 360 9.4.2. Ograniczanie tabel i związków ............................................................................... 362 9.4.3. Dostosowanie generowania metadanych ............................................................... 363 9.4.4. Generowanie metadanych hbm2java i XDoclet .................................................... 365 9.5. XDoclet ................................................................................................................................ 366 9.5.1. Ustawianie atrybutów typu wartości ...................................................................... 367 9.5.2. Odwzorowanie asocjacji encyjnych ....................................................................... 368 9.5.3. Uruchomienie XDoclet .......................................................................................... 369 9.6. Podsumowanie .................................................................................................................... 371 8 Spis treści A Podstawy języka SQL 373 B Strategie implementacji systemów ORM 377 B.1. Właściwości czy pola? ........................................................................................................ 378 B.2. Strategie sprawdzania zabrudzenia .................................................................................. 379 B.2.1. Dziedziczenie po wygenerowanym kodzie ........................................................... 379 B.2.2. Przetwarzanie kodu źródłowego ............................................................................ 379 B.2.3. Przetwarzanie kodu bajtowego .............................................................................. 380 B.2.4. Introspekcja ............................................................................................................. 380 B.2.5. Generowanie kodu bajtowego „w locie” ................................................................ 381 B.2.6. Obiekty „uogólnione” ............................................................................................. 382 383 C.1. Dziwna kopia ...................................................................................................................... 384 C.2. Im więcej, tym lepiej .......................................................................................................... 385 C.3. Nie potrzebujemy kluczy głównych .................................................................................. 385 C.4. Czas nie jest liniowy ........................................................................................................... 386 C.5. Dynamicznie niebezpieczne .............................................................................................. 386 C.6. Synchronizować czy nie synchronizować? ....................................................................... 387 C.7. Naprawdę gruby klient ...................................................................................................... 388 C.8. Wznawianie Hibernate ...................................................................................................... 388 391 393 C Powrót do świata rzeczywistego Bibliografia Skorowidz Wprowadzenie i integracja Hibernate W rozdziale: ♦ Działanie Hibernate na przykładzie aplikacji „Witaj świecie” ♦ Podstawowe interfejsy programistyczne Hibernate ♦ Integracja z zarządzanymi i niezarządzanymi środowiskami ♦ Zaawansowane opcje konfiguracyjne 50 ROZDZIAŁ 2. Wprowadzenie i integracja Hibernate Dobrze zdawać sobie sprawę z potrzeby odwzorowania obiektowo-relacyjnego w aplikacjach Javy, ale jeszcze lepiej zobaczyć takie odwzorowanie w akcji. Za- cznijmy od prostego przykładu obrazującego zalety Hibernate. Wiele osób wie, że niemal każda książka o programowaniu rozpoczyna się od przykładu „Witaj świecie”. Nie zamierzamy się wyłamywać z tej konwencji i rów- nież przedstawimy prostą aplikację tego typu używającą Hibernate. Niestety, pro- ste wyświetlenie komunikatu tekstowego na konsoli nie uwidoczniłoby żadnych zalet Hibernate. Z tego powodu tworzony program będzie tworzył nowe obiekty w bazie danych, aktualizował je i wykonywał zapytania, by je pobrać. Niniejszy rozdział stanowi podstawę dla pozostałych rozdziałów. Poza przed- stawieniem typowego dla książek informatycznych przykładu wprowadzimy rów- nież interfejs programistyczny Hibernate i omówimy konfigurację systemu w róż- nych środowiskach wykonawczych, na przykład serwerach aplikacji J2EE lub aplikacjach klienckich. 2.1. „Witaj świecie” w stylu Hibernate Aplikacje Hibernate definiują klasy trwałe, które są odwzorowywane na tabele bazy danych. Pierwszy przykład zawiera jedną klasę i jeden plik opisu odwzo- rowania. Przyjrzyjmy się, jak wygląda prosta klasa trwałości, jak określa się odwzo- rowanie i jak wykonuje się podstawowe operacje dotyczące trwałości danych. Celem pierwszej aplikacji jest zapamiętywanie w bazie danych komunikatów, a następnie ich pobieranie w celu wyświetlania. Aplikacja stosuje prostą klasę trwałości, Message, reprezentującą komunikaty do wyświetlenia. Klasę przedsta- wia listing 2.1. Listing 2.1. Plik Message.java — prosta klasa trwałości package hello; public class Message { private Long id; private String text; private Message nextMessage; private Message() {} public Message(String text) { this.text = text; } public Long getId() { return id; } private void setId(Long id) { this.id = id; } public String getText() { return text; } private void setText(String text) { this.text= text; } 2.1. „Witaj świecie” w stylu Hibernate 51 public Long getNextMessage() { return nextMessage; } private void setnNextMessage(Long nextMessage) { this.nextMessage= nextMessage; } Klasa Message ma trzy atrybuty: identyfikator, treść komunikatu i referencję do innego komunikatu. Atrybut identyfikacyjny umożliwia aplikacji dostęp do iden- tyfikatora bazodanowego — wartości klucza głównego — obiektu trwałego. Jeśli dwa egzemplarze klasy Message zawierają ten sam identyfikator, dotyczą tego same- go wiersza w tabeli bazy danych. Jako typ identyfikatora wybraliśmy Long, choć nie jest to wymóg. Hibernate dopuszcza stosowane dla identyfikatorów dowolnych typów, co wkrótce przedstawimy. Wszystkie atrybuty klasy Message stosują metody dostępowe do właściwości w stylu ziarenek JavaBeans. Klasa zawiera także bezparametrowy konstruktor. Klasy trwałości stosowane w kolejnych przykładach wyglądają bardzo podobnie do przedstawionej. Egzemplarze klasy Message mogą być zarządzane (w sensie zapewnienia trwa- łości) przez Hibernate, ale nie jest to przymus. Ponieważ obiekt Message nie imple- mentuje żadnych klas i interfejsów specyficznych dla Hibernate, można go używać jak dowolnej innej klasy Javy. Message message = new Message( Witaj świecie ); System.out.println(message.getText()); Przedstawiony fragment wykonuje właśnie to zadanie, którego oczekuje się po aplikacji „Witaj świecie” — wyświetla na konsoli napis Witaj świecie. Niektó- rym wydaje się zapewne, że w tym momencie jesteśmy wyjątkowo uprzejmi — w rzeczywistości ten prosty przykład demonstruje istotną cechę wyróżniającą Hiberante od innych rozwiązań trwałości, na przykład ziarenek encyjnych EJB. Klasę trwałości można stosować w dowolnym kontekście, bo nie jest konieczny żaden szczególny kontener. Ponieważ książka dotyczy Hibernate, zapiszmy obiekt Message do bazy danych. Session session = getSessionFactory().openSession(); Transaction tx = session.beginTransaction(); Message message = new Message( Witaj świecie ); session.save(message); tx.commit(); session.close(); Przedstawiony kod korzysta z interfejsów Session i Transaction systemu Hiber- nate (wkrótce zajmiemy się wywołaniem getSessionFactory()). Przedstawiony kod skutkuje przekazaniem do bazy danych polecenia SQL podobnego do nastę- pującego: insert into MESSSAGE (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID) values (1, Witaj świecie , null) 52 ROZDZIAŁ 2. Wprowadzenie i integracja Hibernate Chwileczkę — kolumna MESSAGE_ID zostaje zainicjalizowana dziwną wartością. Nigdzie nie ustawialiśmy w kodzie właściwości id, więc oczekujemy dla niej war- tości null, prawda? W rzeczywistości właściwość id jest szczególna — jest wła- ściwością identyfikującą, która przechowuje wygenerowaną, unikatową wartość (w dalszej części tekstu wyjaśnimy sposób generowania wartości). Wartość zostaje wprowadzona do obiektu Message w momencie wykonania metody save(). W przykładzie zakładamy wcześniejsze istnienie tabeli MESSAGE. W rozdziale 9. omówimy wykorzystanie Hibernate do automatycznego tworzenia tabel wyma- ganych przez aplikację dzięki informacjom zawartym w plikach odwzorowań (w ten sposób unikamy pisania jeszcze większej ilości kodu SQL). Chcemy, by program wyświetlił komunikat na konsoli. Skoro komunikat znalazł się w bazie danych, nie powinno to sprawić żadnych trudności. Kolejny przykład pobiera z bazy danych wszystkie komunikaty w kolejności alfabetycznej i wyświetla ich zawartość. Session newSession = getSessionFactory().openSession(); Transaction newTransaction = newSession.beginTransaction(); List messages = newSession.find( from Message as m order by m.text asc ); System.out.println( Znalezionych komunikatów: + messages.size()); for (Iterator iter = messages.iterator(); iter.hasNext();) { Message message = (Message) iter.next(); System.out.println(message.getText()); } newTransaction.commit(); newSession.close(); Ciąg znaków from Message as m order by m.text asc to zapytanie Hibernate zapisane w specjalnym, obiektowym języku zapytań Hibernate (HQL — Hiber- nate Query Language). Zapytanie zostaje wewnętrznie przekształcone na nastę- pujący kod SQL w momencie wywołania metody find(). select m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID from MESSAGES m order by m.MESSAGE_TEXT asc Przedstawiony kod powoduje wyświetlenie na konsoli poniższego tekstu: Znalezionych komunikatów: 1 Witaj świecie Jeśli ktoś nigdy wcześniej nie korzystał z narzędzi ORM, spodziewa się ujrzeć kod SQL w metadanych lub też kodzie Javy. Nie ma go tam. Cały kod SQL zostaje wygenerowany dynamicznie w trakcie działania aplikacji (ewentualnie w momen- cie jej uruchamiania dla wszystkich instrukcji SQL wielokrotnego użytku). Aby wystąpiła cała magia, Hibernate potrzebuje więcej informacji na temat zapewniania trwałości klasie Message. Informację tę najczęściej umieszcza się dokumencie odwzorowania zapisywanym w formacie XML. Dokument ten defi- niuje, poza innymi kwestiami, w jaki sposób przełożyć właściwości klasy Message na kolumny tabeli MESSAGES. Przyjrzyjmy się fragmentowi dokumentu odwzoro- wania — listing 2.2. 2.1. „Witaj świecie” w stylu Hibernate 53 Listing 2.2. Prosty plik odwzorowania Hibernate w formacie XML ?xml version= 1.0 ? !DOCTYPE hibernate-mapping PUBLIC -//Hibernate/Hibernate Mapping DTD//EN http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd hibernate-mapping class name= hello.Message table= MESSAGES id name= id column= MESSAGE_ID generator class= increment / /id property name= text column= MESSAGE_TEXT / many-to-one name= nextMessage cascade= all column= NEXT_MESSAGE_ID / /class /hibernate-mapping Dokument odwzorowania informuje Hibernate, że klasa Message przekłada się na tabelę MESSAGES. Informuje również, że właściwość identyfikatora ma trafić do kolumny nazwanej MESSAGE_ID, właściwość komunikatu do kolumny o nazwie MESSAGE_TEXT, natomiast właściwość nextMessage jest asocjacją z krotnością wiele- do-jednego i powinna trafić do kolumny o nazwie NEXT_MESSAGE_ID (pozostałymi szczegółami na tym etapie nie będziemy się zajmować). Dokument XML nie jest trudny do zrozumienia. Można go bez problemów ręcznie tworzyć i modyfikować. W rozdziale 3. omówimy sposób generowania tego pliku na podstawie komentarzy zawartych w kodzie źródłowym aplikacji. Nie- zależnie od wybranego podejścia Hiberante uzyskuje wystarczająco dużo infor- macji, by poprawnie generować wszystkie polecenia SQL dotyczące wstawiania, aktualizacji, usuwania i pobierania egzemplarzy klasy Message. Nie trzeba ręcznie pisać wszystkich wymaganych poleceń SQL. Uwaga Wielu programistów Javy narzeka na tak zwane „piekło metadanych”, które towarzyszy tworzeniu oprogramowania J2EE. Niektórzy sugerują nawet rezygnację z metadanych XML i powrót do zwykłego kodu Javy. Choć w pełni popieramy te dążenia w niektórych dziedzinach, ORM wydaje się być zagadnieniem, w którym metadane naprawdę są potrzebne. Hibernate stosuje sensowne wartości domyślne, by zminimalizować dłu- gość plików konfiguracyjnych. Wykorzystuje dojrzałą definicję typu doku- mentu (DTD), więc możliwe jest wykorzystanie edytorów z uzupełnianiem składni i walidacją. Istnieją nawet narzędzia zapewniające automatyczne generowanie metadanych. 54 ROZDZIAŁ 2. Wprowadzenie i integracja Hibernate Zmieńmy pierwszy komunikat i dodatkowo utwórzmy kolejny powiązany z pierw- szym. Kod wykonujący to zadanie przedstawia listing 2.3. Listing 2.3. Aktualizacja komunikatu Session session = getSessionFactory().openSession(); Transaction tx = session.beginTransaction(); // 1 to identyfikator wygenerowany dla pierwszego komunikatu Message message = (Message) session.load(Message.class, new Long(1)); message.setText( Witajcie Ziemianie ); Message nextMessage = new Message( Proszę zabrać mnie do waszego przywódcy ); message.setNextMessage(nextMessage); tx.commit(); session.close(); Powyższy kod powoduje wykonanie w jednej transakcji trzech poleceń SQL. select m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID from MESSAGES m where m.MESSAGE_ID = 1 insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID) values (2, Proszę zabrać mnie do waszego przywódcy , null) update MESSAGES set MESSAGE_TEXT = Witajcie Ziemianie , NEXT_MESSAGE_ID = 2 where MESSAGE_ID = 1 Zauważ, że Hibernate automatycznie rozpoznał modyfikację właściwości text i nextMessage dla pierwszego komunikatu i zapisał nowe wartości w bazie danych. Skorzystaliśmy z cechy Hibernate nazywanej automatycznym wykrywaniem zabrudzenia. Pozwala ona uniknąć jawnego proszenia Hibernate o aktualizację bazy danych, gdy zmienia się stan obiektu wewnątrz transakcji. Warto zwrócić uwagę, iż nowy komunikat również stał się trwały, gdy tylko powstała referencja do niego z pierwszego komunikatu. Jest to tak zwany zapis kaskadowy — unika się w ten sposób jawnego wywoływania metody save() dla nowego obiektu trwa- łego, o ile tylko jest on osiągalny z poziomu innego obiektu trwałego. Kolejność wykonania instrukcji SQL nie jest taka sama jak kolejność modyfikacji wartości właściwości. Hibernate używa wyrafinowanego algorytmu do określenia wydajnej kolejności zapisów, by uniknąć zerwania ograniczeń klucza obcego i jednocześnie pozostać odpowiednio przewidywalnym. Jest to tak zwany transakcyjny zapis opóź- niony. Ponownie uruchomienie programu spowoduje wyświetlenie poniższego wyniku: Znalezionych komunikatów: 2 Witajcie Ziemianie Proszę zabrać mnie do waszego przywódcy 2.2. Podstawy architektury Hibernate 55 Na tym zakończymy przygodę z aplikacją „Witaj świecie”. Gdy poznaliśmy dzia- łający kod, możemy się cofnąć i dokładniej omówić poszczególne elementy głów- nego interfejsu programistycznego Hibernate. 2.2. Podstawy architektury Hibernate Interfejs programistyczny to pierwszy element Hibernate, który trzeba poznać, by móc skorzystać z warstwy trwałości w aplikacji. Głównym celem projektowym interfejsu była minimalizacja współzależności między poszczególnymi kompo- nentami oprogramowania. W praktyce interfejs programistyczny ORM nie należy do najmniejszych. Na szczęście nie wszystkie interfejsy trzeba poznać od razu, by korzystać z Hibernate. Rysunek 2.1 przedstawia zadania najważniejszych interfej- sów w warstwie biznesowej i trwałości. Na rysunku warstwa biznesowa znajduje się powyżej warstwy trwałości, gdyż w typowych aplikacjach warstwowych działa jako klient warstwy trwałości. Niektóre proste aplikacje niezbyt dobrze separują logikę biznesową od trwałości — nie będziemy się tym jednak zajmować, bo zale- cane podejście przedstawia rysunek. Rysunek 2.1. Wysokopoziomowy przegląd interfejsów programistycznych Hibernate z uwzględnieniem architektury warstwowej Interfejsy Hibernate przedstawione na rysunku 2.1 można podzielić następująco: 56 ROZDZIAŁ 2. Wprowadzenie i integracja Hibernate (cid:141) Interfejsy wywoływane przez aplikacje w celu wykonania prostych operacji CRUD i wyszukiwania. Interfejsy te stanowią główny punkt styku logiki biznesowej z Hibernate. Zawierają interfejsy: Session, Transaction i Query. (cid:141) Interfejsy wywoływane przez kod infrastruktury aplikacji w celu konfiguracji Hibernate. Jest to przede wszystkim klasa Configuration. (cid:141) Interfejsy wywołań zwrotnych pozwalające aplikacji reagować na zdarzenia zachodzące wewnątrz Hibernate. Są to interfejsy: Interceptor, Lifecycle i Validatable. (cid:141) Interfejsy zapewniające rozszerzanie rozbudowanej funkcjonalności odwzorowania w Hibernate. Są to interfejsy: UserType, CompositeUserType i IdentifierGenerator. Interfejsy te implementuje kod infrastruktury aplikacji (jeśli to konieczne). Hibernate wykorzystuje istniejące interfejsy programistyczne Javy, włączając w to JDBC, JTA (Java Transaction API) oraz JNDI (Java Naming and Directory Interface). JDBC zapewnia odpowiedni poziom abstrakcji funkcji wspólnych dla różnych systemów relacyjnych baz danych, co oznacza, że Hibernate potrafi sko- rzystać z dowolnej bazy danych ze sterownikiem JDBC. JNDI i JTA umożliwiają Hibernate integrację z serwerami aplikacji J2EE. W niniejszym podrozdziale nie będziemy omawiać szczegółowej semantyki metod interfejsów Hibernate. Zajmiemy się raczej podstawowymi rolami inter- fejsów. Większość interfejsów znajduje się w pakiecie net.sf.hibernate. Przyj- rzyjmy się pokrótce każdemu z nich. 2.2.1. Interfejsy podstawowe Pięć interfejsów podstawowych pojawia się w niemal każdej aplikacji wykorzy- stującej Hibernate. Dzięki nim możliwe staje się pobieranie i zapamiętywanie trwałych obiektów oraz sterowanie transakcjami. Interfejs Session Interfejs Session to główny interfejs każdej aplikacji Hibernate. Egzemplarze Session są lekkie — koszt ich utworzenia i zniszczenia bywa niewielki. Jest to niezwykle istotne, bo każda aplikacja cały czas tworzy i usuwa coraz to nowe sesje, prawdopodobnie przy każdym nowym żądaniu. Sesje Hibernate nie są bezpieczne wielowątkowo i z tego powodu należy tak projektować aplikację, by używać ich w danym momencie w tylko jednym wątku. Znaczenie sesji Hibernate można opisać jako coś pomiędzy połączeniem i transakcją. Najprościej traktować sesję jako bufor lub kolekcję załadowanych obiektów powiązanych z jedną jednostką zadaniową. Hibernate potrafi wykryć zmiany w obiektach tej jednostki zadaniowej. Często interfejs Session nazywa się zarządcą trwałości, gdyż zapewnia dostęp do podstawowych operacji trwało- ści takich jak zapis i pobieranie obiektów. Warto podkreślić, że sesja Hibernate nie ma nic wspólnego z sesją warstwy połączenia internetowego, na przykład 2.2. Podstawy architektury Hibernate 57 z HttpSession. Gdy w książce używamy słowa sesja, mamy na myśli sesję Hiber- nate. Gdy mówimy o sesji użytkownika, mamy na myśli obiekt HttpSession. Interfejs Session został dokładnie omówiony w podrozdziale 4.2. Interfejs SessionFactory Aplikacja pobiera egzemplarze Session z SessionFactory. W porównaniu z Session obiekt ten jest znacznie bardziej interesujący. Interfejs SessionFactory pewnością nie jest lekki! Został zaprojektowany z myślą o współdzieleniu przez wiele wątków aplikacji. Najczęściej na całą aplika- cję występuje tylko jeden obiekt SessionFactory tworzony w momencie jej ini- cjalizacji. Jeśli jednak aplikacja korzysta z kilku baz danych w połączeniu z Hiber- nate, potrzeba osobnego obiektu SessionFactory dla każdej bazy danych. Obiekt SessionFactory buforuje wygenerowane polecenia SQL i inne meta- dane odwzorowania stosowane przez Hibernate w trakcie działania aplikacji. Dodatkowo buforuje dane, które zostały odczytane w jednej jednostce zadanio- wej i mogłyby przydać się w innej jednostce zadaniowej (ten drugi poziom bufo- rowania działa tylko wtedy, gdy odwzorowania klas i kolekcji sugerują jego użycie). Interfejs Configuration Obiekt Configuration służy do konfiguracji i uruchomienia Hibernate. Aplikacja używa egzemplarza Configuration do wskazania położenia dokumentów odwzo- rowań i właściwości specyficznych dla Hibernate. Podrozdział 2.3 ze średnim stopniem złożoności opisuje konfigurację systemu Hibernate. Interfejs Transaction Interfejs Transaction jest opcjonalny. Aplikacje Hibernate nie muszą z niego korzy- stać, jeśli chcą zarządzać transakcjami we własnym zakresie. Interfejs stara się ukryć szczegóły implementacji konkretnych mechanizmów transakcyjnych: JDBC, klasy UserTransaction z JTA lub nawet transakcji CORBA (Common Object Requ- est Broker Architecture). W ten sposób zapewnia aplikacji jednorodny sposób ich obsługi. Ułatwia to zachowanie przenośności aplikacji Hibernate między różnymi środowiskami wykonywania i kontenerami. W niniejszej książce stosujemy interfejs Transaction. Został on dokładnie wyjaśniony w rozdziale 5. Interfejsy Query i Criteria Interfejs Query umożliwia wysyłanie zapytań do bazy danych i sterowanie proce- sem ich wykonywania. Zapytania pisze się w języku HQL lub też w odpowied- nim dla danej bazy danych dialekcie SQL. Egzemplarz Query odpowiada za dowią- zanie parametrów zapytania, ograniczenie liczby zwracanych wyników i wykonanie zapytania. Interfejs Criteria jest bardzo podobny. Umożliwia utworzenie i wykonanie obiektowych kryteriów wyszukiwania. 58 ROZDZIAŁ 2. Wprowadzenie i integracja Hibernate Aby tworzony kod był możliwie krótki, Hibernate dostarcza kilka skrótów w interfejsie Session, by móc w jednym wierszu wykonać zapytanie. W książce nie stosujemy tych skrótów — zawsze używamy interfejsu Query. Egzemplarz Query jest lekki nie daje się zastosować poza egzemplarzem Session, dla którego powstał. Opis funkcji interfejsu Query znajduje się w rozdziale 7. 2.2.2. Interfejsy wywołań zwrotnych Interfejsy wywołań zwrotnych umożliwiają aplikacji otrzymywanie powiadomień, gdy coś ciekawego stanie się ze sprawdzanym obiektem — na przykład zostanie załadowany, zapisany lub usunięty. Aplikacje stosujące Hibernate nie muszą ko- rzystać z wywołań zwrotnych, ale niejednokrotnie przydają się one do tworzenia ogólnej funkcjonalności, na przykład automatycznego tworzenia zapisów audy- torskich. Interfejsy Lifecycle i Validatable zapewniają trwałym obiektom reakcję na zdarzenia związane z własnym cyklem życia trwałego. Cykl życia ma nieroze- rwalny związek z operacjami CRUD obiektu. Zespół projektowy Hibernate był pod silnym wpływem innych rozwiązań ORM posiadających podobne wywoła- nia zwrotne. Później zdano sobie sprawę, że kasy trwałości implementujące interfejsy specyficzne dla Hibernate nie są najlepszym pomysłem, gdyż ich sto- sowanie utrudnia przenośność kodu. Ponieważ ich używanie obecnie nie jest zale- cane, nie są one szerzej opisywane w niniejszej książce. Interfejs Interceptor wprowadzono, by aplikacje mogły przetwarzać wywo- łania zwrotne bez potrzeby wprowadzania implementacji interfejsów Hibernate do klas trwałości. Implementacje interfejsu Interceptor wprowadza się do egzem- plarzy trwałych klas jako parametry. Przykład ich użycia pojawi się w rozdziale 8. 2.2.3. Typy Podstawowym i niezwykle użytecznym elementem architektury jest sposób wyko- nania obiektu Type w Hibernate. Obiekt ten odwzorowuje typ Javy na typ kolumny tabeli bazy danych (w rzeczywistości typ może dotyczyć wielu kolumn). Wszystkie trwałe właściwości klas trwałych, włączając w to asocjacje, posiadają odpowiedni typ Hibernate. Ten sposób obsługi czyni Hibernate wyjątkowo elastycznym i roz- szerzalnym. Istnieje bogaty zbiór typów wbudowanych zawierający wszystkie typy podsta- wowej Javy oraz wiele klas ze standardowej biblioteki JDK, włączając w to typy: java.util.Currency, java.util.Calendar, byte[] i java.io.Serializable. Co więcej, Hibernate obsługuje typy zdefiniowane przez użytkownika. Inter- fejsy UserType i CompositeUserType dają możliwość kreowania własnych typów. W ten sposób klasy wykorzystywane w wielu różnych aplikacjach, na przykład Address, Name i MonetaryAmount udaje się obsłużyć wygodnie i elegancko. Własne typy uważa się za jedną z najistotniejszych cech Hibernate. Zalecamy z nich korzy- stać w coraz to nowy sposób! Szczegóły dotyczące typów Hibernate zostały omówione w podrozdziale 6.1. 2.3. Konfiguracja podstawowa 59 2.2.4. Interfejsy rozszerzeń Większość funkcjonalności Hibernate można dostosować do własnych potrzeb, włączając w to wybór wbudowanych strategii. Gdy okazują się one niewystarcza- jące, Hibernate dopuszcza zastosowanie własnej implementacji przez zastoso- wanie odpowiedniego interfejsu. Możliwe rozszerzenia są następujące: (cid:141) generacja klucza głównego (interfejs IdentifierGenerator), (cid:141) obsługa dialektu języka SQL (klasa abstrakcyjna Dialect), (cid:141) strategia buforowania (interfejsy Cache i CacheProvider), (cid:141) zarządzanie połączeniem JDBC (interfejs ConnectionProvider), (cid:141) zarządzanie transakcjami (interfejsy TransactionFactory, Transaction i TransactionManagerLookup), (cid:141) strategia ORM (hierarchia interfejsów ClassPersister), (cid:141) strategia dostępu do właściwości (interfejs PropertyAccessor), (cid:141) tworzenie pośredników (interfejs ProxyFactory). Hibernate zawiera co najmniej jedną implementację każdego z wymienionych interfejsów, więc najczęściej nie trzeba zaczynać od podstaw, gdy chce się jedy- nie rozszerzyć pewną wbudowaną funkcjonalność. Co więcej, dostępny kod źró- dłowy stanowi doskonały przykład w sytuacji, gdy tworzy się własne rozwiązanie. Zanim zacznie się tworzyć jakikolwiek kod związany z Hibernate, warto zadać sobie następujące pytanie: w jaki sposób zmusić do działania obiekt Session? 2.3. Konfiguracja podstawowa Przyjrzeliśmy się przykładowej aplikacji oraz podstawowym interfejsom Hiber- nate. Aby móc skorzystać z automatycznej trwałości, trzeba poznać sposób jej konfiguracji. Hibernate udaje się tak skonfigurować, by działało poprawnie w nie- malże dowolnej aplikacji Javy i środowisku programistycznym. Na ogół jednak stosuje się go w dwu- lub trójwarstowych aplikacjach klient-serwer, przy czym Hibernate zostaje wdrożony tylko po stronie serwera. Aplikacją kliencką najczę- ściej jest przeglądarka internetowa, ale zdarzają się również aplikacje SWT i Swing. Choć w książce skupiamy się na wielowarstwowych aplikacjach internetowych, przedstawiane opisy mają zastosowanie również w dowolnej innej architekturze, na przykład aplikacjach wiersza poleceń. Istotnym jest, by zrozumieć różnicę w konfiguracji Hibernate w środowisku zarządzanym i niezarządzanym. (cid:141) Środowisko zarządzanie — tworzy pule zasobów, na przykład połączeń z bazą danych, i dopuszcza deklaratywne (w postaci metadanych) określanie zakresu transakcji oraz zasad bezpieczeństwa. Serwery aplikacji J2EE, na przykład JBoss, BEA WebLogic lub IBM WebSphere, implementują w Javie standardowe (zgodne z J2EE) środowisko zarządzane. (cid:141) Środowisko niezarządzane — zapewnia proste zarządzanie współbieżnością dzięki puli wątków. Pojemnik serwletowy taki jak Jetty lub Tomcat 60 ROZDZIAŁ 2. Wprowadzenie i integracja Hibernate zapewnia niezarządzane środowisko serwerowe dla aplikacji internetowych pisanych w Javie. Samowystarczalne aplikacje kliencie i aplikacje wiersza poleceń również uważa się za niezarządzane. Środowiska te nie udostępniają automatycznego zarządzania transakcjami i zasobami oraz nie zapewniają infrastruktury bezpieczeństwa. Sama aplikacja zarządza połączeniami z bazą danych i określa granice transakcji. Hibernate stara się w sposób abstrakcyjny traktować środowisko, w którym przy- chodzi mu pracować. W środowisku niezarządzanym sam obsługuje transakcje i połączenia JDBC (lub deleguje ich wykonanie do odpowiedniego kodu apli- kacji). W środowisku zarządzanym integruje się z transakcjami i połączeniami bazodanowymi zarządzanymi przez kontener. Hibernate potrafi poprawnie dzia- łać w obu środowiskach. W obu środowiskach pierwszym zadaniem jest uruchomienie Hibernate. W praktyce nie jest to trudne — wystarczy utworzyć obiekt SessionFactory, używając klasy Connection. 2.3.1. Tworzenie obiektu SessionFactory Aby uzyskać obiekt SessionFactory, należy najpierw utworzyć pojedynczy egzem- plarz klasy Configuration w momencie inicjalizacji aplikacji i skonfigurować ścieżki do plików odwzorowań. Po konfiguracji obiekt Configuration pozwala tworzyć egzemplarze SessionFactory. Po ich wykonaniu obiekt Configuration staje się zbędny. Poniższy kod uruchamia Hibernate: Configuration cfg = new Configuration(); cfg.addResource( hello/Message.hbm.xml ); cfg.setProperties(System.getProperties()); SessionFactory sessions = cfg.buildSessionFactory(); Lokalizację pliku odwzorowania, Message.hbm.xml, określa się względem pod- stawowej ścieżki klas aplikacji. Jeśli na przykład ścieżka klas jest aktualnym fol- derem, plik Message.hbm.xml musi znajdować się wewnątrz folderu hello. Pliki odwzorowania XML muszą znajdować się w ścieżce wyszukiwania klas. W przy- kładzie wykorzystujemy również właściwości systemowe maszyny wirtualnej, by ustawić pozostałe opcje konfiguracyjne (można je inicjalizować wcześniej w samej aplikacji lub przy uruchamianiu systemu maszyny wirtualnej). Łańcuch wywołań metod Tworzenie łańcuchów wywołań metod to styl programowania obsługiwany przez wiele interfejsów Hibernate. Jest on bardziej popularny w języku Smalltalk niż w Javie. Niektóre osoby uważają go za mniej czytelny i trud- niejszy do debugowania niż typowy styl programowania w Javie. W więk- szości sytuacji jest jednak wyjątkowo wygodny. Większość programistów Javy tworzy metody ustawiające lub doda- jące zwracające typ void, czyli brak wartości. Język SmallTalk nie posiada typy void, więc metody ustawiające lub dodające zwracają obiekt otrzy- mujący dane. Takie podejście umożliwia zmianę wcześniejszego kodu na następujący. 2.3. Konfiguracja podstawowa 61 SessionFactory sessions = new Configuration() .addResource( hello/Message.hbm.xml ) .setProperties(System.getProperties()) .buildSessionFactory(); Zauważ, że nie potrzeba deklarować lokalnej zmiennej dla obiektu Confi- guration. Styl ten będzie stosowany w niektórych przykładach, ale gdy ktoś go nie lubi, nie wymuszamy jego stosowania. Jeśli ktoś go lubi, zalecamy pisanie każdego wywołania metody w osobnym wierszu. W przeciwnym razie znacznie trudniej testować utworzony kod debugerem. Przyjęło się, że pliki odwzorowań Hibernate w formacie XML zapisuje się w pli- kach z rozszerzeniem .hbm.xml. Dodatkowo przyjęło się, by tworzyć osobny plik odwzorowania dla każdej klasy, zamiast umieszczać cały opis odwzorowań w jed- nym pliku (jest to możliwe, ale nie jest zalecane). Przedstawiony przykład „Witaj świecie” stosuje tylko jedną klasę trwałości, ale załóżmy, że jest ich wiele i każde odwzorowanie znajduje się w osobnym pliku. Gdzie należy umieścić pliki odwzo- rowań? Dokumentacja Hibernate zaleca, by plik odwzorowania dla każdej klasy trwa- łości umieszczać w tym samym folderze co klasę. Przykładowo, plik odwzoro- wania dla klasy Message należy umieścić w folderze hello pod nazwą Message. hbm.xml. Dla innej klasy trwałej należałoby wykonać osobny plik odwzorowania. Zalecamy stosować się do przedstawionej sugestii. Monolityczne pliki metada- nych narzucane przez niektóre systemy szkieletowe, na przykład struts-config.xml z Struts, są głównym czynnikiem powodującym powstanie hasła „piekło meta- danych”. Wiele plików odwzorowań wczytuje się, wielokrotnie wywołując metodę addResource(). Ewentualnie, gdy programista stosuje się do przedstawionej powy- żej konwencji, może użyć metody addClass(), przekazując jako parametr klasę trwałą. SessionFactory sessions = new Configuration() .addClass(org.hibernate.auction.model.Item.class) .addClass(org.hibernate.auction.model.Category.class) .addClass(org.hibernate.auction.model.Bid.class) .setProperties(System.getProperties()) .buildSessionFactory(); Metoda addClass() zakłada, że nazwa pliku odwzorowania kończy się rozszerze- niem .hbm.xml i znajduje się w tym samym folderze co odwzorowywany plik klasy. Przedstawimy tworzenie pojedynczego obiektu SessionFactory, ponieważ takie podejście występuje w aplikacjach najczęściej. Jeśli potrzebny jest kolejny obiekt, bo na przykład istnieje kilka baz danych, cały proces powtarza się od nowa. W ten sposób zawsze istnieje jeden obiekt SessionFactory na bazę danych gotowy do tworzenia obiektów Session działających z tą bazą danych i zestawem odwzo- rowań klas. Konfiguracja Hibernate to nie tylko wskazanie dokumentów odwzorowań. Trzeba również wskazać sposób uzyskania połączenia z bazą danych oraz określić zachowanie Hibernate w różnych sytuacjach. Mnogość dostępnych właściwości konfiguracyjnych potrafi przytłoczyć (pełna ich lista znajduje się w dokumentacji 62 ROZDZIAŁ 2. Wprowadzenie i integracja Hibernate Hibernate). Na szczęście większość parametrów stosuje sensowne wartości do- myślne, więc najczęściej potrzeba zmienić tylko ich niewielką część. Aby określić opcje konfiguracyjne, korzysta się z jednej z wymienionych technik. (cid:141) Przekazuje się egzemplarz klasy java.util.Properties jako parametr metody Configuration.setProperties(). (cid:141) Ustawia się właściwości systemowe za pomocą konstrukcji java -Dwłaściwość=wartość. (cid:141) Umieszcza się w ścieżce wyszukiwania klas plik o nazwie hibernate. properties. (cid:141) Dołącza się elementy property do pliku hibernate.cfg.xml znajdującego się w ścieżce wyszukiwania klas. Techniki pierwszą i drugą stosuje się naprawdę rzadko — jedynie w trakcie testów lub szybkiego prototypowania. Większość aplikacji potrzebuje stałego pliku konfi- guracyjnego. Oba pliki, hibernate.properties i hibernate.cfg.xml, pełną tę samą funkcję — konfigurują Hibernate. Wybór pliku zależy tak naprawdę od własnych preferencji co do składni właściwości. Możliwe jest nawet mieszanie obu technik i posiadanie osobnych ustawień dla środowiska testowego i wdrożeniowego. Przed- stawimy to zagadnienie w dalszej części rozdziału. Bardzo rzadko stosowanym rozwiązaniem alternatywnym jest przekazywanie przez aplikację obiektu Connection z JDBC w momencie tworzenia obiektu Session dzięki obiektowi SessionFactory (powstaje wtedy kod typu sessions.openSession (myConnection)). Opcja ta pozwala nie podawać w trakcie konfiguracji żadnych opcji związanych z połączeniem z bazą danych. Nie polecamy takiego podejścia dla nowych aplikacji, które mogą skorzystać z infrastruktury połączeń bazodano- wych całego środowiska (na przykład wykorzystując pulę połączeń JDBC lub źró- dła danych serwera aplikacji). Ze wszystkich opcji konfiguracyjnych najważniejsze są ustawienia połącze- nia bazodanowego. Różnią się w zależności od tego, czy stosuje się środowisko zarządzane czy niezarządzane. Z tego względu opis rozbijemy na dwa przypadki. Zacznijmy od środowiska niezarządzanego. 2.3.2. Konfiguracja w środowisku niezarządzanym W środowisku niezarządzanym, na przykład kontenerze serwletów, aplikacja odpowiada za uzyskanie połączeń JDBC. Hibernate jest częścią aplikacji, więc również może uczestniczyć w ich uzyskaniu. Plik konfiguracyjny informuje, w jaki sposób Hibernate może uzyskać (lub utworzyć nowe) połączenia JDBC. Ogól- nie nie zaleca się tworzenia połączeń za każdym razem, gdy tylko chce się skorzy- stać z bazy danych. Aplikacja Javy powinna zatem używać puli połączeń JDBC. Istnieją trzy powody przemawiające ze stosowaniem puli: (cid:141) Uzyskiwanie nowych połączeń jest kosztowne. (cid:141) Utrzymywanie wielu niewykorzystywanych połączeń jest kosztowne. 2.3. Konfiguracja podstawowa 63 (cid:141) Tworzenie instrukcji przygotowanych dla niektórych sterowników również jest kosztowne. Rysunek 2.2 przedstawia rolę puli połączeń JDBC w środowisku wykonawczym aplikacji internetowej. Ponieważ samo środowisko nie udostępnia puli połączeń bazodanowych,
Pobierz darmowy fragment (pdf)

Gdzie kupić całą publikację:

Hibernate w akcji
Autor:
,

Opinie na temat publikacji:


Inne popularne pozycje z tej kategorii:


Czytaj również:


Prowadzisz stronę lub blog? Wstaw link do fragmentu tej książki i współpracuj z Cyfroteką: