Serwery aplikacji. mgr Radosław Matusik. Wydział Matematyki i Informatyki Uniwersytetu Łódzkiego www.math.uni.lodz.pl/ radmat radmat@math.uni.lodz.



Podobne dokumenty
Mapowanie obiektowo-relacyjne z wykorzystaniem Hibernate

Bazy danych tworzenie aplikacji bazodanowych ORM / JPA

Programowanie wielowarstwowe i komponentowe

Dostęp do baz danych w aplikacjach Java EE

Programowanie obiektowe

Java Server Faces narzędzie do implementacji w wy prezentacji

Metody dostępu do danych

Informacje wstępne Autor Zofia Kruczkiewicz Wzorce oprogramowania 4

Konwersja danych. Programowanie komponentowe 4. wg bnaph.html

Budowa prostej aplikacji wielowarstwowej. Laboratorium 1 Programowanie komponentowe Zofia Kruczkiewicz

Programowanie obiektowe

Serwery aplikacji. dr Radosław Matusik. radmat

Tworzenie aplikacji dla Oracle Application Server 10g R3 w technologii EJB 3.0

Podejście obiektowe do relacyjnych baz danych Hibernate.

Programowanie obiektowe

Metody dostępu do danych

1 Wprowadzenie do J2EE

NHibernate Hibernate dla platformy.net. Hibernate posiada także dużą społeczność, zatem nietrudno uzyskać jakieś wsparcie w przypadku problemów.

Programowanie obiektowe i zdarzeniowe wykład 4 Kompozycja, kolekcje, wiązanie danych

ODWZOROWANIE OBIEKTOWO-RELACYJNE

Hibernate. Adrian Gawor, Adam Klekotka, Piotr Kubisz. Technologie Biznesu Elektronicznego. 12 maja 2009

Programowanie w języku Java WYKŁAD

Aplikacje w środowisku Java

Wzorce logiki dziedziny

Oracle PL/SQL. Paweł Rajba.

Podyplomowe Studium Informatyki w Bizniesie Wydział Matematyki i Informatyki, Uniwersytet Łódzki specjalność: Tworzenie aplikacji w środowisku Oracle

JDBC w LoXiMie. Interfejs Java Database Connectivity dla systemu LoXiM. Adam Michalik 2008

Enterprise JavaBeans

Temat: Ułatwienia wynikające z zastosowania Frameworku CakePHP podczas budowania stron internetowych

Programowanie MSQL. show databases; - pokazanie jakie bazy danych są dostępne na koncie

Programowanie obiektowe

Projektowanie bazy danych. Jarosław Kuchta Projektowanie Aplikacji Internetowych

Tworzenie komponentów logiki biznesowej i warstwy dostępu do danych w oparciu o EJB3.0/JPA lub EJB 3.1/JPA2

Obiektowy PHP. Czym jest obiekt? Definicja klasy. Składowe klasy pola i metody

Aplikacje w środowisku Java

Dariusz Brzeziński. Politechnika Poznańska, Instytut Informatyki

EJB 3.0 (Enterprise JavaBeans 3.0)

Dokumentacja do API Javy.

Wprowadzenie do Doctrine ORM

Laboratorium 03: Podstawowe konstrukcje w języku Java [2h]

Budowa aplikacji wielowarstwowych zastosowanie szablonów. Laboratorium 2 Programowanie komponentowe Zofia Kruczkiewicz

NHibernate. Narzędzie mapowania obiektowo - relacyjnego

Programowanie komponentowe 5

15. Funkcje i procedury składowane PL/SQL

Odwzorowanie obiektowo-relacyjne

Java. język programowania obiektowego. Programowanie w językach wysokiego poziomu. mgr inż. Anna Wawszczak

Zaawansowane Techniki Bazodanowe

Programowanie obiektowe

Projektowanie obiektowe oprogramowania Wzorce architektury aplikacji (3) Wykład 11 Repository, Unit of Work Wiktor Zychla 2016

Enterprise JavaBeans. 1. Architektura EJB: komponenty encyjne, komponenty sesyjne, komponenty sterowane komunikatami. 2. Kontenery EJB JBoss.

