person (person_id, person_name, birth_date, gender, mother_id, father_id, address_id) osoby z określeniem pokrewieństwa
marriage (husband_id, wife_id, wedding_date) informacje o małżeństwach 3 Diagram E-R przykładowej bazy 1 * CITY ADDRESS 1 * PERSON 4 Diagram przykładowej bazy 1 1 PERSON PERSON (mother) (father) 1 1 MARRIAGE 0..1 0..1 * * PERSON 5 Cechy przykładowej bazy
Klucze sztuczne typu INTEGER, nadawane na podstawie sekwencji lub inaczej numerowane automatycznie najwygodniejsze do stosowania z Hibernate (warto je stosować nawet gdy podczas normalizacji wyłania się klucz złożony)
Tabela marriage ma celowo wprowadzony klucz złożony w celu ilustracji jego obsługi w Hibernate 6 Cechy typowej relacyjnej bazy danych
Dane umieszczone w wielu znormalizowanych tabelach (3NF)
Poszczególne kolumny zawierają dane o wartościach atomowych (INTEGER, TEXT, DATE itp.)
Powiązania za pomocą kluczy
Dodatkowe więzy integralności, triggery 7 Co dają relacyjne bazy danych
Świetnie opracowana teoria i metody projektowania
Dużo gotowych silników , od systemów wbudowanych do dużych klastrów serwerów
Znormalizowany, bogaty język SQL
Wydajność, indeksy, wieloużytkownikowość
Więzy integralności, triggery, transakcje
Procedury składowane
Gotowe narzędzia do administracji, wykonywania 8 kopii bezpieczeństwa itp. Co dają transakcje
Atomicity efekt transakcji jest zapisywany w bazie danych w całości, albo cała transakcja jest wycofywana
Consistency po zakończeniu transakcji baza pozostaje zawsze spójna
Isolation efekt transakcji jest widziany przez innych użytkowników dopiero po jej zatwierdzeniu
Durability baza danych gwarantuje że efektu zatwierdzonej transakcji nie da się już podważyć/wycofać 9 Dostęp do bazy przez JDBC
Rozwiązanie najprostsze, działa z podstawową wersją Java Standard Edition
Wyganania: kompilator Javy, oraz sterownik , np. postgresql-8.3-603.jdbc3.jar
Uruchamianie programu: java -Djdbc.drivers=org.postgresql.Driver -classpath postgresql-8.3-603.jdbc3.jar ... 10 Dostęp do bazy przez JDBC (nawiązanie połączenia) import java.sql.*; import java.util.Properties; Properties p = new Properties(); p.setProperty( user , użytkownik ); p.setProperty( password , hasło ); try { Connection dbConn = DriverManager.getConnection( jdbc:postgresql://komputer/baza , p) } catch (SQLException e) { // Połączenie nie udało się... } 11 Dostęp do bazy przez JDBC (proste zapytania) try { dbConn.begin(); Statement s = dbConn.createStatement(); ResultSet r = s.executeQuery( SELECT person_name FROM person ); while(r.next()) { System.out.println( r.getString( person_name )); } dbConn.commit(); } catch (SQLException e) { dbConn.rollback(); } dbConn.close(); 12 Klasy Statement i ResultSet
Statement zapytanie SQL (wymaga SQL w dialekcie odpowiedniej bazy)
executeQuery( SELECT ... ) zapytanie zwracające wynik
executeUpdate( INSERT INTO ... ) polecenie DML
ResultSet wynik zapytania SELECT
next() - przechodzi do następnego wiersza, zwraca true, gdy OK
getXXX(int), getXXX(String) zwraca wynik z bieżącego wiersza, z kolumny o danym numerze lub 13 nazwie (XXX = Int, Double, String, Date, Time itp.) Prepared Statements
Pozwalają na przygotowanie polecenia SQL i wielokrotne uruchamianie go dla różnych parametrów (szybsze gdy obsługiwane specjalnie przez serwer bazodanowy, np. PostgreSQL)
Funkcje setXXX(nr, wartość) ustawianie wartości parametrów
Uniknięcie ataków typu SQL Injection - sterownik dba o odpowiednie escape'owanie i konwersję parametrów 14 Prepared Statements PreparedStatement s = dbConn.prepareStatement( SELECT * FROM person WHERE person_name = ? ); s.setString(1, Jan ); ResultSet r = s.executeQuery(); s.setString(1, Elżbieta ); r = s.executeQuery(); // Poniższe polecenie zadziała bezpiecznie s.setString(1, '; DELETE FROM person; SELECT ' ); r = s.executeQuery(); 15 Savepoints
Służą do realizacji eleganckiej obsługi błędów
W przypadku problemu wycofanie transakcji następuje do określonego punktu, nie trzeba wycofywać całej transakcji Savepoint sp = dbConn.setSavepoint(); try { // Operacje na bazie danych } catch (Exception e) { dbConn.rollback(sp); throw e; } finally { dbConn.releaseSavepoint(sp); } 16 Plain Old Java Objects class Person { private int id; private String personName; private Date birthDate; private char gender; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getPersonName() { return personName; } public void setPersonName(String personName) { this.personName = personName; } } 17 Plain Old Java Objects
Często wykorzystywany model budowy klasy, zgodny ze standardem Java Beans (nadaje się do automatycznej obsługi za pomocą pakietu java.beans)
Poszczególne zmienne (id, personName itp.) prywatne, dostępne jedynie dla funkcji klasy
Dostęp do zmennych za pomocą pary getter/setter (getNazwaZmiennej/setNazwaZmiennej)
Dla zmiennych typu boolean można stosować isNazwaZmiennej zamiast getNazwaZmiennej 18 Aączenie JDBC i obiektowości
Konieczność przepisania danych z ResultSet do obiektu ResultSet r = s.executeQuery(); r.next(); Person p = new Person(); p.setId(r.getInteger( person_id )); p.setPersonName(r.getString( person_name )); p.setBirthDate(r.getDate( birth_date )); p.setGenre(r.getChar( genre )); //... 19 Aączenie JDBC i obiektowości
Modyfikacja obiektu konieczność sprawdzenia, czy obiekt się zmienił i wykonania odpowiedniego polecenia UPDATE (np. dodatkowa flaga informująca czy w obiekcie nastąpiły zmiany)
Nowy obiekt, usunięcie obiektu konieczność wygenerowania odpowiednich poleceń INSERT lub UPDATE
Problem ustalenia kolejności zapisywania danych do bazy, gdy kilka obiektów zależy od siebie nawzajem 20 JDBC podsumowanie
Mechanizm szybki i prosty w użyciu
Dużo ciekawych możlwiości (savepoints, prepared statements itp.)
Problemy gdy wyniki zapytań mają być przepisane do obiektu, oraz zmiany w obiekcie mają być naniesione w bazie danych itp.
Problemy gdy w bazie danych ma być zapisanych wiele powiązanych ze sobą obiektów 21 Object-Relational Mapping
Automatyczna wypełnienie obiektów Java na podstawie wyniku zapytania SQL
Przetworzenie zmian w obiekcie do odpowiednich poleceń INSERT/UPDATE/DELETE
Rozwiązywanie problemów związanych z zapisem i odczytem powiązanych obiektów 22 Hibernate
ORM
Możliwość zapisu zapytań w języku HQL (Hibernate Query Language) i Criteria Query automatyczna translacja na odpowiedni dialekt SQL
Cache dla obiektów i zapytań
Kontrola transakcji i reakcja na błędy
Dużo dodatkowych możliwości i narzędzi 23 Hibernate podstawowe klasy
SessionFactory zarządza konfiguracją, tworzy sesje
27 Mapowanie bazy danych type= string column= person_name not-null= true unique= false /> type= date column= birth_date not-null= true unique= false />
28 Zwyczajowe rozmieszczenie plików | |-- hibernate.cfg.xml |-- pakiet1 | |-- Klasa1.java | |-- Klasa1.hbm.xml | |-- Klasa2.java | |-- Klasa2.hbm.xml |-- pakiet2 29 Podstawowy program SessionFactory sf = new Configuration().configure() .buildSessionFactory(); Session s = sf.getCurrentSession(); Transaction t = s.getTransaction(); t.beginTransaction(); // Operacje na obiektach t.commit(); 30 Podstawowe operacje na obiektach Person p1 = (Person) s.getObject( Person.class, 1); s.lock(p1, LockMode.UPDATE); p1.setPersonName( Antoni ); Person p2 = new Person(); p2.setPersonName( Zdzisław ); s.save(p2); s.flush(); s.evict(p1); 31 Operacje na obiektach
Klasa Session:
get(klasa, identyfikator) zwraca obiekt lub null
save(obiekt) zapisuje obiekt w bazie
delete(obiekt) usuwa obiekt z bazy
lock(obiekt, tryb) blokuje obiekt w bazie
Wykonanie save() powoduje nadanie obiektowi identyfikatora bazodanowego (np. na podstawie sekwencji) 32 Zapytania HQL
Język HQL pozwala na uniezależnienie się od dialektu SQL: Query q = s.createQuery( from Person where personName = :name ) q.setString( name , Antoni ); q.setCacheable(true); for (Person p : (List) q.list()) { System.out.println(p.getBirthdayDate()); } 33 Klasa Query
Funkcje setXXX(), podobnie jak PreparedStatement z JDBC
Można stosować :nazwa do oznaczania parametrów zapytań
Funkcje:
list() - zwraca wynik w postaci listy obiektów
iterate() - zwraca iterator po wynikach (oszczędza pamięć)
uniqueResult() - gdy wiemy, że wynik będzie dokładnie jeden 34 Składnia HQL
from pakiet.klasa nie ma wyliczenia kolumn (SELECT), bo i tak wszystkie są odczytywane, chyba że ograniczamy listę kolumn
Typowe operatory języka SQL (AND, OR, NOT, =, <, >, LIKE itp.)
Możliwość stosowania złączeń (inner/outer join)
Możliwość agregacji i grupowania
Elementy języka Java (stałe, klasy)
Dodatkowe funkcje: empty(), size(), maxelement() 35 Ciąg dalszy nastąpi...
Uzupełnieniem prezentacji jest kod programów, które były pokazywane na żywo podczas wykładu
Temat jest dopiero napoczęty ciąg dalszy bez wątpienia nastąpi 36