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
poziomu wywołań SQL z języka Java o nazwie JDBC.
Szczególnie
interfejs JDBC stał się popularny i jest używany między innymi w:
programach
aplikacyjnych napisanych w Javie po stronie klienta;
appletach 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.
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. Aby użyć JDBC w programie należy dokonać importu:
import java.sql.*;
Sterownik JDBC - zestaw klas, które implementują interfejsy pakietu java.sql dla konkretnej bazy danych:
java.sql.Driver – interfejs odpowiedzialny za nawiązanie połączenia z bazą danych oraz tłumaczenie zapytań SQL na język baz danych.
java.sql.DriverManager - klasa zarządzająca zbiorem dostępnych sterowników oraz udostępniająca aplikacji ten, który jest przez nią wymagany, w celu nawiązania połączenia z bazą danych.
java.sql.Connection - klasa reprezentująca połączenie z bazą danych w celu wykonania ciągu instrukcji SQL.
java.sql.Statement - klasa reprezentująca instukcję SQL. Podstawowe dwie metody:
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.
java.sql.ResultSet – klasa reprezentująca zbiór rekordów zwracanych przez zapytanie – przy czym jeden rekord jest dostępny w danej chwili.
Kolejne rekordy uzyskuje się stosując metodę next, któora zwraca wartość logiczną:
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, które mając daną nazwę pola zwracają wartość tego pola w bieżącym rekordzie.
java.sql.SQLException - rozszerzenie klasy java.lang.Exception umożliwiające dostęp do informacji o błędach związanych z wykonywaniem instrukcji SQL na bazie danych.
Składnia URL używanego przez JDBC (jdbc oznacza nazwę protokołu):
jdbc:<podprotokół>:<podnazwa>
np.
jdbc:odbc:moja_baza
jdbc:oracle:thin:@xeon.pjwstk.waw.pl:1521:ORCL
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 metody RegisterDriver
obiektu DriverManager:
DriverManager.RegisterDriver(new sun.jdbc.odbc.JdbcOdbcDriver());
Krok 2: użycie metody getConnection klasy DriverManager do otwarcia połączenia z bazą danych, która zwraca referencję do obiektu klasy implementującej interfejs java.sql.Connection.
Connection con =
DriverManager.getConnection("jdbc:odbc:nazwa_bazy", "użytkownik",
"hasło");
Obiekty klas Connection, Statement i ResultSet:
//połącz się z bazą danych
Connection con =
DriverManager.getConnection(url, "scott","tiger");
Statement stmt = con.createStatement();
String query = "SELECT Ename, Sal FROM Emp";
// zbuduj obiekt reprezentujący instrukcję SQL
ResultSet rs = stmt.executeQuery(query);
try {
// przejdź po wszystkich wierszach wynikowych
while (rs.next()) {
String s = rs.getString("Ename");
Int n = rs.getFloat("Sal");
System.out.println(s + ": " + n);
}
} catch(SQLException ex) {// obsłuż wyjątki
System.out.println(ex.getMessage ()
+ ex.getSQLState () + ex.getErrorCode ());
}
gdzie przykładowo
url = "jdbc:oracle:thin:@xeon.pjwstk.waw.pl:1521:ORCL"
lub
url="jdbc:odbc:mojaBD"
(sterownik typu
most między JDBC a ODBC).
Modyfikowanie danych w bazie danych
Statement stm = con.createStatement();
int liczba = stm.executeUpdate(
"UPDATE Osoba SET Zarobki =
Zarobki*1.1");
System.out.println(
"Podniesiono zarobki o 10%: "+ liczba+"
osobom.");
stm.close();
-- za pomocą obiektu ResultSet
Statement stm =
con.CreateStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE)
String sql = "SELECT * FROM
Osoba";
ResultSet rs = executeQuery(sql);
rs.first();
rs.updateString("Nazwisko","Kowalski");
rs.updateInt("Zarobki",10000);
rs.updateRow();
Usunięcie bieżącego rekordu:
rs.deleteRow();
Dodanie nowego rekordu:
rs.moveToInsertRow();
rs.updateString("Nazwisko","Kowalski");
rs.updateInt("Zarobki", 10000);
rs.insertRow();
Domyślnie każda instrukcja SQL kończy się automatycznym zatwierdzeniem (auto-commit). Poniżej zmieniamy to domyślne ustawienie:
try {
con.setAutoCommit(false);
Statement stm=con.createStatement();
stm.executeUpdate(" .....");
stm.executeUpdate(" .....");
.....
con.commit();
}
catch(Exception e){
con.rollback();
}
float zarobki =
rs.getFloat("Zarobki");
if (rs.wasNull(){
zarobki = 0;
}