PARADYGMATY PROGRAMOWANIA Wykład 4

Wprowadzenie do technologii JavaServer Faces 2.1 na podstawie

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

Bazy danych 2. Wykład 1

E:\DYDAKTYKA\ZAI\ZWWW\Laboratoria\L07\Java Persistence.doc 2011-lis-24, 17:0 Zaawansowane aplikacje internetowe Laboratorium Java Persistence.

Podstawowe wykorzystanie Hibernate

Aplikacja webowa w Javie szybkie programowanie biznesowych aplikacji Spring Boot + Vaadin

BEAN VALIDATION. Waldemar Korłub. Narzędzia i aplikacje Java EE KASK ETI Politechnika Gdańska

EJB 2.x oraz zmiany w standardzie dla EJB 3.0. Michał Stanek

Java. Michał Wójcik.

JPA Java Persistance API

Budowa aplikacji w technologii. Enterprise JavaBeans. Maciej Zakrzewicz PLOUG

Projektowanie obiektowe oprogramowania Wykład 9 Wzorce architektury aplikacji (1) Wiktor Zychla 2013

Dotacje na innowacje. Inwestujemy w waszą przyszłość.

Bazy danych - wykład wstępny

Programowanie w języku Java. Wykład 13: Java Platform, Enterprise Edition (Java EE)

Szkolenie wycofane z oferty

Programowanie w Ruby

UML a kod w C++ i Javie. Przypadki użycia. Diagramy klas. Klasy użytkowników i wykorzystywane funkcje. Związki pomiędzy przypadkami.

JAVA W SUPER EXPRESOWEJ PIGUŁCE

Programowanie współbieżne Wykład 8 Podstawy programowania obiektowego. Iwona Kochaoska

SYSTEM MONITORINGU PARAMETRÓW WĘZŁÓW PRZECHOWYWANIA DANYCH DLA PROJEKTU KRAJOWY MAGAZYN DANYCH PODRĘCZNIK DEWELOPERA

Technologie i usługi internetowe cz. 2

Wprowadzenie do technologii JavaServer Faces 2.1 na podstawie

Warstwa integracji. wg. D.Alur, J.Crupi, D. Malks, Core J2EE. Wzorce projektowe.

Wybrane działy Informatyki Stosowanej

Interfejsy. Programowanie obiektowe. Paweł Rogaliński Instytut Informatyki, Automatyki i Robotyki Politechniki Wrocławskiej

Wykład 8: klasy cz. 4

Ref. 7 - Język SQL - polecenia DDL i DML

Kurs programowania. Wykład 1. Wojciech Macyna. 3 marca 2016

PHP: bazy danych, SQL, AJAX i JSON

EJB 3.0 & JBoss Seam. 25 kwietnia 2007 Jacek Gerbszt 1

Systemy baz danych. mgr inż. Sylwia Glińska

Kurs programowania aplikacji bazodanowych

Technologie obiektowe

Wprowadzenie do technologii JavaServer Faces 2.2 na podstawie Wykład 2 Technologie internetowe

JAX-RS czyli REST w Javie. Adam Kędziora

Java - wprowadzenie. Programowanie Obiektowe Mateusz Cicheński

Projektowanie aplikacji z bazami danych

Zasady generowania kluczy głównych Język Java Persistence Podstawowa architektura wielowarstwowych aplikacji w oparciu o wzorce oprogramowania

Instrukcja 2 Laboratorium z Podstaw Inżynierii Oprogramowania

Plan prezentacji. Budowa aplikacji w technologii Enterprise JavaBeans. Przegląd architektur: CORBA. Cele budowy aplikacji rozproszonych

Enterprise JavaBeans 3.0

JAVA. Java jest wszechstronnym językiem programowania, zorientowanym. apletów oraz samodzielnych aplikacji.

Baza danych sql. 1. Wprowadzenie. 2. Repozytaria generyczne

Technologia informacyjna

TEMAT : KLASY DZIEDZICZENIE

Zaawansowane aplikacje WWW - laboratorium

Co nowego w Java EE?

Gdzie jest moja tabela?

