Sunteți pe pagina 1din 8

JDBC

JDBC (Java DataBase Connectivity) este o parte a Java API dedicată conectării la
baze de date. Utilizând JDBC, se pot executa instrucţiuni SQL pentru orice bază de date
relaţională.
Etapele principale într-o aplicaţie ce foloseşte JDBC sunt următoarele:
- realizarea unei conexiuni cu baza de date;
- crearea unui "obiect instrucţiune" prin care se transmit instrucţiuni SQL către
gestionarul bazei de date;
- regăsirea rezultatelor.

Înregistrarea unei baze de date în driverul ODBC

Se presupune că a fost creată o bază de date cu Microsoft Access.


Baza de date astfel creată este însă particulară şi nu este recunoscută ca atare de orice
sistem. De aceea trebuie folosit un "intermediar" care să permită accesarea şi exploatarea ei.
Un astfel de intermediar este ODBC (Open DataBase Connectivity). Baza de date trebuie
conectată la o sursă de date ODBC, prin înregistrarea ei la driverul ODBC.
Din Administrative Tools se alege Data Sources (ODBC), ceea ce determină apariţia
ferestrei ODBC Data Source Administrator. În System DSN sau User DSN (baza de date a
sistemului sau a utilizatorului) se apasă ADD… şi apoi se selectează un driver pentru
Microsoft Acces (*.mdb) şi se apasă Finish. Se dă un nume sursei de date la Data Source
Name, nume care va fi folosit în programul Java. Se selectează calea unde este salvată baza de
date. Se apasă apoi OK.

Înregistrarea driverului JDBC folosind clasa DRIVER MANAGER

Un driver JDBC este înregistrat automat de managerul de drivere atunci când clasa
driver este încărcată dinamic.
Încărcarea driverului punte JDBC-ODBC se realizează prin:
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

Încărcarea driverului MySQL Connector/J care permite conectarea la serverul de baze


de date MySQL:
Class.forName("com.mysql.jdbc.Driver");

În cazul în care clasa nu este găsită se aruncă o excepţie ClassNotFoundException.

Stabilirea unei conexiuni cu baza de date sau


cu o sursă de date sub formă tabelară

Conectarea la baza de date se realizează prin crearea unui obiect de tipul


Connection. Modalitatea tipică de conectare este următoarea:
try {
String url="…";
Connection con =
DriverManager.getConnection(url,"user","parola");
}
catch (SQLException e) {...}
Se observă că trebuie trimis numele utilizatorului şi o parolă, pentru o eventuală
validare a accesului la baza de date.

Un URL (eng. Uniform Resource Locator) JDBC este un mod de a identifica o bază
de date astfel încât driverul corespunzător să o recunoască şi să stabilească o legătură cu
aceasta.
Sintaxa standard pentru URL-urile JDBC este:

jdbc:<subprotocol>:<nume>, unde:

 jdbc - precizează că pentru stabilirea conexiunii se foloseşte JDBC.


 <subprotocol> - nume de driver valid sau al altei soluţii de conexiune a bazelor de
date.
 <nume> - un nume logic sau alias corespunzător bazei de date. Dacă baza de date va
fi accesată prin internet, această secţiune va conţine:
//numegazda : port/ subnume

Exemple pentru câteva drivere JDBC:


ODBC - jdbc:odbc:<sursa_date>[;<nume_atribut> = <valoare_atribut>]*
MySQL - jdbc:mysql://server[:port]/numeBazaDate
Oracle - jdbc:oracle:thin:@server:port:numeInstanta

Execuţia instrucţiunilor SQL

O dată ce s-a stabilit o conexiune, aceasta este folosită pentru a trimite instrucţiuni
SQL unei baze de date.
În acest scop, JDBC conţine următoarele clase ale căror instanţe se creează prin apelul
unei metode speciale din clasa Connection:
 Statement. Un obiect Statement este utilizat pentru a trimite instrucţiuni SQL
simple. Acest obiect este creat de metoda createStatement().
 PreparedStatement. Un obiect PreparedStatement reprezintă o instrucţiune
