background image

1

Obsługa baz danych przy 

uŜyciu JDBC

Beata Pańczyk - Java (Wykład 11)

2

ODBC

• ODBC (Open DataBase Connectivity - otwarte 

łącze baz danych) - interfejs programowania baz 
danych opracowany w firmie Microsoft, który 
pozwala wszystkim aplikacjom Windows 
korzystającym z baz danych za pośrednictwem sieci 
posługiwać się tym samym zbiorem wywołań

• W skład ODBC wchodzą wywołania wbudowane 

w aplikacje oraz sterowniki ODBC 

3

JDBC

• JDBC (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 zaprojektowanego 

przez Microsoft łącza ODBC 

4

Programowanie bazodanowe 

w Javie

• aplikacje bazodanowe  programowane w tradycyjnych 

językach - zaleŜne od architektury konkretnej bazy danych

• w Javie - niezaleŜność dzięki wprowadzeniu interfejsu 

JDBC, który

– operuje na poziomie języka SQL

– ukrywa przed programistą specyficzne własności i 

ustawienia bazy danych

• program napisany w Javie – działa z dowolną bazą danych

– obsługującą ten sam standard SQL-a 

– wspierającą technologię JDBC

• klasy  i interfejsy JDBC – dostępne w pakiecie java.sql

5

Praca z bazą danych poprzez 

JDBC

załadowanie sterownika JDBC

zdefiniowanie adresu URL połączenia

nawiązanie połączenia

utworzenie obiektu Statement

wykonanie zapytania lub aktualizacja danych

przetworzenie wyników

zamknięcie połączenia

6

Sterowniki

• sterownik JDBC - zestaw klas  implementujących 

interfejsy JDBC dla określonej bazy danych

• zazwyczaj pisane przez producentów baz danych

• z jednej strony przyjmują połączenia JDBC 

i instrukcje, a z drugiej wysyłają wywołania do 
bazy danych

background image

2

7

Kategorie sterowników

1. JDBC-ODBC bridge driver 

(technologia pomostowa między JDBC a ODBC 
Microsoftu)

2. Native API partly–Java driver

(biblioteki napisane w innych językach)

3. JDBC-Net pure Java driver

(standardowe interfejsy sieciowe)

4. Native–protocol pure Java driver

(protokoły sieciowe wbudowane w maszyny 
bazodanowe)

8

Kategorie sterowników

• Sterowniki typu 1 i 2

– często rozpowszechniane za darmo (np. w SDK)

– wymagają instalacji dodatkowego oprogramowania po 

stronie klienta

• Sterowniki typu 3 i 4

– zwykle odpłatne

– nie wymagają Ŝadnych dodatkowych instalacji

• Aktualna lista dostępnych na rynku sterowników - na 

stronie java.sun.com

9

Klasa DriverManager

• w celu nawiązania połączenia z bazą danych środowisko 

wykonawcze Javy musi załadować odpowiedni sterownik 
dla danej bazy

• za ładowanie i usuwanie z pamięci sterowników 

odpowiedzialna jest klasa DriverManager (zarządca 
sterowników), która: 

– dynamicznie zarządza obiektami sterowników 

zachowując kontekst zabezpieczeń kaŜdego sterownika

– kontekst zabezpieczeń definiuje środowisko, w jakim 

aplikacja jest uruchamiana

– porównuje kontekst zabezpieczeń sterownika 

z kontekstem programu (sprawdza czy są takie same)

10

Droga od kodu Javy do bazy danych

Program Java

MenedŜer sterowników

Sterownik

Wewnętrzny sterownik

Baza danych

JDBC

Baza 
danych

DriverManager
utrzymuje 
struktur
ę danych 
zawieraj
ącą 
obiekty Driver 
oraz informacje 
o nich

11

Ładowanie sterownika

Przy pomocy wiersza poleceń:

• Ŝeby wykorzystać sterownik JDBC trzeba go załadować

• naleŜy określić sterownik do załadowania przy uŜyciu 

zmiennej systemowej jdbc.drivers

• pomost JDBC-ODBC załaduje polecenie:

java  –Djdbc.drivers=sun.jdbc.JdbcOdbcDriver nazw_apl

W programach (mniej elastyczne):

• uŜytkownik końcowy nie moŜe w prosty sposób zmienić 

wersji bazy danych

• łatwiejsze w codziennym uŜytkowaniu

12

Rejestracja sterownika

• wywołanie metody Class.forName()
• argument metody (typu String) określa sterownik, np. dla 

technologii pomostowej JDBC-ODBC jest to: 

"sun.jdbc.odbc.JdbcOdbcDriver"

• załadowanie sterownika – aby zapewnić elastyczność kodu 

naleŜy unikać podawania na stałe nazwy uŜywanej klasy 
sterownika, np.
try {

Class,forName("connect.microsoft.MicrosoftDriver");
Class.forName("oracle.jdbc.driver.OracleDriver");
Class.forName("com.sybase.jdbc.SybDriver");

catch (ClassNotFoundException exp) 

{ System.out.println("Błąd ładowania sterownika: "+exp);}

background image

3

13

Określenie adresu URL połączenia

• adresy URL odwołujące się do baz danych wykorzystują protokół 

jdbc: i zawierają informacje o nazwie komputera na którym działa 
serwer bazy danych, numer uŜywanego portu oraz nazwę bazy 
danych

• format zapisu adresu URL – podany w dokumentacji dostarczonej 

z konkretnym sterownikiem JDBC

• np.:

String host="dbhost.firma.com.pl";
String db="nazwaBazy";
int port=1234;
String oracleURL = "jdbc:oracle:thin:@" + host + ":" + port + ":" + db;
String sybaseURL = "jdbc:sybase:Tds:"+ host + ":" + port + ":" + 

"?SERVICENAME" +db;

String msaccessURL = "jdbc:odbc" +db ;

14

Nawiązanie połączenia - klasa 

Connection

• po zarejestrowaniu sterownika program łączy się za jego pomocą 

z bazą danych

• nawiązanie połączenia realizuje metoda 

getConnection

klasy 

DriverManager:

DriverManager.getConnection("url","user","pass");

• wywołanie metody moŜe zgłosić wyjątek SQLException

• metoda zwraca obiekt klasy 

Connection

• np.:

String user="beatap";

String haslo="tajne";

Connection polaczenie = DriverManager.getConnection( 
oracleURL, user, haslo);

15

Interfejs Connection

• prepareStatement – tworzy prekompilowane zapytania do 

przesłania do bazy danych

• prepareCall – metoda odwołuje się do procedur 

zachowanych, przechowywanych na serwerze BD

• rollback, commit – metody do obsługi transakcji; commit -

zatwierdza zmiany, rollback odrzuca wszystkie zmiany 
dokonane od ostatniego wywołania commit

• setAutoSubmit() wyłącza opcję automatycznego 

dokonywania zmian

• close – zamyka otwarte połączenie z bazą danych
• isClosed – sprawdza czy nie skończył się okres waŜności 

połączenia lub czy nie zostało ono jawnie zamknięte

• getMetaData – zwraca obiekt DataBaseMetaData

16

Informacje o bazie danych

• Metody obiektu DatabaseMetaData:

– getDatabaseProductName – nazwa BD

– getDatabaseProductversion – numer wersji BD

– getDriverName – nazwa sterownika JDBC

– getDriverVersion – numer versji sterownika

• Np.:

DatabaseMetaData dbmeta = polaczenie.getMetaData();
String nazwaBazy = dbmeta. getDatabaseProductName();
System.out.println("Baza danych: " + nazwaBazy );
String numerwersji = dbmeta. getDatabaseProductversion();
System.out.println("Numer wersji bazy: " + numerwersji); 

17

Utworzenie polecenia - obiekt 

Statement

• do przesyłania zapytań i poleceń do BD są 

wykorzystywane obiekty Statement

• metoda createStatement() utworzonego obiektu 

klasy Connection zwraca obiekt Statement

• np.

Statement polecenie=polaczenie.createStatement(); 

• większość sterowników JDBC pozwala na 

jednoczesne tworzenie i uŜywanie większej liczby 
obiektów Statement korzystających z tego samego 
połączenia z BD

18

Wykonanie zapytania

• dysponując obiektem Statement moŜna juŜ 

przesłać zapytanie SQL

• executeQuery – przesyła zapytanie i w wyniku 

zwraca obiekt ResultSet przechowujący wiersze 
tabeli wyników

• np.

String zapytanie = "SELECT * FROM books"; 
ResultSet wynik = polecenie.executeQuery(zapytanie);

background image

4

19

Interfejs Statement – przesyłanie i 

wykonywanie dowolnych poleceń SQL

• executeQuery – wykonuje polecenie SQL i zwraca dane w postaci 

obiektu ResultSet (obiekt moŜe być pusty ale metoda nie zwraca null)

• executeUpdate – realizuje polecenia SQL UPDATE, INSERT, 

DELETE i zwraca liczbę rekordów objętych działaniem 
poszczególnych poleceń (równieŜ 0); obsługuje takŜe polecenia 
CREATE TABLE, DROP TABLE, ALTER TABLE

• executeBatch – wykonuje grupę poleceń SQL jako jedną całość i 

zwraca tablicę wierszy objętych działaniem poszczególnych poleceń; 
dodawanie poleceń do grupy – metoda addBatch

• setQueryTimeout – określa czas przez jaki sterownik będzie czekał na 

odebranie wyników zanim zgłosi wyjątek SQLException

• getMaxRows, setMaxRows – max liczba wierszy jaką moŜe zawierać 

obiekt ResultSet (domyślnie 0 – nie ograniczona) 

20

Obiekty Statement i ResultSet

program Java

JDBC & Driver

baza danych

czas

Statement(SQL)

ResultSet

Statement(SQL)

ResultSet

Baza 

danych

21

Interfejs ResultSet -

przetworzenie wyników 

• metoda next() zwraca kolejny wiersz lub

false

jeśli 

osiągnięto koniec zbioru wynikowego

• getXxx – metody zwracające wartości niemal wszystkich 

podstawowych typów danych (np. getString(), getInt() )

• UWAGA! Kolumny zbioru wynikowego są indeksowane 

(zgodnie z konwencją przyjętą 
w SQL) od 1 a nie od 0. 

• odczytując dane przechowywane w obiekcie ResultSet, 

lepiej jest uŜywać nazw kolumn (nie ich indeksów) – w 
przypadku zmiany struktury tabeli niebezpieczeństwo 
awarii kodu obsługującego wyniki jest mniejsze

22

Przykład – wyświetlenie 

wyników

String host="dbhost.firma.com.pl"; String db="nazwaBazy"; int port=1234;
String URL = "jdbc:odbc" +db ;
String user="beatap"; String haslo="tajne";
Connection polaczenie = DriverManager.getConnection(URL, user, haslo);
Statement polecenie=polaczenie.createStatement();
String zapytanie = "SELECT * FROM znajomi"; 
ResultSet wynik = polecenie.executeQuery(zapytanie);
while (wynik.next()) 

{

int id = wynik.getInt("id");
String n = wynik.getString("nazwisko");
String i = wynik.getString("imie");
String e = wynik.getString("email");
System.out.println(id+" "+n+" "+i+" "+e); }

polaczenie.close();

23

Interfejs ResultSet

• next(), previous()
• relative(int)

– przesuwa kursor o podaną liczbę wierszy do 

przodu lub do tyłu (wartość ujemna)

• absolute(int)

– przesuwa kursor do wiersza o wskazanym 

numerze

• getXxx

– zwraca wartość odczytaną z wiersza o podanej 

nazwie lub indeksie

• wasNull

– sprawdza czy wartość odczytana przez ostatnie 

wywołanie metody getXxx jest Null

• findColumn

– zwraca indeks kolumny o podanej nazwie

• getRow

– zwraca numer bieŜącego wiersza (numerowane 

od 1)

• getMetaData

– zwraca obiekt typu ResultSetMetaData 

opisujący zawartość ResultSet

24

Interfejs ResultSetMetaData

• getColumnCount
• getColumnName(int)
• getColumnType

– zwraca wartość int do 

porównania ze stałymi klasy java.sql.Types

• isReadOnly

– czy wskazana kolumna tylko do 

odczytu

• isSearchable

– czy wskazana kolumna moŜe być 

zastosowana w klauzuli WHERE

• isNullable

- czy wskazana kolumna moŜe 

zawierać NULL

background image

5

25

Zamknięcie połączenia

• polaczenie.close();

• Zamknięcie połączenia powoduje równieŜ zamknięcie 

uŜywających go obiektów 

Statement 

ResultSet

• JeŜeli planowane jest przeprowadzenie innych operacji na 

BD – nie naleŜy zamykać połączenia przed ich 
wykonaniem (koszt otwarcia nowego połączenia jest dość 
wysoki)

• W praktyce stosowanie juŜ otwartych połączeń jest bardzo 

waŜnym aspektem optymalizacji korzystania z baz danych

• API JDBC – definiuje specjalny interfejs 

ConnectionPoolDataSource

do korzystania z pul 

połączeń

26

Instalacja i konfiguracja 

serwera MySQL

• pobranie MySQL ze strony 

http://dev.mysql.com/downloads/ i zainstalowanie  
jako usługi systemowej (w Windows) –
sczególowe informacje na stronie 
http://dev.mysql.com/doc/

• utworzenie bazy danych

• utworzenie uŜytkownika

• instalacja sterownika JDBC

27

Instalacja sterownika JDBC

• najczęściej stosowane sterowniki do połączenia 

z MySQL (dostępne w plikach JAR):

– MySQL Connector/J (zalecany przez twórców MySQL)

– Caucho Resin

• Ŝaden z tych sterowników nie jest w pełni zgodny ze 

specyfikacją JDBC 2.0 ani ze standardem ANSI SQL-92

• podczas tworzenia aplikacji w zmiennej środowiskowej 

CLASSPATH naleŜy podać ścieŜkę dostępu do pliku JAR 
sterownika

• podczas wdraŜania aplikacji – plik sterownika naleŜy 

umieścić (dla serwera Tomcat) w folderze WEB-INF/lib lub 
we wspólnym folderze kat_instalacyjny/common/lib  (jeśli na 
serwerze działa wiele aplikacji WWW korzystających z bd)

28

Sterownik MySQL Connector/J 

• do pobrania ze strony:

http://www.mysql.com/products/connector-j/

• umieszczony w pliku:

mysql-connector-java-3.1.14\mysql-connector-java-
3.1.14-bin.jar

• klasa sterownika:

com.mysql.jdbc.Driver

• URL uŜywany do połączenia z bazą danych:

jdbc:mysql://komputer:3306//NazwaBazy

29

Sterownik Caucho Resin 

• do pobrania ze strony:

http://www.caucho.com/projects/jdbc-mysql/index.xtp

• umieszczony w pliku:

caucho-jdbc-2.1.0.jar

• klasa sterownika:

com.caucho.jdbc.mysql.Driver

• URL uŜywany do połączenia z bazą danych:

jdbc:mysql-caucho://komputer:3306//NazwaBazy

• wg. danych firmy Caucho sterownik jest 50% 

szybszy od sterownika MySQL Connector/J

30

Przykład 1 – wyświetlanie 

danych z bazy MYSQL 

import java.sql.*;
public class testBD {

public static void main(String[] args)

throws SQLException, ClassNotFoundException {

Class.forName("com.mysql.jdbc.Driver");
Connection polacz =
DriverManager.getConnection("jdbc:mysql://localhost:3306/
dane", "root", "");
Statement zapytanie = polacz.createStatement();
ResultSet w = zapytanie.executeQuery
("SELECT * FROM news");

background image

6

31

Przykład 1 – c.d.

while (w.next()) 
{

int id = w.getInt("Lp");
String n = w.getString("Naglowek");
String i = w.getString("Tresc");
String e = w.getString("Autor");
System.out.println(id+" "+n+" "+i+" \n"+e);

}
polacz.close();

}

}

32

33

Przykład 1a

• Przykład zmodyfikowanego zapytania SQL

  ResultSet w = zapytanie.executeQuery(

"SELECT Autor FROM news");

  while (w.next()) 
  {
 

String n = w.getString("Autor");

 

System.out.println(n);

  }

34

Przykład 1b – dodawanie 

rekordów do bazy

  Statement zapytanie = polacz.createStatement();
  int x = zapytanie.executeUpdate( "INSERT INTO news 
  (Autor, Naglowek, Tresc) VALUES ('Wilk', 'Tytul', 'Tresc')");
  System.out.println("Dodano rekordow: " + x);

35

Netbeans 6.5 i serwer JavaDB 

36

Połączenie z Network Java DB

projektu w NetBeans  

• w strukturze projektu wskazać 

Libraries

oraz 

wybrać

Add JAR/Folder...

(pod prawym przyciskiem)

• wskazać ścieŜkę do

\db\lib\derbyclient.jar

(np. ...sun\JavaDB\lib\derbyclient.jar )

• W aplikacji przetestować przykładowy kod: 

Class.forName("org.apache.derby.jdbc.ClientDriver");

Connection conn=
DriverManager.getConnection("jdbc:derby://localhost:1527/db", "app", 
"app");

ResultSet rs =
conn.createStatement().executeQuery("SELECT * FROM db_table");        
while(rs.next()){     System.out.println(rs.getString(2));        }

background image

7

37

Połączenie z Embedded Java DB

projektu w NetBeans

• w strukturze projektu wskazać

Libraries

oraz 

wybrać

Add JAR/Folder...

(pod prawym przyciskiem)

• wskazać ścieŜkę do

\db\lib\derby.jar

(np. ...sun\JavaDB\lib\derby.jar )

• W aplikacji przetestować przykładowy kod:

Class.forName("org.apache.derby.jdbc.EmbeddedDriver");

Connection conn=
DriverManager.getConnection("jdbc:derby:db", "app", "app");
ResultSet rs =
conn.createStatement().executeQuery("SELECT * FROM db_table");        
while(rs.next()){      System.out.println(rs.getString(2));        }

38

Baza testbp z tabelą studenci

39

Rekordy tabeli studenci

40

Przykład 2 – połączenie z JavaDB

import java.sql.*;
public class Main {

public static void main(String[] args) throws SQLException,

ClassNotFoundException {

Class.forName("org.apache.derby.jdbc.ClientDriver");
Connection conn=

DriverManager.getConnection("jdbc:derby://localhost:1527/testbp",
"beatap", "beatap");

ResultSet rs =

conn.createStatement().executeQuery("SELECT * FROM studenci");

while(rs.next()){ System.out.println(rs.getString(2)); }

}

}

41

Przykład 2 - wynik

42

Zalety JDBC

• łatwość uŜycia (dzięki temu, Ŝe jest juŜ 

zdefiniowany interfejs i wszystkie mechanizmy do 
obsługi baz danych, pozostaje jedynie z niego 
skorzystać) 

• uniwersalność (jak z kaŜdego produktu SUN 

z JDBC moŜna korzystać na kaŜdej platformie; 
obsługa róŜnych rodzajów baz danych (Oracle, 
Access, MySQL itd.) jest bardzo podobna

background image

8

43

Wady JDBC

• niska wydajność (poniewaŜ jest to interfejs - zanim 

zapytanie powędruje do bazy danych, jest ono 
przetwarzane do postaci uniwersalnej, rozumianej 
przez wszystkie systemy oraz bazy danych; nawet 
jeśli uŜytkownik pracuje na dwóch identycznych 
bazach danych, to i tak komunikacja między nimi 
sprowadza się do tłumaczenia na "język uniwersalny" 
a dopiero potem dostarczania docelowej bazie 
danych) 

• niski poziom bezpieczeństwa (aby komunikacja 

z bazą danych mogła przebiegać w miarę szybko 
i być przy tym uniwersalna poziom bezpieczeństwa 
jest tutaj na niezbyt wysokim poziomie)