Transkrypt:

Wydział Matematyki i Informatyki Uniwersytetu Łódzkiego www.math.uni.lodz.pl/ radmat radmat@math.uni.lodz.pl

Konwersja i walidacja W wyniku działania konwersji i walidacji surowe dane, przesyłane w postaci żądania HTTP, przekształcane są na logiczne struktury danych występujące w Javie. Następnie sprawdzane są pod kątem poprawności. Dzięki temu możemy zapomnieć o wielu pojawiających się problemach, które ujawniają się w przypadku innych technologii webowych. JSF zadba za nas niemal o wszystko. Procesy konwertowania i walidacji stanowią istotną część drugiej i trzeciej fazy cyklu życia aplikacji JSF. Po wykonaniu pierwszego kroku JSF wie, czy żądanie przesłane przez użytkownika zostało zrealizowane po raz pierwszy w obrębie danej sesji (tzw. initial view), czy też użytkownik korzysta z danego widoku po raz kolejny (tzw. postback). Oczywiście w pierwszym przypadku konwertowanie i walidacja nie występują, ponieważ użytkownik nie miał możliwości przesłania żadnych danych, które podlegałyby konwersji i walidacji.

Konwertowanie standardowych wartości jest procesem w dużym stopniu zautomatyzowanym. Wszystkie prymitywne typy danych, takie jak int, double, itp. mogą być bez problemu konwertowane do typu String i odwrotnie. Dzięki temu wartość typu double zapisana np. w polu tekstowym zostanie wyświetlona poprawnie, natomiast po zmianie tej wartości przez użytkownika, Java spróbuje dokonać konwersji łańcucha znaków na liczbę. Jeśli operacja ta przebiegnie poprawnie, to wartość pola zostanie przekazana dalej do walidacji. Problemy zaczynają się, gdy istnieje potrzeba skorzystania z klasy, która nie może być automatycznie konwertowana na typ String. W tej sytuacji konieczne staje się napisanie własnego konwertera.

Konwertery standardowe W zdecydowanej większości typowych przypadków konwersja realizowana jest za pomocą standardowych konwerterów. Programiści firmy Sun udostępnili standardowe konwertety dla wartości typów prymitywnych: 1 Liczb całkowitych IntegerConverter LongConverter ShortConverter ByteConverter 2 Liczb zmiennoprzecinkowych DoubleConverter FloatConverter 3 Znaków CharacterConverter 4 Wartości logicznych BooleanConverter

Oprócz wymienionych powyżej konwerterów typów prymitywnych otrzymujemy dwa dodatkowe: BigIntegerConverter - dzięki któremu można wykonywać operacje na liczbach całkowitych o dowolnej długości BigDecimalConverter - dzięki któremu można wykonywać operacje na liczbach zmiennoprzecinkowych o dowolnej długości

NumberConverter - rozbudowany konwerter liczb Nie w każdym przypadku konwersji liczb wystarczą nam powyższe konwertery. Trochę więcej możliowści konwersji daje klasa NumberConverter. <h:inputtext id="info" value="#{ziarno.kwota}"> <f:convertnumber type="currency" /> </h:inputtext>

Najważniejsze atrybuty: minfractiondigits - minimalna liczba cyfr umieszczonych po przecinku maxfractiondigits - maksymalna liczba cyfr umieszczonych po przecinku minintegerdigits - minimalna liczba cyfr części ułamkowej maxintegerdigits - maksymalna liczba cyfr części ułamkowej integeronly - określa, czy powinna być zwracana jedynie część całkowita liczby type - określa typ konwertowanej liczby. Dozwolonymi wartościami są: percent (procent), currency (kwota pieniężna), number (liczba) pattern - określa wzorzec, jaki musi spełniać konwertowany łańcuch znaków. Wzorzec ten musi spełniać reguły określone w java.text.decimalformat.

Zauważmy, że w zależności od przekazanej wartości i ustawień niektórych atrybutów, konwerter może zwrócić obiekt typu Long lub Double. Oba typy dziedziczą po klasie Number, dlatego to właśnie atrybuty tej klasy powinny być deklarowane w klasie ziaren zarządzanych.

