Spring DAO Wzorzec projektowy Data Access Object (DAO) rozdzielenie mechanizmu trwałości obiektów od reguł biznesowych Oferuje wsparcie dla interfejsu JDBC narzędzi ORM: Hibernate, JDO, ibatis SQL Maps Dlaczego kolejna warstwa nad JDBC? zarządzanie Connection, ResultSet, Statement uniwersalny wyjątek DataAccessException
Spring DAO Połączenie przez JDBC... import org.springframework.jdbc.core.jdbctemplate; import org.springframework.jdbc.datasource.drivermanagerdatasource;... DriverManagerDataSource dbbean = (DriverManagerDataSource)ctx.getBean("dbBean"); JdbcTemplate template = new JdbcTemplate(dbBean); List result = template.queryforlist("select * FROM emp"); for (Object o : result) { Map map = (Map)o; System.out.println(map.get("ENAME") + " " + map.get("job")); }
Spring DAO Konfiguracja połączenia <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans>... <bean id="databean" class="org.springframework.jdbc.datasource.drivermanagerdat asource"> <property name="driverclassname" value="oracle.jdbc.driver.oracledriver"/> <property name="url" value="jdbc:oracle:thin:@kis:1521:psoir"/> <property name="username" value="student"/> <property name="password" value= psoir"/> </bean> </beans>
Transakcje w Spring Framework Wsparcie transakcji w architekturze Spring Interfejs PlatformTransactionManager Wybór między JTA, Hibernate, JDO, JDBC Szablon TransactionTemplate Deklaratywne zarządzanie transakcjami za pomocą POJO i programowania aspektowego przy użyciu ProxyFactoryBean i TransactionInterceptor, Demarkacja transakcji przez metadane i adnotacje, Jednolity obraz dla transakcji lokalnych i globalnych
Transakcje w Spring Konfiguracja... <bean id="datasource" class="org.springframework.jndi.jndiobjectfactorybean"> <property name="jndiname" value="java:comp/env/jdbc/sid"/> </bean> <bean id="transactionmanager" class="org.springframework.transaction.jta.jtatransactionmanager "/> <bean id="empmanagerjdbcbean" class= com.spring.managerjdbc"> <property name="datasource"><ref bean="datasource"/></property> </bean>
Transakcje w Spring Konfiguracja cz.2... <bean id="empmanagerbean" class="org.springframework.transaction.interceptor.transactionproxyfactor ybean"> <property name="transactionmanager"> <ref bean="transactionmanager"/></property> <property name="target"><ref bean="empmanagerjdbcbean"/></property> <property name="transactionattributes"> <props> <prop key="load*">propagation_required,readonly</prop> <prop key="store*">propagation_required</prop> </props> </property> </bean>
Spring MVC Kontrolery i interceptory wewnątrz kontenera IoC Zalety w porównaniu ze Struts to: Bardziej elastyczna architektura Serwlety DispatcherServlet współdzielą kontekst Łatwa konfiguracja środowiska Brak zależności aplikacji od szkieletu Warstwa widoku niezwiązana z technologią
Spring MVC Zalety modelu: Separacja warstw modelu, prezentacji i kontrolera Model niezależny od Spring API lub Servlet API Obiekty modelu do obsługi formularzy Testowanie przy pomocy JUnit Integracja z warstwą pośrednią Integracja z technologiami warstwy prezentacji
Spring MVC przykład cz.2 <?xml version = '1.0' encoding = 'windows-1252'?> <web-app> <servlet> <servlet-name>empstudent</servlet-name> <servletclass>org.springframework.web.servlet.dispatcherservle t</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>empstudent</servlet-name> <url-pattern>/empstudent/*</url-pattern> </servlet-mapping> </web-app>
Spring MVC - przykład <bean name="/index" class="my.spring.empstudentcontroller"/> <bean id="dbbean" </bean> <bean class="org.springframework.web.servlet.view.internalresource ViewResolver"> <property name="prefix"><value>/web- INF/jsp/</value></property> <property name="suffix"><value>.jsp</value></property> <property name="viewclass"> <value>org.springframework.web.servlet.view.jstlview</value> </property> </bean>
Spring MVC przykład cz.3 public class EmpStudentController implements Controller { public ModelAndView handlerequest( HttpServletRequest request,httpservletresponse response) throws ServletException, IOException { ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); DriverManagerDataSource dbbean = (DriverManagerDataSource)ctx.getBean("dbBean"); JdbcTemplate template = new JdbcTemplate(dbBean); List employeesraw = template.queryforlist("select ename from emp"); List employees = new ArrayList(); for (Object o : employeesraw) employees.add(((map)o).get("ename")); ModelAndView mv = new ModelAndView("emps"); mv.addobject("employees", employees); return mv; } }
Spring MVC przykład cz.4 <%@ page contenttype="text/html;charset=windows-1252" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <html> <body> <c:foreach var="emp" items="${students}"> <c:out value="${emp}"/> <br/> </c:foreach> </body> </html>
TECHNOLOGIE ORM Object-Relational Mapping obejmuje: API do zarządzania trwałością obiektów mechanizm specyfikowania metadanych Descujących - odwzorowanie klas na relacje w bazach danych język do wykonywania zapytań Najpopularniejszą implementacją ORM jest Hibernate.
Hibernate Najpopularniejsza implementacja odwzorowania obiektowo-relacyjnego dla języka Java Relational Persistence For Idiomatic Java obsługa asocjacji, kompozycji, dziedziczenia, polimorfizmu, kolekcji Wysoka wydajność i skalowalność Wiele sposobów wydawania zapytań Wykorzystuje siłę technologii relacyjnych baz danych
Architektura Hibernate Żródło: http://www.tutorialspoint.com/hibernate/hibernate_pdf_version.htm
Konfiguracja Hibernate <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.datasource">jdbc/sample</property> <property name="dialect"> org.hibernate.dialect.oracledialect</property> <mapping resource="myhib/student.hbm.xml"/> </session-factory> </hibernate-configuration>
Student Class Są to klasy implementujące encje występujące w modelu danych aplikacji Definiowane w formie POJO Posiadające sztuczny identyfikator public class Student { private Long id; private String dname; public void setid(long id) { this.id = id; } public Long getid() { return id; } public void setdname(string dname) { this.dname = dname; } public String getdname() { return dname; } }
ORM w Hibernate Definiowane w pliku lub plikach XML typowo odrębny plik dla każdej klasy zwyczajowe rozszerzenie.hbm.xml. Zorientowane na Desc odwzorowania z punktu widzenia klasy Java, a nie tabeli Tworzone ręcznie lub generowane za pomocą narzędzi Typowo pliki odwzorowania wskazywane w pliku konfiguracyjnym hibernate.cfg.xml
ORM, przykład odwzorowania <?xml version="1.0"?> <hibernate-mapping package= kisstud"> <class name= Student" table= Student"> <id name="id" type="long" column= studno"> <generator class="sequence"> <param name="sequence">stud_seq</param> </generator> </id> <property name= studname" column= studname type="string" not-null="true /> </class> </hibernate-mapping>
Interfejsy Hibernate API SessionFactory służy do tworzenia obiektów Session obiekt tworzony raz dla całej aplikacji Session jednostka pracy ( unit of work ) obsługuje trwałość obiektów Transaction transakcja w bazie danych najczęściej jedna w sesji
Przykład 1 SessionFactory sf =New Configuration().configure().buildSessionFacto ry(); Session s = sf.opensession(); Transaction tx = s.begintransaction(); Student d = new Student(); d.setstudname( Anarkowski"); s.save(d); tx.commit(); s.close();
Stany obiektu Ulotny (ang. transient) utworzony operatorem new, ale niezwiązany z sesją Trwały (ang. persistent) posiada identyfikator i reprezentację w bazie danych związany z sesją 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 obiektów w Hibernate Uczynienie obiektu trwałym: metoda save() obiektu Session Odczyt obiektu o znanym identyfikatorze: metody load() i get() obiektu Session Usunięcie obiektu: metoda delete() obiektu Session Modyfikacja trwałego obiektu metody setxxx() obiektu Synchronizacja obiektów odłączonych metody update(), saveorupdate() i merge() obiektu Session
Przykłady obsługi obiektów Utworzenie i zachowanie obiektu Student d = new Student(); d.setstudname("anarkowski"); Long genid = (Long) session.save(d); Odczyt i modyfikacja obiektu Student d = (Student) session.load(student.class, new Long(20)); d.setstudname(" Anarkowski XYZ"); Usunięcie obiektu Student d = (Student) session.load(student.class, new Long(20)); session.delete(d);
Zapytania w Hibernate Zapytania w języku HQL (Hibernate Query Language) składnia podobna do SQL zorientowany obiektowo zapytania odwołują się do klas, a nie tabel Zapytania w natywnym SQL Zapytania poprzez obiekty Criteria Zapytania poprzez obiekty Example
Asocjacje w Hibernate 1:1, N:1, 1:N, N:M Z tabelą pośrednią (1:1, N:1, 1:N, N:M) lub bez (1:1, N:1, 1:N) Jednokierunkowe lub dwukierunkowe Istnieje możliwość kaskadowej propagacji operacji na następujące obiekty zależne: none, all, save-update, delete, all-deleteorphan
Java Persistence API Standard dotyczący zapewniania trwałości obiektów w aplikacjach Java EE i Java SE Rola Java Persistence na tle technologii ORM oparty o odwzorowanie obiektoworelacyjne definiuje standardowe API
Elementy standardu JPA Interfejs programistyczny Java Persistence API Język zapytań Java Persistence Query Language Metadane o odwzorowaniu obiektoworelacyjnym
Encje Encja (ang. entity) to lekki obiekt służący do reprezentacji trwałych danych Typowo reprezentuje tabelę z relacyjnej bazy danych Definiowana w formie klasy encji i ewentualnie klas pomocniczych Wymagania dla klas encji: POJO z adnotacją @Entity bezargumentowy konstruktor (public lub protected) implementacja Serializable, jeśli obiekty będą odłączane
Przykład klasy encji @Entity @Table(name="BLEDY") public class Blad implements Serializable { @Id private Long id; private String code; private String Desc; public Blad() { } public Long getid() { return id; } public void setid(long id) { this.id = id; } public String getcode() { return code; } public void setcode(string code) { this.code = code; } public String getdesc() { return Desc; } public void setdesc(string Desc) { this.desc = Desc; } }
Związki pomiędzy encjami Liczność 1:1 (@OneToOne) 1:N (@OneToMany) N:1 (@ManyToOne) N:M (@ManyToMany) Kierunkowość dwukierunkowe jednokierunkowe Kaskada operacji: PERSIST, MERGE, REMOVE, REFRESH, ALL
Entity Manager Zarządca encji zarządzany przez kontener (EJB, JSF) wstrzykiwany do komponentu aplikacji @PersistenceContext EntityManager em; kontekst trwałości propagowany między komponentami w ramach transakcji JTA Zarządca encji zarządzany przez aplikację (serwlety,se) tworzony i niszczony przez aplikację każdy zarządca encji tworzy odrębny kontekst trwałości @PersistenceUnit EntityManagerFactory emf; EntityManager em = emf.createentitymanager();
Persistence Unit Definiuje zbiór klas encji zarządzanych przez EntityManager w aplikacji Obejmuje klasy encji z jednej bazy danych Definiowana w pliku konfiguracyjnym persistence.xml Posiada nazwę unikalną w zasięgu widzialności W aplikacjach Java EE wykorzystuje źródło danych obsługujące transakcje JTA nieobsługujące transakcji JTA W aplikacjach Java SE zawiera parametry połączenia
Plik persistence.xml <?xml version="1.0" encoding="utf-8"?> <persistence version="1.0"...> <persistence-unit name= Testy" transactiontype="jta"> <provider>oracle.toplink.essentials.ejb.cmp3.entityman agerfactoryprovider</provider> <jta-data-source>jdbc/sample</jta-data-source> <properties> <property name="toplink.ddl-generation" value="createtables"/> </properties> </persistence-unit> </persistence>
Cykl życia encji Instancje encji są zarządzane przez instancję EntityManager Stany instancji encji: nowa (ang. new) zarządzana (ang. managed) odłączona (ang. detached) usunięta (ang. removed)
Utrwalenie instancji encji @PersistenceContext EntityManager em; Blad b = new Blad(); b.setkod("b001"); b.setopis("niedozwolona operacja w module X"); em.persist(b);
Operacje na encjach Metoda find() Metoda refresh() Metoda merge() Moment zapisu danych do bazy: automatycznie: gdy transakcja jest zatwierdzana jawnie: w wyniku wywołania metody flush() Strategia blokowania danych domyślnie blokowanie optymistyczne Metoda lock()
Rodzaje zapytań do bazy Rodzaje zapytań dynamiczne w JPQL - createquery() dynamiczne natywne - createnativequery() nazwane Parametryzacja zapytań nazwane pozycyjne Wykonanie zapytania (metody obiektu Query) getresultlist(), getsingleresult() executeupdate()
Zapytanie dynamiczne EntityManager em; List<X> zn = null; Query q = em.createquery( "SELECT x FROM X x WHERE x.opis LIKE '%cosx%'"); zn = q.getresultlist();
Zapytanie nazwane @Entity @NamedQuery(name = "findbykeyword", query = "SELECT x FROM X x WHERE x.opis LIKE :cosx") EntityManager em; List<Blad> zn = null; zn = em.createnamedquery("findbykeyword").setparameter("keyword", "%oneofx%").getresultlist();
JPQL Umożliwia formułowanie przenaszalnych zapytań, niezależnych od specyfiki poszczególnych systemów Zapytania operują na abstrakcyjnym schemacie obejmującym encje i związki między nimi Składnia podobna do SQL: zapytania SELECT-FROM-WHERE-GROUP BYHAVING-ORDER BY polecenia UPDATE i DELETE dla masowych operacji modyfikacji i usuwania: UPDATE-SET-WHERE, DELETE-FROM-WHERE Wyrażenia ścieżkowe do nawigacji do związanych encji
Przykłady JPQL SELECT DISTINCT * FROM Wykonawca w, IN(w.albumy) SELECT DISTINCT * FROM Wykonawca w JOIN w.albumy a SELECT * FROM Album a WHERE a.autor.nazwa = Kukiz
MATERIAŁY http://docs.oracle.com/javaee/6/tutorial/d oc/bnafd.html http://www.oracle.com/technetwork/java/ javaee/jsp/index.html http://www.tutorialspoint.com/spring/inde x.htm http://www.tutorialspoint.com/hibernate/h ibernate_pdf_version.htm
Dziękuję za uwagę