SQL precompilată. Acest obiect poate fi utilizat pentru a executa aceeaşi
instrucţiuni de mai multe ori. El este creat de metoda prepareStatement().
 CallableStatement. Un obiect CallableStatement este utilizat pentru a executa
proceduri stocate SQL. Acest obiect este creat de metoda prepareCall().

Clasa Statement conţine trei metode pentru executarea comenzilor SQL:


 executeUpdate (StringSQL) - execută comenzi SQL de tipul: INSERT, UPDATE,
DELETE, CREATE TABLE, DROP TABLE, ALTER TABLE şi returnează
numărul liniei (înregistrării) afectate sau 0.
 executeQuery (StringSQL) - execută o comandă SQL care returnează un singur
ResultSet (instrucţiunile SELECT)
 execute (StringSQL) - execută o comandă SQL care întoarce mai multe mulţimi
rezultat

Clasa PreparedStatement se foloseşte pentru execuţia unor instrucţiuni SQL cu


parametri. Uneori programul trimite cereri de aceleaşi tip, dar cu alte valori pentru unul sau
mai multe câmpuri. În aceste situaţii este utilă, dar şi eficientă, folosirea unor instrucţiuni
SQL în care apar parametri. Astfel, instrucţiunea este compilată o singură dată în momentul
creării instanţei clasei PreparedStatement şi folosită apoi repetat, pentru valori diferite ale
parametrilor. În locul câmpului (câmpurilor) se introduce caracterul '?', urmând ca acesta să
fie înlocuit cu o valoare efectivă înainte de cererea propriu-zisă.

Metodele de setare:
public void setTip(int i, tip t) throws SQLException
setează parametrul cu numărul de ordine i, cu precizarea că numerotarea începe cu 1. Driver-
ul îl converteşte la o valoare de tipul tipSQL şi îl trimite bazei de date. Iată câteva cazuri
particulare:

Tip tip tipSQL


Boolean boolean BIT
Byte byte TINYINT
Short short SMALLINT
Int int INTEGER
Long long BIGINT
Float float FLOAT
Double double DOUBLE
BigDecimal BigDecimal NUMERIC
String String VARCHAR
Date Date DATE
Time Time TIME
Ref Ref REF
URL URL DATALINK

PROCESAREA REZULTATELOR

Un obiect ResultSet este rezultatul unei interogări SQL.


ResultSet-urile sunt sub formă de tabel iar denumirea coloanelor şi valorile acestora
sunt returnate în ordinea specificată în instrucţiune, satisfăcând condiţiile interogării. Metoda
public getTip(String s)întoarce conţinutul câmpului cu numele s din înregistrarea
curentă ca o valoare de tipul Tip din Java: String, Int etc.
Metodele fără parametri de intrare puse la dispoziţie de clasa Connection pentru cele
trei interfeţe prezentate mai sus produc mulţimi rezultat fără cursor deplasabil (cursorul se
deplasează doar înainte folosind metoda next()) şi nesenzitive la modificări (mulţimea rezultat
nu se actualizează automat la modificările survenite între timp în tabelă). Se pot însă obţine
mulţimi rezultat senzitive şi având cursor deplasabil prin specificarea în constructorul
instanţei Statement a două argumente:

Primul argument poate fi:


 TYPE_FORWARD_ONLY
 TYPE_SCROLL_INSENSITIVE
 TYPE_SCROLL_SENSITIVE

Al doilea argument poate fi:


 CONCUR_READ_ONLY
 CONCUR_UPDATABLE

Specificând constanta TYPE_FORWARD_ONLY se creează un ResultSet fără


cursor deplasabil. Dacă al doilea argument se ia ca fiind CONCUR_READ_ONLY se va
crea un ResultSet identic cu ResultSet-ul creat folosind metoda care nu conţine niciun
argument.
Pentru a crea un ResultSet ce are cursor deplasabil, trebuie specificat ca prim
argument una dintre constantele: TYPE_SCROLL_INSENSITIVE sau TYPE_SCROLL_
SENSITIVE. Diferenţa între cele două este că un ResultSet definit utilizând prima constantă
nu reflectă schimbările făcute cât timp ea este încă deschisă, lucru care se realizează
utilizând cea de-a doua constantă. Desigur, modificările se pot vedea închizând şi
redeschizând ResultSet-ul.

