RBD_wjap_13

advertisement
Relacyjne Bazy Danych
wykład XIII
1
opr. Lech Banachowski, Jan Wierzbicki
JDBC - programistyczny
interfejs do bazy danych
Na tym wykładzie, dla porównania, przedstawimy
tak samo popularny jak ADO interfejs
programistyczny do bazy danych – mianowicie
JDBC. Należy on do środowiska języka
programowania Java i będzie używany na
zajęciach dotyczących Javy. Nas interesuje tutaj
przede wszystkim porównanie ADO z JDBC - jak
bardzo są do siebie podobne, co nie powinno
stanowić niespodzianki bo oba są oparte na tym
samym standardzie interfejsu poziomu wywołań
(CLI) języka SQL.
2
opr. Lech Banachowski, Jan Wierzbicki
JDBC
W związku z popularnością języka Java w dziedzinie aplikacji
bazodanowych zostały opracowane dwie wersje:
•języka SQL osadzonego w Javie o nazwie SQLJ;
•interfejsu programistycznego SQL z języka Java o nazwie
JDBC.
3
opr. Lech Banachowski, Jan Wierzbicki
Interfejs JDBC stał się popularny i jest używany między innymi
w:
•programach aplikacyjnych napisanych w Javie - po stronie
klienta;
•apletach czyli małych programach Javy realizowanych na
przeglądarce użytkownika;
•serwletach czyli programach Javy spełniających rolę małych
serwerów aplikacyjnych to jest programów realizujących przez
sieć zlecenia użytkowników;
•procedurach i funkcjach zakodowanych w Javie składowanych w
bazie danych.
4
opr. Lech Banachowski, Jan Wierzbicki
JDBC jest zbiorem klas i interfejsów w Javie, które umożliwiają
dostęp do bazy danych z programów napisanych w Javie. Klasy
te i interfejsy tworzą pakiet java.sql.
Na początku programu zamieszcza się zwykle dyrektywę
importu:
import java.sql.*;
5
opr. Lech Banachowski, Jan Wierzbicki
Do określenia sposobu łączenia się z bazą danych służy napis
połączenia URL (jdbc oznacza nazwę głównego protokołu
połączenia):
jdbc:<podprotokół>:<podnazwa>
np.
jdbc:odbc:moja_baza
jdbc:oracle:thin:@xeon.pjwstk.waw.pl:1521:ORCL
6
opr. Lech Banachowski, Jan Wierzbicki
Sterownik JDBC - zestaw klas, które implementują
interfejsy pakietu java.sql dla konkretnego systemu baz danych.
Aby połączyć się z bazą danych należy wykonać dwie instrukcje:
Krok 1: załadowanie odpowiedniego sterownika JDBC do
pamięci:
- albo za pomocą mechanizmu Javy dynamicznego ładowania
klas:
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
- albo używając statycznej metody registerDriver klasy
DriverManager:
DriverManager.registerDriver(new
sun.jdbc.odbc.JdbcOdbcDriver());
7
opr. Lech Banachowski, Jan Wierzbicki
Krok 2: użycie metody getConnection klasy DriverManager do
otwarcia połączenia z bazą danych, która zwraca referencję do
obiektu klasy Connection.
String URL = "jdbc:odbc:moja_baza"
Connection con = DriverManager.getConnection(URL,
"użytkownik", "hasło");
8
opr. Lech Banachowski, Jan Wierzbicki
Obiekty JDBC
Zasady korzystania z podstawowych obiektów klas interfejsu
JDBC są następujące:
• Sesja z bazą danych rozpoczyna się od utworzenia obiektu klasy
Connection (odpowiednik klasy Connection w ADO).
• Obiekt klasy Statement reprezentuje wykonywaną instrukcję
SQL (odpowiednik klasy Command w ADO). Podstawowe dwie
metody to:
•executeQuery - jako parametr bierze tekst zapytania SQL a
zwraca obiekt typu ResultSet – z danymi.
•executeUpdate – jako parametr bierze instrukcję SQL i zwraca
liczbę przetworzonych przez nią w bazie danych rekordów.
9
opr. Lech Banachowski, Jan Wierzbicki
•Obiekt klasy ResultSet reprezentuje zbiór rekordów zwracanych
przez zapytanie - przy czym dokładnie jeden rekord jest dostępny
w danej chwili (odpowiednik klasy RecordSet w ADO).
•Kolejne rekordy uzyskuje się stosując metodę next, która zwraca
wartość logiczną, przy czym:
•false oznacza, że doszliśmy do końca zbioru wynikowego
rekordów.
•Poszczególne wartości pól uzyskuje się stosując metody takie jak
getString i getFloat, które mając daną nazwę pola (odpowiedniego
typu) zwracają wartość tego pola w bieżącym rekordzie.
•Obiekt klasy SQLException reprezentuje błąd (wyjątek)
związany z wykonywaniem instrukcji SQL na bazie danych.
10
opr. Lech Banachowski, Jan Wierzbicki
Przykład zastosowania interfejsu JDBC do bazy danych określonej
przez połączenie ODBC o nazwie oras z logowaniem na konto
"scott" z hasłem "tiger". Zakładamy, że w bazie danych znajduje
się tabela Emp mająca kolumny: Ename typu napisowego oraz Sal
typu numerycznego.
//połącz się z bazą danych
try{Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");}
catch(ClassNotFoundException ex) {
System.out.println(ex.getMessage ());
}
try {
Connection con =
DriverManager.getConnection("jdbc:odbc:oras", "scott",
"tiger");
11
opr. Lech Banachowski, Jan Wierzbicki
//zbuduj obiekt reprezentujący instrukcję SQL i wykonaj ją
Statement stmt = con.createStatement();
String query = "SELECT Ename, Sal FROM Emp";
ResultSet rs = stmt.executeQuery(query);
//przejdź w pętli po wszystkich wierszach wynikowych
while (rs.next()) {
String s = rs.getString("Ename");
float z = rs.getFloat("Sal");
System.out.println(s + ": " + z);
}
} catch(SQLException ex) {// obsłuż wyjątki
System.out.println(ex.getMessage ()
+ ex.getSQLState () + ex.getErrorCode ());
}
}
12
opr. Lech Banachowski, Jan Wierzbicki
W przykładzie został użyty sterownik typu most między JDBC a
ODBC.
Można byłoby użyć innego sterownika, na przykład sterownika
firmy Oracle.
Wtedy przykładowo URL =
"jdbc:oracle:thin:@elektron.pjwstk.edu.pl:1521:ORCL".
Jako ćwiczenie, można sprawdzić działanie załączonego pełnego
programu w Javie - obejmującego powyższy przykład dla bazy
danych MS Access.
13
opr. Lech Banachowski, Jan Wierzbicki
Modyfikowanie danych w bazie danych
Statement stm = con.createStatement();
int liczba = stm.executeUpdate(
"UPDATE Emp SET Sal = Sal*1.1");
System.out.println(
"Podniesiono zarobki o 10%: "+ liczba+" osobom.");
stm.close();
Wywołanie stm.executeUpdate zwraca pojedynczą liczbę,
określającą liczbę wierszy tabeli, których dotyczyło zapytanie
(tzn. które zostały zaktualizowane). Metoda
stm.executeUpdate używana jest do wykonywania operacji:
INSERT, UPDATE, DELETE, a także operacji definiowania
danych takich jak: CREATE TABLE, ALTER TABLE,
DROP TABLE.
14
opr. Lech Banachowski, Jan Wierzbicki
Modyfikowanie danych w bazie danych przy użyciu obiektu ResultSet
Statement stm =
con.createStatement(ResultSet.TYPE_SCROLL_SENSITIV
E, ResultSet.CONCUR_UPDATABLE)
String sql = "SELECT * FROM Emp";
ResultSet rs = stm.executeQuery(sql);
rs.first();
rs.updateString("Ename","Kowalski");
rs.updateFloat("Sal",10000);
rs.updateRow();
Należy zdawać sobie sprawę, że nie każdy system obsługuje
modyfikowalne obiekty ResultSet (podobnie jest dla obiektów
RecordSet w ADO).
15
opr. Lech Banachowski, Jan Wierzbicki
Usunięcie bieżącego rekordu
rs.deleteRow();
Dodanie nowego rekordu
rs.moveToInsertRow();
rs.updateString("Ename","Kowalski");
rs.updateFloat("Sal", 10000);
rs.insertRow();
16
opr. Lech Banachowski, Jan Wierzbicki
Obsługa transakcji
Domyślnie w JDBC każda instrukcja SQL kończy się
automatycznym zatwierdzeniem (auto-commit). Poniżej
zmieniamy to domyślne ustawienie. Gdy wykonywanie
wszystkich instrukcji SQL kończy się pomyślnie, explicite
wykonujemy zatwierdzanie przy pomocy metody commit
obiektu Connection. Gdy w trakcie wykonywania instrukcji SQL
powstanie błąd, wykonujemy wycofanie transakcji przy pomocy
metody rollback obiektu Connection.
17
opr. Lech Banachowski, Jan Wierzbicki
try {
con.setAutoCommit(false);
Statement stm=con.createStatement();
stm.executeUpdate(" .....");
stm.executeUpdate(" .....");
.....
con.commit();
}
catch(Exception e){
con.rollback();
}
18
opr. Lech Banachowski, Jan Wierzbicki
Obsługa NULL - funkcja wasNull()
float Sal = rs.getFloat("Sal");
if (rs.wasNull(){
Sal = 0;
}
19
opr. Lech Banachowski, Jan Wierzbicki
Przygotowanie instrukcji - PreparedStatement
Gdy wielokrotnie wykonuje się tę samą instrukcję, warto ją
wcześniej raz przygotować dokonując analizy składniowej, a
potem wykonywać wielokrotnie. Co więcej, taka instrukcja
może mieć parametry zmieniane przy każdym wywołaniu. W
miejsce klasy Statement korzystamy w tym przypadku z klasy
PreparedStatement. Parametry formalne są w treści
instrukcji oznaczone przez znaki zapytania:
PreparedStatement stmt =
con.prepareStatement("UPDATE Emp SET Deptno = ?
WHERE Deptno = ?");
20
opr. Lech Banachowski, Jan Wierzbicki
Następujące metody służą do nadania wartości parametrom:
setInt(), setString(), setDate() etc. Każda z nich ma dwa
argumenty: numer parametru i jego wartość. Po przygotowaniu
można wielokrotnie nadawać różne wartości temu samemu
parametrowi. Oto przykładowy fragment kodu, który przenosi
wszystkich pracowników z działu numer 10 do działu nr 50.
PreparedStatement stmt = con.prepareStatement(
"UPDATE Emp SET Deptno = ? WHERE Deptno = ?");
stmt.setInt(1, 50);
stmt.setInt(2, 10);
System.out.println(stmt.executeUpdate()+" przeniesionych");
stmt.close();
21
opr. Lech Banachowski, Jan Wierzbicki
Podsumowanie
Na dwóch ostatnich wykładach czytelnik zaznajomił się z
programistycznym interfejsem poziomu wywołań czyli ze sposobem
wykonywania w programie konwencjonalnego języka
programowania instrukcji SQL na bazie danych. Sposób ten polega
na zainicjowaniu połączenia z bazą danych przy pomocy obiektu
klasy Connection. Następnie korzystając z odpowiednich metod
albo samego obiektu klasy Connection albo obiektu
reprezentującego instrukcję SQL czyli obiektu klasy Command
w VBA i Statement w Javie następuje wykonanie instrukcji
SQL. W przypadku wykonywania instrukcji SELECT otrzymywane
z bazy danych wiersze są zapisywane i przetwarzane przy pomocy
metod obiektu RecordSet w VBA i ResultSet w Javie.
22
opr. Lech Banachowski, Jan Wierzbicki
JDBC - zbiór klas i interfejsów w Javie, które umożliwiają dostęp
do bazy danych z programów napisanych w Javie. Klasy te i
interfejsy tworzą pakiet java.sql.*
sterownik JDBC - zestaw klas, które implementują interfejsy
pakietu java.sql dla konkretnej bazy danych.
Connection - klasa, której obiekty reprezentują połączenie z bazą
danych w celu wykonania ciągu instrukcji SQL.
Statement - klasa, której obiekty reprezentują instukcję SQL.
23
opr. Lech Banachowski, Jan Wierzbicki
ResultSet - klasa, której obiekty reprezentują zbiór rekordów
zwracanych przez zapytanie – przy czym jeden rekord jest
dostępny w danej chwili.
przygotowanie instrukcji - gdy wielokrotnie wykonuje się tę samą
instrukcję, warto ją wcześniej raz przygotować (zanalizować
składniowo), a potem wykonywać wielokrotnie. Co więcej, taka
instrukcja może mieć parametry zmieniane przy każdym
wywołaniu.
24
opr. Lech Banachowski, Jan Wierzbicki
Koniec Wykładu XIII
25
opr. Lech Banachowski, Jan Wierzbicki
Download