Introduction to Java. Part I

advertisement
InMoST
Wielkopolska sieć współpracy w zakresie innowacyjnych metod wytwarzania oprogramowania
Termin realizacji: 01.08.2005 – 31.07.2007
Dostęp do baz danych
przez interfejs JDBC
Bartosz Walter
Szkolenie finansowane ze środków Europejskiego Funduszu Społecznego (75%) i budżetu
państwa (25%) w ramach Zintegrowanego Programu Operacyjnego Rozwoju Regionalnego
Wprowadzenie
 JDBC (Java DataBase Connectivity) jest biblioteką
Javy (zbiorem interfejsów i klas) służącą do
wykonywania operacji na bazach danych
 JDBC z punktu widzenia aplikacji nie zależy od
wykorzystywanego systemu bazy danych, dzięki
czemu stosunkowo łatwo zmienić go na inny
 Biblioteka znajduje się w Java SDK w pakietach
java.sql.* i javax.sql.*
Odczyt informacji z bazy danych
1. Załadowanie sterownika JDBC specyficznego dla
konkretnej bazy danych (MySQL, PostgreSQL, Oracle
etc.) i zarejestrowanie go w JVM
2. Utworzenie obiektu Connection, reprezentującego
połączenie z bazą danych
3. Utworzenie obiektu Statement, reprezentującego
instrukcję do wykonania w bazie danych
4. Wykonanie instrukcji; w przypadku zapytań –
pobranie obiektu ResultSet udostępniającego wyniki
5. Przetworzenie obiektu ResultSet
6. Zamknięcie obiektów ResultSet, Statement i
Connection
Sterownik JDBC
baza
danych
komunikacja z
serwerem bazy danych
sterownik
 Sterownik JDBC jest niewielką biblioteką
umożliwiającą operacje na bazie danych specyficznej
dla sterownika
 Każdy system zarządzania bazą danych wymaga
własnego sterownika JDBC. Są one dostarczane przez
producentów systemów zarządzania bazami danych
protokół
JDBC
Aplikacja
użytkownik
Ładowanie sterownika JDBC
 Sterownik JDBC musi być widoczny dla aplikacji, tzn.
musi znajdować się na jej ścieżce klas (CLASSPATH)
 W Eclipse wystarczy dołączyć bibliotekę do projektu
 Załadowanie klasy sterownika
Class.forName("org.hsqldb.jdbcDriver");
// w przypadku braku klasy – wyjątek SQLException
DriverManager.registerDriver(
new org.hsqldb.jdbcDriver());
// w przypadku braku klasy – wyjątek ClassNotFoundEx.
Utworzenie obiektu Connection
 Obiekt Connection reprezentuje fizyczne połączenie
do bazy danych
Connection conn = DriverManager.getConnection(
"jdbc:hsqldb:hsql:@localhost",
"student", "wsb");
URL bazy danych
nazwa użytkownika i hasło
jdbc:hsqldb:hsql:@komputer.domena.pl:9001/bazadanych
protokół
adres serwera
port nazwa bazy danych
Utworzenie obiektu Statement
 Obiekt Statement reprezentuje instrukcję języka SQL,
którą możemy wykonać w danym połączeniu
 Tworzeniem obiektu Statement zajmuje się obiekt
Connection
 Obiekt Statement zajmuje się m.in.. weryfikacją
poprawności polecenia
Statement stm = conn.createStatement();
Utworzenie obiektu Statement – cd.
 W przypadku wielokrotnego wykonywania tej samej
operacji SQL z różnymi danymi można skorzystać z
obiektu PreparedStatement
 PreparedStatement w odróżnieniu od obiektu
Statement nie wykonuje za każdym razem weryfikacji
poprawności polecenia SQL, co poprawia wydajność
PreparedStatement pstm =
conn.prepareStatement("SELECT * FROM STUDENCI");
Utworzenie obiektu Statement – cd.
 Obiekt PreparedStatement może uwzględniać
niekonkretne wartości atrybutów polecenia SQL,
które będą ukonkretniane w momencie wykonywania
polecenia
 Pozwala to na efektywniejsze wykonywanie poleceń
PreparedStatement pstm =
conn.prepareStatement(
"select * from STUDENCI where ID=? and IMIE=?");
pstm.setInt(1, 100);
pstm.setString(2, 'Jan');
ResultSet rs = pstm.executeQuery();
Wykonanie polecenia SQL
 Obiekt Statement wykonuje przekazane mu polecenie
 W przypadku zapytań wynikiem wykonania polecenia