Metode folosite de mulţimile rezultat care au cursor deplasabil:


 previous()
 first()
 last()
 beforeFirst()
 afterLast()
 absolute(int nrLinie)
 relative(int nrSalt)
 isFirst()
 isLast()
 isBeforeLast()
 isAfterLast()
 getRow()

Metode folosite de mulţimile rezultat care pot fi modificate:


 updateTip(String numeCâmp, Tip valoare) //actualizare numai in ResultSet
 updateRow() //actualizare si in tabelul asociat din baza de date
 deleteRow()
 insertRow()
 moveToInsertRow() //e o linie specială

MetaData

Un obiect MetaData conţine informaţii despre baza de date sau capacităţile sale care
sunt disponibile datorită API-ului JDBC.

Principalele tipuri de MetaData accesibile prin JDBC sunt:


 DatabaseMetaData
 ResultSetMetaData
 ParameterMetaData

Un obiect DatabaseMetaData se creează apelând metoda Connection.getMetaData.


El poate fi folosit pentru a afla informaţii despre baza de date.

ResultSetMetaData

Informaţii referitoare la coloanele dintr-un ResultSet sunt disponibile apelând metoda


getMetaData. Obiectul ResultSetMetaData întors dă numărul, tipul şi proprietăţile coloanelor
obiectului ResultSet respectiv.
Unele din metodele utilizate pentru a accesa ResultSetMetaData sunt următoarele:

 getColumnCount() — Returnează numărul de coloane din ResultSet


 getColumnDisplaySize(int coloana)— Returnează lungimea maximă a coloanei exprimată
printr-un număr de caractere
 getColumnLabel(int coloana) — Returnează titlul coloanei pentru tipărire şi afişare
 getColumnName(int coloana) — Returnează numele coloanei
 getColumnType(int coloana) — Returnează indicele tipului de date SQL asociat coloanei
 getColumnTypeName(int coloana)— Returnează numele tipului de date SQL asociat
coloanei
 getPrecision(int coloana)— Returnează numărul de cifre corespunzător coloanei
 getScale(int coloana) —Returnează numărul de cifre după punct din coloană
 getTableName(int coloana) — Returnează numele tabelului
 isAutoIncrement(int coloana) — Returnează true dacă coloana este numerotată în mod
automat
 isCurrency(int coloana) — Returnează true dacă valoarea coloanei este frecventă
 isNullable(int coloana)— Returnează true dacă valoarea coloanei poate fi setată la valoarea
NULL

ParameterMetaData

Metoda getMetaData a clasei PreparedStatement recuperează obiectul


ResultSetMetaData care conţine o descriere a coloanelor care vor fi întoarse când se execută
PreparedStatement. Metoda getParameterMetaData() întoarce un obiect ParameterMetaData
care conţine descrierea parametrilor IN sau OUT folosiţi de PreparedStatement.

Mapări de tipuri între SQL şi Java

Tipul SQL Tipul Java


CHAR String
VARCHAR String
LONGVARCHAR String
NUMERIC java.math.Bigdecimal
DECIMAL java.math.BigDecimal
BIT boolean
TINYINT byte
SMALLINT short
INTEGER int
BIGINT long
REAL float
FLOAT double
DOUBLE double
BINARY byte[]
VARBINARY byte[]
LONGVARBINARY byte[]
DATE java.sql.Date
TIME java.sql.Time
TIMESTAMP java.sql.Timestamp

Exemplul 1:
import java.sql.*; // imports the JDBC core package
public class JDBCDemo{
public static void main(String args[]){
int nota;
String nume, prenume;
// SQL Query string
String query = "SELECT * FROM Detalii";
try {
// load the JDBC driver
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
}
catch(java.lang.ClassNotFoundException e) {
System.err.print("ClassNotFoundException: ");
System.err.println(e.getMessage());
}
try{
// get a connection
Connection con =
DriverManager.getConnection ("jdbc:odbc:DB");

Statement stmt = con.createStatement();


ResultSet rs = stmt.executeQuery(query); // execute query
while (rs.next()) { // parse the results
nume = rs.getString("Nume");
prenume = rs.getString("Prenume");
nota = rs.getInt("Nota");
System.out.println(nume+ " "+ prenume + " " +
nota);
}
stmt.close();
con.close();
}
catch(SQLException e){
e.printStackTrace();
}
}
}

