Moduł 01
Transkrypt
Moduł 01
Metody dostępu do danych dr inż. Grzegorz Michalski Na podstawie wykładów dra inż. Juliusza Mikody Metody dostępu do danych JDBC - Java Database Connectivity JDO - Java Data Object ORM - Object-Relational Mapping Hibernate - object-relational mapping for Java JDBC Java DataBase Connectivity Interfejs programowania opracowany w 1996 r. przez Sun Microsystems Umożliwiający niezależnym od platformy aplikacjom napisanym w języku Java porozumiewać się z bazami danych za pomocą języka SQL Interfejs ten jest odpowiednikiem zaprojektowanego przez Microsoft łącza ODBC JDBC umożliwia Nawiązanie połączenia ze źródłem danych jakim jest baza danych Producenci baz danych udostępniają sterowniki umożliwiające połączenie bazy danych z aplikacją Przetwarzanie zapytań wybierających i zmieniających Pobiera i przetwarza wyniki zwrócone przez bazę danych Architektura dostępu do danych Model dwuwarstwowy – umożliwia połączenie aplikacji / apletu ze źródłem danych. Dane wędrują pomiędzy serwerem bazy danych, a aplikacją klienta. Model trójwarstwowy - W modelu trójstopniowym, polecenia są wysyłane do warstwy pośredniej, która następnie wysyła polecenia do źródła danych. Źródło danych przetwarza polecenia i wysyła wyniki z powrotem do warstwy pośredniej, która następnie wysyła je do użytkownika. Model trójwarstwowy jest popularny, ponieważ warstwa środkowa pozwala zachować kontrolę nad dostępem i rodzajem aktualizacji, które mogą być wprowadzone. JDBC - inicjacja Załadowanie sterownika dla dedykowanej bazy danych Oracle Class.forName("oracle.jdbc.driver.OracleDriver" ) SQLite Class.forName("org.sqlite.JDBC"); Mysql Class.forName("com.mysql.jdbc.Driver"); ODBC Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Nawiązanie połączenia z BD Po załadowaniu sterownika odpowiedniej bazy danych dalszą obsługą połączenia z bazą zajmuje się klasa DriverManager. Do nawiązania połączenia służy statyczna metoda: static Connection getConnection(String url) static Connection getConnection(String static Connection getConnection ( String String password) url, Properties info) url, String user, URL nawiązanie połączenia URL to adres usługi, którą chcemy wykorzystać. Adres usługi to: jdbc:subprotocol:subname jdbc – to nazwa protokołu jakim będzie się posługiwał sterownik subprotocol – szczegółowe ustawienia protokołu – typ sterownika bazy danych (np: mysql, odbc, oracle) subname – nazwa źródła danych URL - przykłady "jdbc:sqlite:test.db" – połączenie z plikową bazą danych SQLite zapisaną w pliku test.db "jdbc:oracle:thin:@oracle2.icis.pcz.pl:15 21:ICIS" – połączenie z bazą Oracle "jdbc:odbc:Fred" – połączenie ze źródłem danych odbc o nazwie Fred "jdbc:mysql://localhost/feedback" połączenie do bazy MySql na lokalnym komputerze z bazą danych o nazwie feedback Nawiązanie połączenia z BD try { Class.forName("oracle.jdbc.driver.OracleDriver"); } catch (ClassNotFoundException e) {} Connection connection = null; try { String serverName = "oracle2.icis.pcz.pl"; String portNumber = "1521"; String sid = "ICIS"; String url = "jdbc:oracle:thin:@" + serverName + ":" + portNumber + ":" + sid; String username = "******"; String password = "******"; connection = DriverManager. getConnection(url, username, password); if (connection != null) System.out.println("OK"); } catch (SQLException e) {} // operacje na bazie danych connection.close(); Operowanie na danych getConnection DriverManager createStatement Connection Statement executeQuery ResultSet executeUpdate int Wykonanie zapytań Aby wykonać zapytanie na otwartej bazie przekazujemy łańcuch z zapytaniem SQL do metody: boolean execute(String sql) Wynikiem zapytania będzie prawda – zapytanie zwracające wynik typu tabela, fałsz – brak wyniku lub wynik w postaci liczby zmienionych wierszy. Wyjątek SQLException jeśli wystąpi błąd w zapytaniu. Odczyt poprawnego wyniku: ResultSet getResultSet() int getUpdateCount() Wykonanie zapytań zmieniających Zapytania zmieniające typu UPDATE, INSERT, DELETE, DROP TABLE, CREATE TABLE wykonywane są za pośrednictwem metody: int executeUpdate(String sql) klasy Statement. Wynikiem zapytania będzie liczba zmienionych wierszy. Wywołanie wyjątku SQLException następuje w momencie gdy wystąpi błąd zapytania, połączenie z bazą jest zamknięte lub wynikiem zapytania będzie ResultSet. Wykonanie zapytań wybierających Do wykonywania zapytań wybierających (SELECT * FROM) przeznaczona jest metoda: ResultSet executeQuery(String sql) Wynikiem wywołania metody jest ResultSet – obiekt zawierający dane, które są wynikiem wykonania zapytania. Błędne wykonanie zapytania spowoduje wywołanie wyjątku SQLException. Zapytanie nie zwróci wartości null !!! Klasa ResultSet Klasa służy do przechowywania wyniku zapytania wykonanego na powiązanej bazie danych. Klasa przechowuje kursor wskazujący na aktualny wiersz tabeli. Klasa posiada metody pozwalające odczytać wartości na poszczególnych kolumnach za pomocą nazwy lub indeksu kolumny (indeks rozpoczyna się od wartości 1). W wersji JDBC 2.0 wprowadzono możliwość wstawiania wierszy oraz modyfikacji wartości przechowywanych w kolumnach i zapisie tych wartości w bazie danych. ResultSet – odczyt wartości Wybrane metody odczytu wartości w komórkach wiersza boolean getBoolean(int columnIndex) int getInt(int columnIndex) Date getDate(int columnIndex) RowId getRowId(int columnIndex) getByte, getBytes, getClob, getDouble, getFloat, getLong, getString, getTime, getTimestamp Dla wartości NULL zwracane jest 0 lub adres pusty null ResultSet - zarządzenie boolean first() - pierwszy boolean next() - nastepny boolean previous() - poprzedni boolean last() -ostatni boolean relative(int rows) – przesuń się o .. boolean absolute(int row) – przesuń się do ... ResultSet - pozycja boolean isAfterLast() - za ostatnim boolean isBeforeFirst() - przed pierwszym boolean isClosed() - zamknięty kursor boolean isFirst() - pierwszy boolean isLast() - ostatni int getRow() - zwraca numer aktualnej krotki wyniku ResultSet – modyfikacja wartości void updateString(int columnIndex, String x) zmiana zawartości aktualnego wiersza (updateBoolean, updateInt, ...) void updateRow() - zapamiętanie zmian void moveToInsertRow() - rozpoczęcie wprowadzania nowego wiersza void insertRow() - wprowadzanie wiersza do bazy void deleteRow() - usuwanie wiersza z bazy void moveToCurrentRow() - pozycja po modyfikacji Przykład Statement stmt = null; try { stmt = connection.createStatement(); try { stmt.executeUpdate("create table people (name VARCHAR(20), occupation VARCHAR(20))"); } catch (SQLException e) {} stmt.executeUpdate("insert into people values ('Gandhi', 'politics')"); stmt.executeUpdate("insert into people values ('Turing', 'computers')"); stmt.executeUpdate("insert into people values ('Wittgenstein', 'smartypants')"); Przykład ResultSet rs = stmt.executeQuery( "select * from people"); while (rs.next()) { long row = rs.getRow(); String name = rs.getString(1); String occupation = rs.getString(2); System.out.println("Wiersz " + row + " = " + name + " " + occupation); } rs.close(); try { stmt.executeUpdate("drop table people"); } catch (SQLException e) {} Przykład } catch (SQLException e) { e.printStackTrace(); } try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); }