jest obiekt ResultSet, który zawiera odczytane
informacje z bazy danych
 W przypadku poleceń INSERT lub UPDATE wynikiem
jest wartość int oznaczająca liczbę zmodyfikowanych
rekordów
ResultSet rs = stm.executeQuery(
"SELECT * FROM STUDENCI");
int liczbaRekordów = stm.executeUpdate(
"INSERT INTO STUDENCI values (1, "Nowak", "Jan");
Przetwarzanie obiektu ResultSet
 Obiekt ResultSet jest obiektem, który zawiera
pierwszy rekord danych
 Odczyt kolejnych rekordów odbywa się przez
wywołanie metody next(), która określa też, czy
kolejny rekord istnieje
ResultSet rs = stm.executeQuery(
"SELECT * FROM STUDENCI");
while (rs.next()) {
// pętla trwa dopóki istnieje kolejny rekord
// przetworzenie rekordu
}
Przetwarzanie obiektu ResultSet – cd.
 Obiekt ResultSet posiada metody pozwalające
odczytywać pola bieżącego rekordu jako różne typy
(int getInt(), String getString(), Date getDate() etc.)
 Pola można adresować nazwą pola
ResultSet rs = stm.executeQuery(
"SELECT ID, IMIE, NAZWISKO FROM STUDENCI");
while (rs.next()) {
String id = rs.getInt("ID");
String imie = rs.getString("IMIE");
String nazwisko = rs.getString("NAZWISKO");
}
Przetwarzanie obiektu ResultSet – cd.
 ...lub indeksem pola w zapytaniu
ResultSet rs = stm.executeQuery(
"SELECT ID, IMIE, NAZWISKO FROM STUDENCI");
while (rs.next()) {
String id = rs.getInt(1);
String imie = rs.getString(2);
String nazwisko = rs.getString(3);
}
Zamknięcie otwartych obiektów
 Wszystkie otwarte obiekty rezerwują zasoby, dlatego
warto zamykać je po wykorzystaniu
 Wszystkie obiekty Connection, Statement i ResultSet
posiadają metodę close()
rs.close();
stm.close();
conn.close();
Cały przykład
public class StudenciDB {
public static void main(String[] args) throws SQLException {
Class.forName("org.hsqldb.jdbcDriver");
Connection conn = DriverManager("jdbc:hsqldb:hsql://localhost/",
"sa", "");
Statement stm = conn.createStatement();
ResultSet rs = stm.executeQuery(
"SELECT ID, IMIE, NAZWISKO FROM STUDENCI");
while (rs.next()) {
System.out.println("Imie: " + rs.getString(2) + ", nazwisko: " + rs.getString(3));
}
rs.close();
stm.close();
conn.close();
}
}
Transakcje
 Transakcje modyfikujące bazę danych muszą zostać
zatwierdzone lub anulowane
 Służą do tego metody commit() i rollback() w klasie
Connection
conn.commit(); // zatwierdzenie
conn.rollback(); // anulowanie
 Aby nie zapomnieć o zatwierdzeniu transakcji można
ustawić automatyczne zatwierdzanie
conn.setAutoCommit(true);
Obsługa transakcji złożonych
 Transakcje składające się z wielu poleceń SQL mogą
być wykonywane w jednym bloku
try {
conn.setAutoCommit(false);
pstm.executeUpdate(sql1);
pstm.executeUpdate(sql2);
conn.commit();
// zatwierdzenie operacji
} catch (SQLException ex) {
System.out.println("Nie udało się...");
conn.rollback(); // anulowanie operacji
} finally {
conn.close();
}
Wydajność JDBC
 Wydajność JDBC może w wielu przypadkach być
niewystarczająca.
 Aby poprawić wydajność realizacji transakcji przez
JDBC, można:
 zastosować mechanizm puli połączeń do bazy danych, dzięki
czemu połączenia nie są tworzone i zamykane, a pobierane i
zwracane do puli
 stosować obiekt PreparedStatement zamiast Statement
 wykonywać wiele operacji SQL w jednej transakcji z
wywołaniem commit() na końcu
Obsługa wyjątków
 Niemal każda operacja JDBC może spowodować
zgłoszenie wyjątku SQLException
 Nieobsłużenie wyjątku może spowodować porzucenie
otwartego połączenia do bazy danych
try {
// wykonujemy różne operacje JDBC
} catch (SQLException ex) {
System.out.println(ex);
} finally {
if (conn != null) // próba zamknięcia połączenia
try { conn.close();
} catch (SQLException ex2) {}
}
Q&A
Download