DataTimeConverter - konwerter daty i czasu Data i czas - analogicznie jak w przypadku wcześniejszych technologii - reprezentowane są w JSF przez klasę java.util.date. W przeciwieństwie do pozostałych klas konwerterów standardowych, konwerter DataTimeConverter nie zawsze zadziała zgodnie z naszymi oczekiwaniami! Związane jest to z możliwością różnego zapisu daty i czasu. Niezbędne okazuje się wówczas jawne określenie konwertera, opcjonalnie z dodatkowymi argumentami. Można to uczynić w następujący sposób: <h:inputtext id="info" value="#{ziarno.czas}"> <f:convertdatatime type="time" /> </h:inputtext>

Ten prosty zapis pozwala na uzyskanie oczekiwanego przez nas efektu. Oczywiście kontrola nad konwertowaniem daty i czasu może być bardziej wyrafinowana, dzięki zastosowaniu atrybutów: type - określa składowe, jakie mogą wystąpić w obrębie zmiennej typu Date. Dozwolonymi wartościami są date, time i both. datastyle - określa jeden z predefiniowanych formatów daty, jaki może przyjąć zmienna. Dozwolonymi wartościami są default, short, medium, long, full. timestyle - określa jeden z predefiniowanych formatów czasu, jaki może przyjąć zmienna. Dozwolone wartości są takie same, jak w przypadku datastyle. pattern - określa dowolny schemat daty i czasu, zgodny ze specyfikacją akceptowaną przez klasę java.text.simpledataformat. Np. wzorcowi h:mm odpowiadają m.in. 02:18, 09:30, czy 18:00.

EnumConverter - konwerter typu wyliczeniowego Typy wyliczeniowe rzadko występują w aplikacjach webowych. Twórcy takich aplikacji często bowiem zamiast tradycyjnego typu wyliczeniowego stosują zwykłe łańcuchy znaków. Zauważmy bowiem, że typy wyliczeniowe są de facto łańcuchami znaków. W związku z tym konwerter typu wyliczeniowego EnumCoverter nie sprawia tylu kłopotów, ile konwerter daty i czasu. Koniecznie trzeba zwrócić uwagę w jaki sposób należy wprowadzać wartości tekstowe, aby te zostały dopasowane do typu wyliczeniowego. Oczywiście należy wprowadzać je dokładnie, trzeba zachować wielkości znaków i nie stosować białych znaków. Za bezpośrednią operację konwersji tekstu do typu wyliczeniowego odpowiedzielna jest metoda Enum.ValueOf().

Przykład konwertera Wbrew pozorom napisanie własnego konwertera nie jest skomplikowane. Musimy jedynie obsłużyć dwie kluczowe operacje, czyli konwersję wprowadzonego do aplikacji typu do łańcucha znaków oraz operację odwrotną. Po utworzeniu klasy musimy jedynie dodać odpowiednie wpisy w pliku faces-config.xml. Klasa konwertera musi implementować interfejs javax.faces.convert.converter. Dzięki temu interfejsowi można zapomnieć o interakcji z JSF. Można zaimplementować następujące metody: Object getasobject(facescontext kontekst, UIComponent komponent, String wartość) - metoda ta zwraca obiekt przekonwertowany z podanej wartości tekstowej. Komponent określa skąd została pobrana wartość. String getasstring(facescontext kontekst, UIComponent komponent, Object wartosc) - metoda ta zwraca łańcuch znaków, utworzony na podstawie przekazanego obiektu.

Walidator Wszystkie walidatory muszą implementować interfejs javax.faces.validator.validator. W tej klasie implementuje się jedną metodę public void validate (FacesContext kontekst, UIComponent komponent, Object wartość), która poddaje walidacji przekazaną wartość uzyskaną z danego komponentu, w aplikacji o podanym kontekście. W przypadku błędu, metoda powinna wyrzucić wyjątek ValidatorException.

Walidacja liczb Walidatory DoubleRangeValidator i LongRangeValidator odpowiadają za walidację liczb, które mieszczą się w zakresie podanym w atrybutach minimum i maximum. <h:inputtext id="wiek" value="#{osoba.wiek}"> <f:validatelongrange minimum="1" maximum="110" /> </h:inputtext>