Exemplul 2: PreparedStatement
import java.sql.*;
public class PreparedStmt{
public static void main(String args[]){
String nume;
Integer[] note={5,10};
String query = ("SELECT * FROM Detalii WHERE nota = ?");

try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
}
catch(java.lang.ClassNotFoundException e) {
System.err.print("ClassNotFoundException: ");
System.err.println(e.getMessage());
}

try{
Connection con =
DriverManager.getConnection ("jdbc:odbc:DB");
PreparedStatement pstmt = con.prepareStatement(query);
for (int i=0; i<2;i++){
pstmt.setInt(1, note[i]);
ResultSet rs = pstmt.executeQuery();
System.out.println(note[i]);
while (rs.next()) {
nume = rs.getString("Nume")+" "+rs.getString("Prenume");
System.out.println(nume);
}
}
pstmt.close();
con.close();
}
catch(SQLException e){
e.printStackTrace();
}
}
}

Exemplul 3: ResultSet care are cursor deplasabil


import java.sql.*;
public class ScrollableResultSet{
public static void main(String args[]){
Integer nota;
String nume, prenume;
String query = "SELECT * FROM Detalii";
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
}
catch(java.lang.ClassNotFoundException e) {
System.err.print("ClassNotFoundException: ");
System.err.println(e.getMessage());
}

try{
Connection con = DriverManager.getConnection ("jdbc:odbc:DB");
// get a connection
Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery(query);
rs.afterLast(); //cursor after last line of the table
// parse the results in reverse order
while (rs.previous()) {
nume = rs.getString("Nume");
prenume = rs.getString("Prenume");
nota = rs.getInt("Nota");
System.out.println(nume+ " "+ prenume+" "+nota);
}
stmt.close();
con.close();
}
catch(SQLException e){
e.printStackTrace();
}
}
}

Exemplul 4: ResultSet care poate fi modificat


import java.sql.*;
public class UpdatableResultSet{
public static void main(String args[]){
int nota;
String nume, prenume;
String query = "SELECT * FROM Detalii";
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
}
catch(java.lang.ClassNotFoundException e) {
System.err.print("ClassNotFoundException: ");
System.err.println(e.getMessage());
}

try{
Connection con = DriverManager.getConnection ("jdbc:odbc:DB");
// get a connection
Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery(query);
ResultSetMetaData md = rs.getMetaData();
if(rs.getConcurrency()==ResultSet.CONCUR_UPDATABLE)
System.out.println("UPDATABLE");
else
System.out.println("READ_ONLY");
int nColumns = md.getColumnCount();
System.out.println("Tabelul Detalii are " + nColumns + "
coloane");
System.out.println("Acestea sunt:");
for(int i=1;i<=nColumns;i++){
System.out.print(md.getColumnLabel(i)+" ");
}
System.out.println();
while (rs.next()) {
rs.updateInt("Nota", 7);
rs.updateRow();
for(int i=1;i<=nColumns;i++){
System.out.print(rs.getString(i)+" ");
}
System.out.println();
}
}
catch(SQLException e){
e.printStackTrace();
}
}
}

Observaţii:
Pentru mai multe informaţii despre JDBC şi MySQL a se vedea:
http://www.developer.com/java/data/article.php/3417381/Using-JDBC-with-MySQL-
Getting-Started.htm

Pentru mai multe informaţii despre JDBC şi Oracle a se vedea:


O'Reilly - Java Programming with Oracle JDBC.pdf

Mai multe despre JDBC puteţi găsi aici:


1. http://java.sun.com/docs/books/tutorial/jdbc/basics/index.html - Exemplele de
aici se găsesc în codeExamples_3.0.zip
2. Cartea Java de la 0 la Expert
3. Cartea Java Database Programming Bible (2002)

De studiat:
Tranzacţii şi instrucţiuni grupate (eng. batch)

Aplicaţii:
Încercaţi realizarea unei conexiuni:
 la o bază de date MySQL
 la o bază de date Oracle

S-ar putea să vă placă și