Zadania
Transkrypt
Zadania
Platformy programowania Lab 12. JavaEE (JFS) & Hibernate Java EE - Java Platform, Enterprise Edition (zwana również jako Java Enterprise, J2EE oraz Java EE czasami tłumaczona jako Java Korporacyjna) jest szeroko rozpowszechnioną serwerową platformą programistyczną języka Java. Definiuje standard tworzenia aplikacji w języku programowania Java opartych o wielowarstwową architekturę komponentową. Komponenty są zwykle osadzane na serwerze aplikacyjnym obsługującym Java Enterprise. Standard ten określa zestaw interfejsów programistycznych jakich musi dostarczać zgodny serwer aplikacyjny. Standard Java Enterprise aktualnie tworzony jest przez Oracle, które wykupiło oryginalnego twórcę - Sun Microsystems. Firma ta dostarcza poza definicją interfejsów programistycznych, wzorcową implementację serwera aplikacyjnego (otwarta wersja: GlassFish). JavaServer Faces (JSF) to bazujący na języku Java framework, który upraszcza tworzenie interfejsu użytkownika do aplikacji Java EE. Obecnie domyślną technologią widoku dla stron JSF jest technologia Facelets, jednak można korzystać także z innych rozwiązań (np. JSP lub XUL). Hibernate - framework do realizacji warstwy dostępu do danych (ang. persistance layer). Zapewnia on przede wszystkim translację danych pomiędzy relacyjną bazą danych, a światem obiektowym (ang. O/R mapping). Opiera się na wykorzystaniu opisu struktury danych za pomocą języka XML, dzięki czemu można "rzutować" obiekty, stosowane w obiektowych językach programowania, takich jak Java bezpośrednio na istniejące tabele bazy danych. Dodatkowo Hibernate zwiększa wydajność operacji na bazie danych dzięki buforowaniu i minimalizacji liczby przesyłanych zapytań. Jest to projekt rozwijany jako open source. Wymagania: 1. NetBeans: Sprawdź wersję zintegrowanego środowiska programistycznego (IDE) NetBeans dostępnego na Twoim stanowisku. Jeśli nie jest to wersja 7.2.1 pobierz ze strony producenta (wybierz wersję z JavaEE). http://netbeans.org/downloads/index.html Zadania: 1. Korzystająx ze środowiska NetBeans utwórz nowy projekt typy Java Web -> Web Application. Korzystając z kreatora wybierz jako serwer dostępną wersję serwera GlassFish, a z dostępnych frameworków wybierz JavaServer Faces (PrimeFaces) oraz Hibernate. 2. Uruchom tak przygotowany projekt i przejdź do strony powitalnej Primefaces. 3. Korzystając z zakładki Services rozwiń gałąź Databases->jdbs:derby->APP. Sprawdź jakie dostępne tabele przygotowane zostały w przykładowej bazie, oraz korzystając z wbudowanego edytora zapytań wylistuj wszystkich konsumentów z Nowego Jorku. 4. Wróć do zakładki Projects. W ramach projektu podejrzyj plik konfiguracyjny hibernate.cfg.xml – zwróć uwagę, że połączeniu odwołuje się do lokalnej, testowej bazy danych Derby. Dodaj do niego deskrypcję: <property name="hbm2ddl.auto">update</property> która określa, że schemat bazodanowy będzie aktualizowany każdorazowo podczas uruchomienia aplikacji. 5. Do utworzonego projektu dodaj plik standardowej klasy (New->Java Class), którą to klasę nazwij Produkt, a pakiet do którego będzie należała katalog. Dodatkowo do klasy tej dodaj trzy prywatne pola: public class Produkt { private Long id; private String nazwa; private double cena; } Do pól dodaj metody set/get korzystając z kreatora (menu kontekstowe dostępne pod prawym przyciskiem myszy, Refactor->Encapsulate fields) 6. Do projektu dodaj plik mapujący obiekty utworzonej klasy na odpowiednią tabelę w przykładowej bazie. W tym celu skorzystaj z kreatora New -> Hibernate (Category) -> Hibernate Mapping Wizard (File Type). Jako klasę do zamapowania wybierz Produkt z pakietu katalog, pole na uzupełnienie tabeli z bazy danych pozostaw puste. Zamień zawartość pliku mapującego następującą treścią: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="katalog"> <class name="Produkt" table="PRODUKTY"> <id name="id" type="long" column="produkt_id"> <generator class="native" /> </id> <property name="nazwa" type="string" not-null="true" /> DTD 3.0//EN" <property name="cena" type="double" not-null="true" /> </class> </hibernate-mapping> 7. W ramach projektu dodaj klasę pomocniczą HibernateUtil udostępniającą obiekt SesssionFactory: package katalog; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static final SessionFactory sessionFactory; static { try { sessionFactory = new Configuration().configure().buildSessionFactory(); } catch (Throwable ex) { System.err.println("Utworzenie SessionFactory nieudane: " + ex); throw new ExceptionInInitializerError(ex); } } public static SessionFactory getSessionFactory() { return sessionFactory; } } 8. Dodaj klasę komponentu backing bean (New->JSF Managed Bean) i nadaj jej nazwę Katalog, dodatkowo w kreatorze zaznacz zakres widzialności jako sesyjny (Scope: session). Dodaj w niej dwa pola do zapamiętania wartości wprowadzonych do pól formularza: private String nazwa; private double cena; Korzystając z kreatora dodaj metody set/get dla obu pól. Do klasy tej dodaj również metodę służącą do wstawiania do tabeli bazy danych nowego produktu: public void addProdukt(String n, double c) { //SessionFactory sf = HibernateUtil.getSessionFactory(); Session s = HibernateUtil.getSessionFactory().openSession(); try { Transaction tx = s.beginTransaction(); Produkt p = new Produkt(); p.setNazwa(n); p.setCena(c); s.save(p); tx.commit(); } finally { s.close(); } } Korzystając z podpowiedzi (Alt+Enter) dodaj brakujące referencje: import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; Dodaj do klasy Katalog metodę wskazaną na stronie JSF jako metodę obsługi zdarzenia naciśnięcia przycisku (dodaj): public String dodaj() { addProdukt(nazwa, cena); nazwa = null; cena = 0.0; return null; } Działanie metody rozpoczyna się od wstawienia do bazy danych produktu o nazwie i cenie wprowadzonych przez użytkownika w formularzu i zapamiętanych we właściwościach komponentu. Następnie zawartość tych właściwości jest resetowana, aby przy ponownym wyświetleniu strony formularz był pusty. Na koniec, metoda zwraca null, co spowoduje ponowne wyświetlenie tej samej strony. Jako ostatnią dodaj metodę pobierającą dostępne produkty z bazy: public List<Produkt> getProdukty() { SessionFactory sf = HibernateUtil.getSessionFactory(); Session s = sf.openSession(); List<Produkt> pp = (List<Produkt>)s.createQuery("from Produkt").list(); s.close(); return pp; } 9. Logika aplikacji została już wstępnie przygotowana. W następnym kroku dodaj nowy plik strony JSF (New JSF Page) i nadaj jej nazwę katalog. Podmień jej treść na następującą: <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui" xmlns:f="http://java.sun.com/jsf/core"> <h:head><title>Welcome to JSF_PrimeFaces_Hibernate Project</title></h:head> <body> <h:form> <table> <tr> <td><h:outputLabel for="name" value="Nazwa:" /></td> <td><p:inputText id="name" value="#{katalog.nazwa}"/></td> </tr> <tr> <td><h:outputLabel for="cena" value="Cena:" /></td> <td><p:inputText id="surname" value="#{katalog.cena}"/> </td> </tr> <tr> <td><p:commandButton id="dodaj" value="Dodaj" action="#{katalog.dodaj}" ajax="false"/></td> </tr> </table> <!-<h:dataTable value="# {katalog.produkty}" var="prod" border="1"> <h:column> <f:facet name="header"> <h:outputText value="Nazwa"/> </f:facet> <h:outputText value="#{prod.nazwa}"/> </h:column> <h:column> <f:facet name="header"> <f:verbatim>Cena</f:verbatim> </f:facet> <h:outputText value="# {prod.cena}"/> </h:column> </h:dataTable> --> </h:form> </body> </html> 10. Zmodyfikuj plik web.xml tak by jako domyśla wyświetlała się strona katalog.xhtml i uruchom projekt. Dodaj przynajmniej dwa nowe produkty i sprawdź w bazie czy zarówno tabela PRODUKTY jak i nowo dodane wpisy zostały poprawnie dodane. 11. Odkomentuj fragment kodu przysłonięty w pliku katalog.html, a także spacje w EL (Expression Language – po znaku #) oraz uruchom ponownie aplikację. Dodaj kolejnych kilka produktów. 12. Uzupełnij odpowiednie pliki o kod EL dodający nową kolumnę w której znajdował będzie się link usuwający dany produkt: <h:column> <f:facet name="header"> <f:verbatim></f:verbatim> </f:facet> <h:commandLink action="#{katalog.usun}"> <h:outputText value="Usuń" /> <f:param name="pid" value="#{prod.id}" /> </h:commandLink> </h:column> Zagnieżdżony w elemencie <h:commandLink> element <f:param> spowoduje przekazanie w żądaniu wygenerowanym przez kliknięcie linku identyfikator produktu do usunięcia. W takim wypadku dodać należy jeszcze logikę działania czyli metodę usun w klasie katalog. public void deleteProdukt(Long pid) { Session s = HibernateUtil.getSessionFactory().openSession(); try { Transaction tx = s.beginTransaction(); Produkt p = (Produkt) s.get(Produkt.class, pid); s.delete(p); tx.commit(); } finally { s.close(); } } public String usun() { FacesContext context = FacesContext.getCurrentInstance(); String spid = context.getExternalContext().getRequestParameterMap().get("pid"); Long pid = Long.parseLong(spid); deleteProdukt(pid); return null; } Metoda najpierw odczytuje poprzez FacesContext identyfikator produktu do usunięcia przekazany jako parametr w żądaniu, a następnie wywołuje metodę pomocniczą usuwającą produkt z bazy danych. Metoda zwraca null, tak aby po obsłużeniu zdarzenia ponownie została zaprezentowana ta sama strona aplikacji. 13. Dodaj nową podstronę, na której wyświetlisz pełną zawartość tabeli PRODUCT z testowej bazy danych korzystając z kontrolki DataTable (Simple Data Table lub Sorting) http://www.primefaces.org/showcase-labs/ui/datatableBasic.jsf