Walidacja łańcuchów znaków Za walidację łańcuchów znaków odpowiada klasa LengthValidator. Udostępnia - podobnie jak walidatory liczb - atrybuty minimum i maximum, które określają minimalną i maksymalną długość łańcucha znaków, który podlega walidacji: <h:inputtext id="imie" value="#{osoba.imie}"> <f:validatelength minimum="3" maximum="15" /> </h:inputtext>

Jeden z podstawowych mechanizmów walidacji może polegać na sprawdzaniu, czy wartość danego pola została wypełniona. JSF daje taką możliwość, ale nie za pomocą osobnego walidatora. Wystarczy bowiem skorzystać z atrybutów required i requiredmessage komponentów wejścia. Pierwszy z nich określa, czy wprowadzenie wartości w danym polu jest obowiązkowe. Drugi natomiast zawiera informację, która zostanie wyświetlona w przypadku, gdy pole nie zostanie wypełnione: <h:inputtext id="imie" value="#{osoba.imie}" required="true" requiredmessage="nie podano imienia." />

Przykład konwertera i walidatora Napiszemy teraz klasę, której zadanie będzie polegało na konwertowaniu oddzielonych spacjami liczb (wprowadzanymi z pól tekstowych) do listy liczb całkowitych i odwrotnie. Taki konwerter wykorzystamy do obliczania sumy dowolnej ilość liczb.

Klasa Kalkulator.java public class Kalkulator { private int liczba1; private int liczba2; private int suma; private ListaLiczb liczby; public int getliczba1() { return liczba1; } public void setliczba1(int liczba1) { this.liczba1=liczba1; }

public int getliczba2() { return liczba2; } public void setliczba2(int liczba2) { this.liczba2=liczba2; } public int getsuma() { return suma; } public String oblicz() { this.suma=this.getliczba1()+this.getliczba2(); return null; }

public ListaLiczb getliczby() { return liczby; } public void setliczby(listaliczb liczby) { this.liczby=liczby; } } public String obliczmulti() { this.suma=this.getliczby().getsuma(); return null; }

Klasa ListaLiczb.java import java.util.list; public class ListaLiczb { private List<Integer> lista; public List<Integer> getlista() { return lista; } public void setlista(list<integer> lista) { this.lista=lista; }

} public int getsuma() { if(lista==null) return 0; int suma=0; for(integer i:this.lista) suma+=i; return suma; }

Klasa KonwerterLiczbJava import java.util.arraylist; import java.util.list; import javax.faces.application.facesmessage; import javax.faces.component.uicomponent; import javax.faces.context.facescontext; import javax.faces.convert.converterexception;

public class KonwerterLiczb implements javax.faces.convert.converter { public String getasstring(facescontext kontekst, UIComponent komponent, Object wartosc) { if(!(wartosc instanceof ListaLiczb)) throw new ConverterException (new FacesMessage("Blad konwersji.")); } List<Integer> lista =((ListaLiczb)wartosc).getLista(); String wynik=""; for(integer i:lista) wynik+=(i+" "); return wynik;

public Object getasobject(facescontext kontekst, UIComponent komponent, String wartosc) { String[] liczby=wartosc.split(" "); List<Integer> lista=new ArrayList<Integer>(); for(string s:liczby) { try { Integer i=integer.valueof(s); lista.add(i); } catch(numberformatexception nfe) { throw new ConverterException (new FacesMessage("Blad konwersji.")); } }

} } ListaLiczb ll=new ListaLiczb(); ll.setlista(lista); return ll;

Plik index.xhtml <?xml version= 1.0 encoding= UTF-8?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"> <h:head> <title>kalkulator</title> </h:head>

<h:body> <h:form id="formularz"> <h:outputlabel for="formularz:liczba1"> Liczba 1:</h:outputLabel> <h:inputtext id="liczba1" value="#{kalkulator.liczba1}" required="true" requiredmessage="podaj 1 liczbe" /> <br />

