JAVA – bazy danych ! na bazie: Język Java - Podstawy Programowania - Jacek Rumiński Plan wykładu Sposoby połączenia z bazą danych Sterowniki JDBC Połączenie z bazą danych poprzez JDBC Język SQL (Structured Query Language) Praca z bazą danych poprzez JDBC Technologia JDBC (ang. Java DataBase Connectivity). " " " Interfejs niezależny od architektury bazy danych używanej podczas projektowania danego systemu Pomostem pomiędzy przestrzeniami bazy danych i aplikacji, napisanej w języku Java. Interfejs ten operuje na poziomie typowego dla baz danych języka SQL (ang. Structured Query Language) JDBC (ang. Java DataBase Connectivity - łącze do baz danych w języku Java) - 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 standardu ODBC opracowanego przez SQL Access Group. Środowisko Java Platform, Standard Edition zawiera API JDBC, natomias użytkownik musi uzyskać specjalny sterownik JDBC do swojej bazy danych. Możliwe jest łączenie się z ODBC przez specjalne sterowniki tłumaczące odwołania JDBC na komendy ODBC. ODBC (ang. Open DataBase Connectivity - otwarte łącze baz danych) - interfejs pozwalający programom łączyć się z systemami zarządzającymi bazami danych. Jest to API niezależne od języka programowania, systemu operacyjnego i bazy danych. Standard ten został opracowany przez SQL Access Group we wrześniu 1992 roku. W skład ODBC wchodzą wywołania wbudowane w aplikacje oraz sterowniki ODBC. Pierwsza implementacja ODBC pojawiła się w systemie Microsoft Windows, lecz obecnie możliwe jest korzystanie z niego na platformach Unix, OS/2 oraz Macintosh. W systemach bazodanowych typu klient-serwer (np. Oracle lub PostgreSQL) sterowniki dają dostęp do silnika baz danych, natomiast w programach dla komputerów osobistych sterowniki sięgają bezpośrednio do danych. Mechanizm ODBC współpracuje zarówno z bazami obsługującymi język SQL, jak i nieobsługującymi go - w tym ostatnim przypadku język SQL jest przekładany na oryginalny język bazy danych. Etapy pracy " " " utworzenie połączenia z bazą danych, wysłanie polecenia (poleceń) SQL, przetworzenie otrzymanych wyników. Sterownikiem JDBC, łączącym naszą aplikację z konkretną bazą danych, nazywamy zestaw klas, które implementują interfejs JDBC. Menadżer sterowników dynamicznie zarządza obiektami sterowników. Obiekty te będą wykorzystywać nasze zapytania do bazy danych. Utworzenie połączenia z bazą danych tworzenie obiektu Connection. statycznya metoda DriverManager.getConnection(). java.sql.Connection conn = null; conn=DriverManager.getConnection(baza, user, pass); ! String baza = "jdbc:mysql://olimp.if.pw.edu.pl/pojava"; String user = "pojava"; String pass = "Java"; Nazwa bazy danych – 3 człony jdbc:<subprotocol>:<subname> Typ protokołu nazwa sterownika lub mechanizmu połączenia do bazy danych msql - sterownik dla bazy mSQL, odbc -mechanizm dla sterowników typu ODBC. adres zależy od sterownika czy mechanizmu połączeń i może zawierać dodatkowe rozszerzenia zgodnie z koncepcją przyjętą przez twórcę sterownika. Standardowo omawiana część adresu wygląda następująco: ! //hostname:port/subsname getConnection(String url, String user, String password) Sterowniki - klasa DriverManager import java.sql.DriverManager; import java.sql.Connection;; ! String url = "jdbc:mysql://olimp.if.pw.edu.pl/pojava"; username = "pojava"; String password = "Java"; try { Class.forName("com.mysql.jdbc.Driver").newInstance();//ładowanie sterownika most JDBC-ODBC } catch (Exception e) {System.out.println("Blad ladowania sterownika JDBC/ODBC."); return; } Connection c = null; try {c = DriverManager.getConnection (url, username, password); //połączenie } catch (Exception e) { System.err.println("Wystapil problem z polaczeniem do "+url); } Co mamy w sterownikach? sterowniki JDBC – odwzorowanie → sterowników Open Database Connectivity – ODBC sterowniki JDBC- s. 9-5?? Wysyłanie polecenia SQL W celu wysłania polecenia SQL należy stworzyć obiekt Statement. ! Statement s = null; Connection con = null; ! con=DriverManager.getConnection(URL,username,password); s=con.createStatement(); ! Obiekt s stanowi kontener dla wykonywanych poleceń SQL. obiekt Statement Metoda: createStatement() ! executeQuery(): do SQL poleceń, których efekt daje pojedynczy zbiór rezultatów ResultSet np. wyrażenie SELECT – wybierz. ! executeUpdate(): do poleceń INSERT, UPDATE oraz DELETE, a także wyrażeń typu SQL DDL (Data Definition Language - język definicji danych): CREATE TABLE i DROP TABLE. INSERT/UPDATE/DELETE " " " Modyfikację jednej lub więcej kolumn w zero i więcej wierszach tabeli. Zwracana wartość w wyniku działania metody executeUpdate() to liczba całkowita wskazująca ilość rzędów, które podlegały modyfikacjom. W przypadku DLL → wartość 0 s = conn.createStatement(); // tworzenie obiektu Statement przesylajacego zapytania do bazy conn ResultSet r; r=s.executeQuery("Select * from meteo;"); // wykonanie kwerendy i przeslanie wynikow do obiektu ResultSet r.next(); // przejscie do kolejnego rekordu (wiersza) otrzymanych wynikow PreparedStatement Metoda: prepareStatement() ! Obiekt używany jest do wykonywania prekompilowanych (przygotowanych - prepared) poleceń SQL zawierających jedno lub więcej pól parametrów (oznaczanych znakiem "?"; tzw. parametry IN) ! ! własne metody execute(), executeUpdate() oraz executeQuery(). wyrażenia SQL musi być przygotowane wcześniej, w obiekcie PreparedStatement ps = c.prepareStatement("INSERT INTO kurs VALUES (?, ?, ?)"); ps.setString(1,"Mariusz"); ps.setString(2,"MK"); ps.setInt(1, 28); ps.executeUpdate(); CallableStatement Metoda: prepareCall() ! Obiekt jest wykorzystywany do stworzenia odwołania (call) do przechowywanych w bazie danych procedur. ! W pracy z zewnętrznymi procedurami przechowywanymi poza kodem programu. ! stworzenie wyrażenia typu CallableStatement → podanie jako parametru metody Connection.prepareCall() sekwencji ucieczki typu {call procedure_name[(?, ?)]} lub {? = call procedure_name[(?, ?)]} w przypadku gdy procedura zwraca wartość. Przykład – przygotowanie danych SQL import java.sql.*; public class DBkurs { static String[] SQL = { "CREATE TABLE kurs ("+ "uczestnik varchar (32),"+ "inicjaly varchar (3),"+ "wiek integer)", "INSERT INTO kurs VALUES ('Jarek', 'JS', 30)", "INSERT INTO kurs VALUES ('Andrzej', 'AM', 27)", "INSERT INTO kurs VALUES ('Ania', 'AM', 20)", "INSERT INTO kurs VALUES ('Marcin', 'MH', 25)", }; Java->JDBC->SQL->DBMS Sterowniki ... public static void main(String[] args) { String url = "jdbc:odbc:kurs"; String username = ""; String password = ""; try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); } catch (Exception e) { System.out.println("Blad ladowania sterownika JDBC/ODBC."); return; } Połączenie... Statement s = null; Connection c = null; try { c = DriverManager.getConnection (url, username, password); s = c.createStatement(); } catch (Exception e) { System.err.println("Wystapil problem z polaczeniem do "+url); } SQL try { for (int i=0; i<SQL.length; i++) { s.executeUpdate(SQL[i]); } c.close(); } ! catch (Exception e) { System.err.println("Wystapil problem z wyslaniem SQL do "+url+ ": "+e.getMessage()); } } Przykład 2 public class DBkurs2 { static String SQL = "CREATE TABLE kurs ("+"uczestnik varchar (32),"+ "inicjaly varchar (3),"+ "wiek integer)"; ! public static void main(String[] args) { String url = "jdbc:odbc:kurs"; String username = ""; String password = ""; String[] imie= {"Jarek","Andrzej","Ania","Marcin"}; String[] inic={"JS","AM", "AM", "MH"}; int[] lat={30,27,20,25}; Sterowniki... try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); } catch (Exception e) { System.out.println("Blad ladowania sterownika JDBC/ODBC."); return; } Łączymy Connection c = null; Statement s = null; ! PreparedStatement ps = null; try { c = DriverManager.getConnection (url,username,password); s = c.createStatement(); } catch (Exception e) { System.err.println("Wystapil problem z polaczeniem do "+url); } try { s.executeUpdate(SQL); s.close(); ps = c.prepareStatement("INSERT INTO kurs VALUES (?, ? , ?)"); for(int n=0; n<4; n++){ ps.setObject(1,imie[n]); //setObject zamiast setString z uwagi na problemy z konwersją typów danych do Text File ODBC (MS) ps.setObject(2,inic[n]); ps.setInt(3, lat[n]); ps.executeUpdate(); } ps.close(); } catch (Exception e) { System.err.println("Wystapil problem z wyslaniem SQL do "+url+ ": "+e.getMessage()); } finally{ try{ } c.close(); } catch(SQLException e) { e.printStackTrace(); } Analiza odpowiedzi executeUpdate() → zwraca liczbę zmienionych wierszy executeQuery() → obiekt typu ResultSet (wszystkie rekordy) dostęp do kolejnych danych/rekordów ResultSet.next() odczyt wartości pól za pomocą metod typu getXXX() XXX – typ danych ! ResultSet r=s.executeQuery("SELECT uczestnik, inicjaly, wiek FROM kurs"); while(r.next()){ n++; imie=r.getString(1); Identyfikator kolumny: dane inic=r.getString(2); numer lub nazwa kolumny lata=r.getInt(3); System.out.println("Dane rekordu nr: "+n+" to: "+imie+", "+inic+", "+lata); } Informacja o kolumnach obiektu Informacjea o kolumnach obiektu ResultSet dostępne są poprzez wywołanie metod interfejsu ResultSetMetaData, którego obiekt zwracany jest poprzez przywołanie metody ResultSet.getMetaData. ! Przykładowe własności kolumn to nazwa kolumnygetColumnName(), czy typ kolumny getColumnType(). Hibernate realizuje podejście mapowania obiektów na struktury danych składowanych w relacyjnych bazach danych