Magdalena Fret I Edukacja Medialna i Informatyczna II stopnia/pedagogika Lab A1 studia stacjonarne Rozwój aplikacji wykorzystujących hibernate 1). Pojęcie Hibernate Hibernate jest frameworkiem służącym do realizacji warstwy dostępu do danych. Hibernate zwiększa wydajność operacji na bazie danych dzięki buforowaniu i minimalizacji liczby przesyłanych zapytań. Framework Hibernate pozwala na kaskadowe wykonywanie operacji usuwania i zapisu. Hibernate jest darmowym systemem ORM o otwartych źródłach. A więc wykonuje kompletne mapowanie obiektowo relacyjne, tym samym również dodaje jedynie niewielkie ograniczenia do projektów aplikacji. System można zaliczyć do całkowicie konfigurowalnych, a także przenośnych. Mianowicie te cechy charakteryzują sukces, jaki osiągnął Hibernate, jest więc jest też często wykorzystywany w aplikacjach płatnych. W dzisiejszych czasach, programiści są bardzo związani z obiektowością. Zdarza się również tak, że duża ilość firm jest związana z obiektowością, ale pod względem inwestycji o długim okresie czasu, które to firmy inwestują w bardzo kosztowne relacyjne systemy bazodanowe. Dane, które przedstawiane są w postaci tabel w systemach relacyjnych w zupełności różnią się od różnorodnych obiektów, które są wykorzystywane w aplikacjach Javy. Takie różnice nazywane są niedopasowaniem paradygmatów relacyjno obiektowych. Narzędzia, które starały się ten problem okazały się być chybione. ORM - odwzorowanie relacyjno obiektowe, jest to nazwa nadana rozwiązaniom, które o charakterze zautomatyzowanym miały znieść niedopasowanie. A więc dzięki ORM programiści unikną czasochłonnego procesu pisania i tworzenia kodu, toteż aplikacje, które korzystały z ORM okazały się być dużo mniej kosztowne, o wiele bardziej wydajne, mniej zależne od odpowiedniego systemu bazodanowego oraz można je łatwiej modyfikować w postaci schematów bazy danych lub w reprezentacji obiektowej. Takie pozytywne rozwiązania są zupełnie za darmo dostępne dla programistów. Gavin King rozpoczął tworzyć hibernate w końcu 2001 roku, w momencie, kiedy zauważył, gdy w ówczesnym czasie popularne
rozwiązanie, które miało za zadanie zapewnić trwałość danych o nazwie CMP Enity Beans odpowiednio nie współpracuje z większymi aplikacjami, które posiadały modele danych bardzo złożone. A więc hibernate rozpoczęło swoją pracę jako projekt niekomercyjny w rodzaju open source. Grupa Hibernate (wraz z autorami) przyswajała sobie ORM, słuchając próśb użytkowników, realizując je. Dzięki temu, końcowe rozwiązanie okazało się o wiele bardziej praktyczne, a więc zwiększające produktywność. Hibernate używane jest przez tysiące ludzi, w kilku tysiącach różnorodnych aplikacji. W chwili, gdy realizowanie wielu próśb ludzi użytkujących aplikacje było procesem za bardzo czasochłonnym, zespół Hibernate zatrudnił profesjonalnych programistów. W 2003 roku projekt dołączył do jboss.org i posiada charakter komercyjny, a mianowicie można kupić w rodzaju wsparcia technicznego lub szkolenia w JBoss Inc. Jednak płatne szkolenia to nie jedyny sposób na zapoznanie się z Hibernate. Trwałość danych jest inspiracją programistów do dyskusji. Duża ilość programistów nie jest zgodna co do zasięgu trwałości. Toteż Hibernate jest projektem, który stara się rozwiązać problem zarządzania trwałością danych w języku programowania Java. A więc łączy ze sobą interakcje aplikacji wraz z relacyjną bazą danych, toteż dzięki temu stwarza programistom możliwość skupić się na pojęciach o charakterze biznesowym. Hibernate nie jest inwazyjne, mianowicie nie jest konieczne propagowanie jego wszelkich reguł w czasie projektowania własnego projektu z pomysłem o charakterze biznesowym oraz trwałości klas danych. Biblioteka również bardzo dobrze współpracuje z dużą liczbą nowych i obecnie używanych aplikacji, nie wymagając przy tym stosowanie ważnych zmian w pozostałej części aplikacji. Budowa aplikacji Hibernate: Część konfiguracyjna, a więc całość plików do konfiguracji zawarta jest w jednym pliku, najczęściej o nazwie hibernate.cfg.xml, Wiele klas mapowanych, tabele w bazie danych, np. Person.java, Contakt.java. Najczęściej takie klasy posiadają dużą ilość atrybutów, a dla każdego z nich przyporządkowane są metody: set ( ) oraz Get ( )), XML owe mappingi powyższych klas - to właśnie w nich można znaleźć opisy, w jaki sposób te klasy mogą ulec procesowi mapowania na poszczególne tabele w bazie danych.
Jedna lub więcej klas, które odwołują się do bazy danych, oraz tych, które wykorzystują z interfejsów takich jak: Transaction, Query, SessionFactory, Configuration, Session. Wyróżniamy pięć interfejsów podstawowych, które pojawiają się prawie w każdej aplikacji, która wykorzystuje Hibernate. Dzięki interfejsom programista może pobierać i zapamiętywać trwałe obiekty, z także może sterować transakcjami. Interfejs Session jest głównym interfejsem każdej aplikacji Hibernate. Projekty Session można uznać za lekkie, ponieważ ich koszt utworzenia, a także zniszczenia nie jest wielki. A więc jest to szczególnie ważny aspekt, ponieważ każda aplikacja nieustannie usuwa, a następnie tworzy coraz to nowsze sesje. Znaczenie sesji Hibernate można nazwać jako zjawisko między połączeniem i transakcją. Interfejs SessionFactory aplikacja zajmuje się pobieraniem egzemplarzy Session z SessionFactory. Interfejs SessionFactory nie można określić jako lekki, ponieważ został utworzony z myślą o współpracy przez większą ilość aplikacji. Często zdarza się tak, że na całą aplikację pojawia się tylko jeden obiekt SessionFactory, który powstaje w czasie procesu inicjalizacji. W przypadku, kiedy aplikacja wykorzystuje kilka baz danych wraz z Hibernate, to wtedy jest potrzebny osobny obiekt SessionFactory dla poszczególnej bazy danych. Interfejs Configuration służy on do konfiguracji i uruchomienia Hibernate. A więc aplikacja korzysta z egzemplarza Configuration do ustalenia położenia dokumentów odwzorowań i właściwości charakterystycznych dla Hibernate. Interfejs Transaction stara się ukryć szczegóły implementacji konkretnych mechanizmów transakcyjnych: JDBC, klasy UserTransaction z JTA lub nawet transakcji COBRA. Ma to na celu ułatwienie przenośności aplikacji Hibernate pomiędzy różnorodnymi środowiskami wykonywania i kontenerami. Aplikacje Hibernate nie są zmuszone korzystać z interfejsu Transaction, jeżeli chcą zarządzać transakcjami we własnym zakresie. Interfejs Query ma na celu umożliwić proces wysyłania zapytań do bazy danych oraz sterowanie procesem ich realizowania. Takie zapytania należy
pisać w języku WQL albo językiem odpowiednim dla poszczególnej bazy danych dialekcie SQL. Egzemplarz Query jest odpowiedzialny za zmniejszenie liczby zwracanych wyników i o wykonanie zapytania. 2). Jakie możliwości stwarza Hibernate? Hibernate jest rodzajem aplikacji, które służą do mapowania obiektowo relacyjnego. Do tego celu Hibernate korzysta z plików konfiguracyjnych, które działają na podstawie języka XML. Można je więc wymienić adnotacjami Javy. Poniższy rysunek przedstawia pozycję Hibernate wśród systemów informatycznych, a także ukazuje różne sposoby komunikacji z kodem klienta a bazą danych. Z rysunku wynika, że proces komunikacji nie odbywa się bezpośrednio pomiędzy klientem a interfejsem JDBC (ang. Java DataBase Connectivity - łącze do baz danych w języku Java), dzięki któremu możliwe staje się nawiązanie łączności z bazą danych za pośrednictwem języka SQL dla różnorodnych aplikacji napisanych w języku Java. Komunikuje się jedynie z Hibernate, który otwiera i zamyka wszelkie połączenia, a także dba o spójność danych, przetwarza w bazie danych operacje w transakcje, a jeśli dojdzie do awarii to wycofuje wprowadzone zmiany. rys. 1. Miejsce Hibernate w systemie informatycznym. Hibernate daje możliwość zapisywania w bazie obiektów POJO (Plain Old Java Object - termin używany przez zwolenników idei mówiącej, że im prostszy design tym lepiej). A więc POJO nie wymaga korzystania z pewnych konwencji nazewniczych, nie wymaga również stosowania trudnych metod, a także implementowania interfejsów. A mianowicie są to wszelkie obiekty Javy. Hibernate nie musi spełniać warunku polegającego
na tym, że jeden obiekt POJO musi być odwzorowany proporcjonalnie do jednej tabeli. Można więc stworzyć tabelę z kilku obiektów POJO, ale także utworzyć POJO z tylko z poszczególnych kolumn tabeli. Hibernate również pracuje ze związkami dziedziczenia oraz z relacjami pomiędzy tabelami, a więc także i takie bardzo trudne i rozbudowane, jak na przykład jeden do wielu oraz wiele do wielu. Hibernate udostępnia swój własny język zapytań, który jest nazwany Hibernate Query Language (HQL). Aspektem pozytywnym jest też fakt, iż Hibernate umożliwia trwałość bez konieczności używania kontenera Java EE, ani także innych skomplikowanych środowisk. A więc dzięki temu aplikacje stają się bardziej lżejsza i praktyczna, a więc za pośrednictwem tych czynników szybciej i prościej można ją testować. 3). Wady Hibernate. Wsparcie techniczne oraz dokumentacja Hibernate, które można znaleźć w Internecie można określić jako niewystarczająca, Posiada wiele usterek, Dla złożonych danych, proces mapowania danych z obiektu do tabeli i odwrotnie, zmniejsza wydajność, powodując tym samym wydłużenie czasu konwersji, Hibernate nie pozwala korzystać z poszczególnych zapytań, których można używać w JBDC, na przykład nie można wstawić dużej liczby obiektów do jednej i tej samej tabeli za pomocą jednego zapytania. 4). Aplikacje stosujące Hibernate. Projekt Hibernate tworzono z myślą o tym, żeby można było z niego korzystać w architekturze programistycznej, która może być dowolna, lecz należy założyć, że ta aplikacja musi być tworzona w języku Java. Hibernate działa wewnątrz systemu serweltów, a mianowicie w dostępnych szkieletach aplikacji internetowych, takich jak WebWork, Struts oraz Tapestry wewnątrz kontenera EJB, klienta Swing, kontenera lekkiego lub nawet serwera JMX, na przykład JBoss. Te środowiska wymagają podłoża integrującego Hibernate wraz z dostępnymi sposobami zarządzania żądaniami, zasobami bazodanowymi oraz transakcjami. Rdzeń hibernate posiada różnorodne komponenty, które mają za zadanie ułatwić proces integracji w typowych środowiskach, biorąc pod uwagę również obsługę JTA, źródeł danych JNDI, JMX, JCA oraz zarządców transakcji różnych popularnych serwerów
aplikacyjnych. Ciekawą sprawą jest fakt, iż niektóre szkielety służące do tworzenia aplikacji posiadają wbudowaną w sobie obsługę Hibernate, a więc do takich można zaliczyć na przykład Spring lub Keel. Natomiast inne posiadają takie moduły dodatkowe, które mają na celu zapewnić obsługę, jak na przykład Tapestry, Apache Avalon i PicoContainer. Serwer aplikacji JBoss posiada charakterystyczną obsługę archiwizacyjną dla Hibernate oraz integrację Hibernate jako komponent zarządzany zgodnie z JMX. Ze względu na dużą liczbę możliwych opcji, trudno się programiście zdecydować, w jaki sposób można zintegrować Hibernate z odpowiednią dla siebie architekturą opartą na języku Java. Mianowicie, trzeba więc utworzyć kod, który musi być powiązany z daną infrastrukturą, aby można było utworzyć własny projekt aplikacji. 5). Witaj świecie w stylu Hibernate. Różnorodne aplikacje Hibernate określają tak zwane klasy trwałe, a więc są one przedstawiane w postaci tabel baz danych. Zadaniem poniższej aplikacji jest zachowanie w pamięci komunikatów w bazie danych, a także musi istnieć proces pobierania komunikatów, aby je potem wyświetlić. Taka aplikacja wykorzystuje klasę trwałości Message, która przedstawia komunikaty do ich wyświetlenia. Package hello; Plik Message.java prosta klasa trwałości 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; Atrybut identyfikatora Treść komunikatu Referencja do innego komunikatu
Private void setid(long id) { This.id = id; Public String gettext () { Return text; Privatte void settext(string text) { This.text = text; Public Long getnextmessage() { Return nextmessage; Private void setnnextmessage(long nextmessage) { This.nextMessage = nextmessage; Klasa o nazwie Message składa się z trzech atrybutów, takich jak: treść komunikatu, identyfikator oraz referencja do innego komunikatu. Jeżeli dwa egzemplarze klasy Message zawierają taki sam identyfikator, to dotyczą one tego samego wiersza w tabeli danych. Wyświetlenie na konsoli napisu Witaj świecie Message message = new Message("Witaj świecie"); System.out.println(message.getText()); Powyższy kod powoduje wyświetlenie na konsoli napisu Witaj świecie. Możemy klasę trwałości wykorzystywać w dowolnym momencie, ponieważ nie wymaga żadnego poszczególnego kontenera.
Zapisywanie obiektu 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 ( ); Taki kod wykorzystuje interfejsy takie jak: Sesssion oraz Transaction systemu Hibernate. Uruchomienie takiego kodu spowoduje przekazanie do bazy danych polecenia SQL, który jest podobny do następnego kodu: Przekazanie do bazy danych polecenia SQL Insert into MESSAGE (MESSAGE_ID, MESSAGE_TEXT_NEXT_MESSAGE_ID) values (1, "Witaj świecie", null) Transaction tx = session.begintransaction( ); Message message = new Message( Witaj świecie ); Session.save(message); Tx.commit ( ); Session.close ( ); Kolejny kod będzie pobierał z bazy danych wszystkie komunikaty, w kolejności alfabetycznej, a następnie wyświetlał na konsoli ich zawartość: Pobieranie z bazy danych wszystkich komunikatów w kolejności alfabetycznej oraz wyświetlanie ich zawartości Session newsession = getsessionfactory ( ).opensession ( ); Transaction newtransaction = newsession.begintransaction( ); List messages = newsession.finf("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( ); Powyższe wyrażenie: from Message as m order by m.text asc oznacza zapytanie Hibernate, które jest opsane w obiektowym języku zapytań Hibernate (HQL Hibernate Query Language). Takie zapytanie przyjmuje inną formę na kod SQL w chwili, gdy zaczniemy wywoływać metodę find( ). Przekształcenie zapytania na kod SQL w chwili wywoływania metody find( ). Select m.message_id, m.message_text, m.next_message_id From MESSAGES m Order by m.message_text asc Taki kod powoduje wyświetlenie na konsoli napisu: Znalezionych komunikatów: 1 Witaj świecie Aby dany projekt mógł poprawnie działać, Hibernate wymaga większej ilości danych do zagwarantowania trwałości dla klasy Message. W formacie XML zwykle znajduje się tą informację w tak zwanym dokumencie odwzorowania. Taki dokument wyraża sposób, w jaki należy przedstawić cechy klasy Message na poszczególne kolumny tabeli MESSAGES. Prosty plik odwzorowania Hibernate w postaci XML <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.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 podaje informacje dla projektu Hibernate, iż klasa Message przekłada się na tabelę MESSAGES. Można z powyższego kodu również wywnioskować, że cechy identyfikatora musi dotrzeć do kolumny o nazwie MESSAGE_ID, a jeśli chodzi o właściwość nextmessage to jest ona skojarzona z krotnością wiele do jednego, a zatem musi ona trafić do kolumny nazwanej NEXT_MESSAGE_ID. Używając Hibernate programista może wykorzystywać narzędzia służące do generowania plików XML, a więc na podstawie annotacji, a także klas. Wielką zaletą Est więc fakt, że nie trzeba ręcznie pisać plików XML. 6). Bibliografia. Bauer Ch., King G.: Hibernate w akcji, popraw wydajność aplikacji bazodanowych w Javie, Wydawnictwo HELION, Gliwice 2005. Minter D., Linwood J.: Hibernate od Nowicjusza do Profesjonalisty, Polish edition Copyright 2007 by PowerNet. http://hibernate.org/ http://www.javaworld.com/javaworld/jw-10-2004/jw-1018-hibernate.html http://czajkowski.waw.pl/html/groovygrails/index.php?option=com_content&view=art icle&id=14:hibernate-wprowadzenie&catid=8:hibernate&itemid=7 http://www.mimuw.edu.pl/~sroka/archiwalne/2006j2ee/lab9/10/www/index.htm http://cvs.ii.uni.wroc.pl/~zsz/poo/hibernate.pdf http://jlaskowski.blogspot.com/2006/02/hibernate-tniemy-koszty-dostpu-do.html
http://www.mimuw.edu.pl/~sroka/archiwalne/2006j2ee/lab9/8/www/hib.html#wstep http://www.javapassion.com/handsonlabs/hibernatestepbystep/ http://software.com.pl/spring-framework-3-0-tutorial-%e2%80%93-cz-2- %E2%80%93-baza-danych-walidacja-wiadomosci-encje-hibernate/