<h:outputlabel for="formularz:liczba2"> Liczba 2:</h:outputLabel> <h:inputtext id="liczba2" value="#{kalkulator.liczba2}" required="true" requiredmessage="podaj 2 liczbe" /> <br /> <h:outputlabel for="formularz:liczby"> Liczby:</h:outputLabel> <h:inputtext id="liczby" value="#{kalkulator.liczby}" required="true" requiredmessage="podaj liczby" /> <br />

<h:commandbutton value="oblicz" action="#{kalkulator.oblicz}" /> <h:commandbutton value="oblicz sumę" action="#{kalkulator.obliczmulti}" /> <br /> <h:outputtext value="suma: #{kalkulator.suma}" /> </h:form> </h:body> </html>

Plik index.xhtml z własnym walidatorem <h:outputlabel for="formularz:liczba1"> Liczba 1:</h:outputLabel> <h:inputtext id="liczba1" value="#{kalkulator.liczba1}" /> <br /> <h:outputlabel for="formularz:liczba2"> Liczba 2:</h:outputLabel> <h:inputtext id="liczba2" value="#{kalkulator.liczba2}" /> <br /> <h:outputlabel for="formularz:liczby"> Liczby:</h:outputLabel>

<h:inputtext id="liczby" value="#{kalkulator.liczby}" > <f:validator id="walidator" validatorid="walidatorliczb"> /> </h:inputtext> <br /> <h:commandbutton value="oblicz" action="#{kalkulator.oblicz}" /> <h:commandbutton value="oblicz sumę" action="#{kalkulator.obliczmulti}" /> <br /> <h:outputtext value="suma: #{kalkulator.suma}" /> </h:form> </h:body> </html>

<faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_1.x version="2.1"> <managed-bean> <managed-bean-name>kalkulator</managed-bean-name> <managed-bean-class> pl.helion.jeeweb.fazyaplikacjijsf.kalkulator </managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean>

<converter> <converter-for-class> pl.helion.jeeweb.fazyaplikacjijsf.listaliczb </converter-for-class> <converter-class> pl.helion.jeeweb.fazyaplikacjijsf.konwerterlicz </converter-class> </converter> </faces-config>

JPA W przypadku wielu aplikacji internetowych źródłem danych jest baza danych, działająca w obrębie wybranego serwera bazodanowego, który najczęściej funkcjonuje w architekturze klient-serwer. Z reguły dostęp do bazy danych odbywa się za pomocą języka zapytań SQL, dzięki któremu możliwe jest tworzenie baz danych i wszystkich elementów wchodzących w jej skład, czyli tabel, widoków, itp., a także oczywiście wypełnianie bazy danymi. Język SQL (w przeciwieństwie do języków programowania takich jak np. C++, czy Java) występuje w różnych odmianach, w zależności od serwera bazodanowego, w którym został zaimplementowany. Można m.in. wyróżnić następujące języki, wywodzące się od standardu SQL: T-SQL (Microsoft SQL Server) PL/SQL (Oracle) PL/pgSQL (PostreSQL) MySQL

Różnice te sprawiają, że tworzenie aplikacji z wykorzystaniem jednego standardu języka SQL trzeba pisać z myślą o konkretnej implementacji języka SQL. Problem ten został dostrzeżony przez programistów Javy. Jego rozwiązanie polega na wykorzystaniu technologii JDBC - Java DataBase Connectivity. Technologia ta pełni funkcję interfejsu między aplikacjami tworzonymi w języku Java, a konkretnymi implementacjami baz danych SQL. Dzięki zastosowaniu JDBC można tworzyć aplikacje używając jednolitego zestawu klas, niezależnie od zastosowanej implementacji. Szczegóły połączenia z bazą danych mogą być przechowywane w jednym miejscu aplikacji, dzięki czemu ewentualne zmiany ustawień nie stanowią problemu.

Mimo ustandaryzowania sposobu połączenia i komunikacji z bazą danych, zapytania SQL nadal pozostawały zależne od konkretnej bazy danych. W przypadku rozbudowanych aplikacji webowych bardzo kłopotliwe było wprowadzanie zmian do klas korzystających z baz danych. Natomiast sam kod był bardzo nieprzejrzysty.

ORM ORM (Object-Relational Mapping) - mapowanie obiektowo-relacyjne. Zadaniem tego mechanizmu jest odwzorowywanie obiektów istniejących w obrębie języków programowania i powiązań między tymi obiektami na relacje istniejące w relacyjnych bazach danych. Zasadę działania mechanizmu ORM można podzielić na etapy: 1 Przygotowania - polegają na zestawieniu połączenia z bazą danych oraz utworzeniu odwzorowań pomiędzy obiektami, a relacjami występującymi w bazie danych. 2 Właściwe operacje - na tym etapie wykonujemy żądane operacje w języku SQL na danych.

Hibernate Hibernate jest najpopularniejszą implementacją odwzorowania ORM dla języka Java. Założeniem jego twórców było zaoferowanie rozwiązania określanego po angielsku jako Relational Persistence For Idiomatic Java, co oznacza zapewnienie trwałości obiektów ze wsparciem dla wszystkich mechanizmów obiektowych języka Java, takich jak obsługa asocjacji, kompozycji, dziedziczenia, polimorfizmu i kolekcji. Hibernate cechuje wysoka wydajność i skalowalność oraz wiele możliwości wydawania zapytań do bazy danych. Jest rozwiązaniem kategorii professional open source. Z jednej strony jego źródła są dostępne, a z drugiej jest on rozwijany przez firmę JBoss Inc., będącą znaczącym graczem na rynku serwerów aplikacj.

Architektura Hibernate: Rysunek: Architektura Hibernate

Stany obiektu w Hibernate 1 Ulotny (ang. transient) utworzony operatorem new, ale niezwiązany z sesją 2 Trwały (ang. persistent) posiada identyfikator i reprezentację w bazie danych związany z sesją 3 Odłączony (ang. detached) obiekt, który był trwały, ale jego sesja się zakończyła można go modyfikować, a następnie związać z nową sesją

Obsługa trwałości obiektów w aplikacjach opartych o Hibernate polega głównie na wywoływaniu odpowiednich metod na rzecz obiektu Session. Do uczynienia obiektu trwałym służy metoda save() obiektu Session. Odczyt obiektu o znanym identyfikatorze umożliwiają bardzo podobne do siebie metody load() i get() obiektu Session, natomiast do usuwania reprezentacji obiektu z bazy danych służy metoda delete() obiektu Session.

Klasy trwałe public class Osoba { private Long ID; private String nazwisko; public void setid(long ID) { this.id=id; } public Long getid() { return ID; } public void setnazwisko(string nazwisko) { this.nazwisko=nazwisko; } public String getnazwisko() { return nazwisko; } }

Trwałe klasy to klasy implementujące encje występujące w modelu danych aplikacji. Nie wszystkie instancje trwałej klasy muszą być trwałe. Hibernate najlepiej działa z klasami spełniającymi reguły POJO - Plain Old Java Object. Klasy POJO dla Hibernate muszą posiadać metody set / get dla trwałych pól i bezargumentowy konstruktor. Zalecane jest, aby klasa posiadała wyróżniony identyfikator (najlepiej sztuczny) w formie dodatkowego pola w klasie, typu nieprostego.

Odwzorowanie obiektowo-relacyjne w Hibernate jest definiowane w pliku lub plikach XML. Typowo odwzorowanie dla każdej trwałej klasy opisane jest w odrębnym pliku z rozszerzeniem.hbm.xml. Język do opisu odwzorowania jest zorientowany na opis odwzorowania z punktu widzenia klasy Java, a nie tabeli. Dokumenty opisujące odwzorowanie można tworzyć ręcznie lub korzystając z narzędzi. Istnieją generatory tworzące plik odwzorowania na podstawie klasy POJO, a także generujące klasy POJO i pliki odwzorowania dla istniejących tabel w bazie danych. Dokumenty opisujące odwzorowanie wskazywane są w pliku konfiguracyjnym hibernate.cfg.xml, ale mogą też być wskazane programowo w aplikacji.

Praca z obiektami Utworzenie i zachowanie obiektu Osoba o=new Osoba(); o.setnazwisko("kowalski"); Long ID=(Long)session.save(o); Odczyt i modyfikacja obiektu Osoba o=osoba()session.load(osoba.class, new Long(20)) o.setnazwisko("kowalski"); Usuwanie obiektu Osoba o=osoba()session.load(osoba.class, new Long(20)) session.delete(o);

Przykład asocjacji Załóżmy, że mamy dwie klasy trwałe: Wydział i Osoba, będące w relacji 1:N. Plik Osoba.java public class Osoba { private Long id; private String nazwisko; private Wydział w; } Plik Osoba.hbm.xml <class name="osoba" table="osoba">... <many-to-one name="w" column="osoba_id" not-null="true" /> </class>

Plik Wydział.java public class Wydział { private Long id; private String nazwa; private Set os; } Plik Wydział.hbm.xml <class name="wydział" table="wydział">... <set name="os"> <key column="osoba_id" /> <one-to-many class="wydział" /> </set> </class>

Język zapytań HQL Zapytania w HQL (Hibernate Query Language) mają następujące cechy: składnia podobna do języka SQL zorientowany obiektowo zapytania odwołują się do klas, a nie do tabel FROM osoba AS o WHERE o.nazwisko LIKE Kowalski ; Pełna składnia: List osoba=(list)session.createquery( "FROM osoba AS o WHERE o.nazwisko LIKE Kowalski ").list();

Java Persistance Java Persistence to nowy, opracowany razem z EJB 3.0 standard zapewniania trwałości obiektów w aplikacjach Java EE i Java SE, stanowiący część specyfikacji Java EE od wersji 5.0. Został on opracowany razem z EJB 3.0 w odpowiedzi na niepowodzenie lansowanej do tej pory koncepcji encyjnych EJB i niewątpliwy sukces technologii odwzorowania obiektowo-relacyjnego takich jak Hibernate czy Oracle Toplink. Technologie te, mimo że oparte o te same idee, różnią się jeśli chodzi o API. Standard Java Persistence jest oparty o odwzorowanie obiektowo-relacyjne i definiuje standardowe API do obsługi trwałości obiektów.

Elementy standardu Java Persistence to: Interfejs programistyczny Java Persistence API, obejmujący interfejs do zarządcy trwałości EntityManager; Język zapytań Java Persistence Query Language (JPQL), o składni przypominającej SQL, umożliwiający tworzenie przenaszalnych zapytań; Metadane o odwzorowaniu obiektowo-relacyjnym, najczęściej umieszczone w kodzie w formie adnotacji, z możliwością dodatkowej konfiguracji w środowisku produkcyjnym poprzez XML-owe pliki konfiguracyjne.

Encje @Entity public class Blad implements Serializable { @id private Long id; private String opis; public Blad() {}; public Long getid() {return id;} public void setid (Long id) {this.id=id;} public String getopis() {return opis;} public void setopis (String opis) { this.opis=opis; } }

Zapytania do bazy danych 1 Rodzaje zapytań (metody obiektu EntityManager): dynamiczne w JPQL - createquery() dynamiczne natywne - createnativequery() zapewniają lepszą optymalizację nazwane (JPQL lub natywne) - createnamedquery() 2 Wykonanie zapytania (metody obiektu Query): getresultlist() - zwraca wyniki zapytania jako kolekcję typu List getsingleresult() - służy do odczytu pojedynczego wyniku zapytania w postaci obiektu Object executeupdate() - służy do wykonania polecenia UPDATE lub DELETE

Zapytanie dynamiczne EntityManager em;... List<Blad> wynik=null; Query q=em.createquery("select b FROM Blad WHERE b.opis LIKE %problem % "); wynik=q.getresultlist();

Zapytanie nazwane Plik Blad.java: @Entity @NamedQuery(nazwa="szukaj", query= "SELECT b FROM Blad b WHERE b.opis LIKE:klucz")... EntityManager em;... <List> Blad wynik=null; wynik=em.createnamequery("szukaj").setparameter( "klucz","%krytyczny%").getresultlist();