Documente Academic
Documente Profesional
Documente Cultură
Oracle JDBC
GeneralităŃi
Pentru scrierea aplicaŃiilor care accesează serverul Oracle XE o soluŃie bună
este limbajul Java. De altfel firma Oracle Co. pune la dispoziŃia utilizatorilor mediul
JDeveloper care posedă multiple facilităŃi în acest sens. În cele ce urmează se va
folosi mediul de programare Netbeans.
JDBC (Java DataBase Connectivity) este o colecŃie de clase care permite unei
aplicaŃii client scrisă în Java să acceseze un server de baze de date relaŃionale.
Folosind aceste clase o aplicaŃie poate să se conecteze la serverul de baze de date,
poate trimite comenzi SQL şi poate prelucra rezultatele furnizate de server ca urmare
a executării acŃiunilor comandate. Spre deosebire de ODBC (Open DataBase
Connectivity – colecŃie de proceduri scrise în C şi dependente de sistemul de
operare), colecŃia de clase conŃinute în JDBC este scrisă în Java fiind astfel realizată
independenŃa faŃă de sistemul de operare.
Fişierele sursă care folosesc clase din JDBC trebuie să includă pachetul
java.sql.
Pentru fiecare server de baze de date există implementări specifice ale JDBC.
Astfel în cazul accesării serverului Oracle XE proiectului aplicaŃiei client trebuie să i se
adauge una dintre arhivele .jar. existente în directorul [ORACLE_HOME]\jdbc\lib.
Dacă instalarea serverului Oracle XE s-a făcut în C:, atunci [ORACLE_HOME] este:
Clasa Connection
Pentru a accesa serverul Oracle XE, clasa principală a aplicaŃiilor care vor fi
realizate va conŃine un obiect din clasa Connection. Crearea sa va fi sistematic
realizată folosind secvenŃa de cod următoare:
try {
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:biblio/bibpas@193.226.7.210:1521/XE");
cnx = ods.getConnection(); // cnx apartine clasei Connection
} catch ( SQLException sqlException ) {
System.out.println("Conectare imposibila.");
System.exit( 1 );
}
cnx.close();
Clasa Statement
Pentru a trimite comenzi SQL individuale serverului de baze de date este
necesară crearea unui obiect din clasa Statement. Crearea obiectului se realizează
prin apelul metodei createStatement() a clasei Connection :
Statement stmt1 = cnx.createStatement() ;
sau
Statement stmt2 = cnx.createStatement(tip, acces) ;
a unor mulŃimi de selecŃie care pot fi parcurse în ambele sensuri se va utiliza varianta
metodei createStatement() cu doi parametri.
Primul parametru, tip, va avea una dintre valorile următoare:
• ResultSet.TYPE_FORWARD_ONLY, care indică faptul că mulŃimea de selecŃie
creată ulterior va putea fi parcursă doar înainte,
• ResultSet.TYPE_SCROLL_INSENSITIVE, care permite realizarea unei
mulŃimi de selecŃie care va putea fi parcursă în ambele sensuri dar nu
va reflecta modificările operate de alŃi utilizatori pe tabelele folosite la
interogare.
Al doilea parametru, acces, poate lua valorile:
După crearea unui obiect din clasa Statement acesta va putea fi folosit pentru
a apela metoda executeQuery() (pentru a trimite serverului comenzi SELECT) sau
metoda executeUpdate() (pentru a trimite serverului comenzi CREATE, UPDATE,
INSERT sau DELETE). Metoda executeQuery() returnează o mulŃime de selecŃie în
timp ce metoda executeUpdate() returnează un număr întreg reprezentând numărul
înregistrărilor afectate de comanda SQL dată.
După încheierea folosirii sale, obiectul Statement trebuie suprimat prin apelul
metodei close().
stmt.close();
Clasa ResultSet
Un obiect din clasa ResultSet conŃine o mulŃime de selecŃie furnizată de
serverul de baze de date ca urmare a executării unei comenzi de interogare
(SELECT).
Pentru parcurgerea liniilor mulŃimii de selecŃie un ResultSet integrează un
cursor care indică linia curentă a mulŃimii. IniŃial, după executarea interogării,
cursorul este poziŃionat înaintea primei linii. Pentru a avansa pe o nouă linie se
foloseşte metoda next() . Deoarece metoda next() returnează null la terminarea
liniilor mulŃimii de selecŃie, aceasta permite scrierea uşoară a unui ciclu de parcurgere
a liniilor mulŃimii de selecŃie.
try {
Statement stmt = cnx.createStatement();
ResultSet rs = stmt.executeQuery( "SELECT * FROM Edituri order by nume"
);
while ( rs.next() ) {
System.out.println( rs.getString("nume") );
}
77
stmt.close();
} catch (SQLException ex) {}
Statement stmt =
cnx.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY ) ;
Pentru inserarea unei noi linii folosind o mulŃime de selecŃie se va folosi o linie
creată în acest scop prin apelul metodei moveToInsertRow(). În această linie pot fi
apoi adăugate valorile dorite folosind metode update*() (updateInt(), updateString()
etc). Exemplu:
rs.moveToInsertRow(); // mută cursorul pe linia suplimentară creată
rs.updateInt(1, "23"); // impune valoarea pt. primul câmp
rs.updateString(2,"Casa cartii"); // idem, câmpul 2
rs.insertRow();
rs.moveToCurrentRow();
79
Clasa PreparedStatement
Deoarece trimiterea efectivă a unei comenzi SQL folosind un obiect din clasa
Statement presupune derularea în prealabil a unui proces de analiză sintactică şi de
construire a unei comenzi acceptate de serverul de baze de date, în cazul trimiterii
repetate a aceleiaşi comenzi SQL se poate câştiga timp dacă procesul de pregătire
menŃionat se derulează o singură dată pentru tot setul de comenzi. Pentru a realiza
acest lucru este necesar însă ca în locul obiectului din clasa Statement să se declare
un obiect din clasa înrudită PreparedStatement. Exemplu:
ps.close;
CHAR setString()
VARCHAR2 setString()
setBigDecimal()
setBoolean()
setByte()
setShort()
NUMBER
setInt()
setLong()
setFloat()
setDouble()
INTEGER setInt()
80
FLOAT setDouble()
CLOB setClob()
BLOB setBlob()
RAW setBytes()
LONGRAW setBytes()
setDate()
DATE setTime()
setTimestamp()
Clasa CallableStatement
Un obiect de tip CallableStatement permite lansarea în execuŃie a unei
proceduri stocate (scrisă în PL SQL de exemplu).
Crearea unui obiect din clasa CallableStatement se realizează ca în exemplele
următoare:
a. Procedură stocată fără parametri:
CallableStatement cs = cnx.prepareCall("{call procst}");
b. Procedură stocată având 2 parametri:
CallableStatement cs = cnx.prepareCall("{call procstoc(?, ?)}");
cs.setString(1,theuser);
cs.setString(2,password);
cs.executeQuery();
cs.executeQuery();
Date dataconect = cs.getDate(3);
Se deselectează!
82
Paşii realizaŃi asigură crearea pe disc a unei structuri de directoare care vor
conŃine fişierele proiectului. Proiectul nu conŃine încă nici o clasă, în arborele acestuia
figurând intrarea Source Packages cu o entitate, <default package>.
83
ConŃinut fereastră
import java.sql.*;
import oracle.jdbc.*;
import oracle.jdbc.pool.OracleDataSource;
ods.setURL("jdbc:oracle:thin:biblio/biblio@localhost:1521/XE");
cnx = ods.getConnection();
88
System.out.println("Conectare Ok");
} catch ( SQLException sqlException ) {
System.out.println("Conectare imposibila.");
System.exit( 1 );
}
// Se continua cu initializarea controalelor
initComponents();
}
Liniile evidenŃiate realizează iniŃializarea variabilei cnx. Aceasta va fi folosită în
continuare pentru accesul la baza de date.
În continuare se poate lansa aplicaŃia în execuŃie.
Dacă nu sunt incidente legate de conectarea la serverul de baze de date,
aplicaŃia va afişa fereastra principală (goală!) iar în regiunea mediului de programare
afectată consolei va apărea şirul de caractere "Conectare Ok":
89
Realizarea formularelor
Controale Windows
Formularele prin care sunt accesate datele conŃinute într-o bază de date pot fi
destinate realizării unei funcŃii elementare (afişare date, modificare, adăugare etc.)
sau pot realiza o funcŃie complexă. Un formular destinat realizării unei funcŃii
complexe conŃine un mare număr de controale Windows, în anumeite stări ale
aplicaŃiei putându-se pune chiar problema ascunderii unora dintre ele.
O aplicaŃie care conŃine formulare simple, fiecare destinat realizării unei
acŃiuni elementare, poate pune probleme de operare dar practica programării
recomandă această abordare deoarece atât depanarea cât şi întreŃinerea aplicaŃiilor
astfel concepute este mai simplă.
JMenuBar
IniŃierea diferitelor acŃiuni se realizează în principal folosind meniuri derulante
şi butoane. Meniurile derulante vor declanşa principalele funcŃii ale aplicaŃiei (afişarea
formularelor şi rapoartelor, salvarea bazei de date, oprirea aplicaŃiei) iar butoanele
vor declanşa acŃiuni în interiorul formularelor.
Pentru a defini meniul unei aplicaŃii trebuie creată o bară de meniuri (obiect
aparŃinând clasei JMenuBar), un ansamblu de meniuri derulante (obiecte de tip
JMenu) şi pentru fiecare meniu derulant, un ansamblu de opŃiuni (obiecte aparŃinând
clasei JMenuItem).
Pentru a realiza o aplicaŃie care accesează baza de date Oracle XE, schema
Biblio, se va proceda astfel:
clic
selectat
În continuare se va edita conŃinutul barei cu meniuri folosind reprezentarea
arborescentă afişată prin selectarea tabului Inspector.
b. Se modifică numele primului meniu derulant (proprietatea text):
selectat
modificarea proprietăŃii text
selectat
modificarea proprietăŃii text
Rezultat:
selectat
Celui de-al doilea meniu derulant i se vor adăuga în timp mai multe intrări,
fiecare având rolul de a declanşa afişarea unuia dintre formularele care vor fi
realizate.
În acelaşi mod va fi adăugat aplicaŃiei un al treilea meniul derulant, Rapoarte,
ale cărui intrări vor fi folosite pentru a declanşa afişarea rapoartelor.
Pentru a creea metoda care trebuie executată la selectarea unei opŃiuni dintr-
un meniu derulant se va selecta opŃiunea cu un dublu clic în fereastra Inspector:
dublu clic
Pentru opŃiunea Iesire din primul meniu derulant se va adăuga o metodă care va
conŃine închiderea conexiunii cu serverul şi va apela metoda System.exit(0) a cărui efect
este oprirea imediată a aplicaŃiei.
JLabel
Controlul de tip JLabel serveşte la plasarea într-un formular a unui text sau a
unei imagini.
93
JTextField
nume_ed.setText(nm);
. . .
String nume = nume_ed.getText();
dublu clic
95
nume_ed
Clic + Enter
System.out.println("Conectare imposibila.");
System.exit( 1 );
}
}
nume_ed.setText(nm);
}
} else {
ed_urm.setEnabled(false);
}
} catch (SQLException esq) {}
}
La fel se iniŃiază scrierea codului pentru celelalte două butoane, prec şi gata:
}
} catch (SQLException esq) {}
}
dublu clic
99
Laborator nr. 7
InterfaŃa aplicaŃiei. Conexiune cu baza de date.
Realizarea interfeŃei unei aplicaŃii care accesează baza de date pentru evidenŃa câinilor.
1. PorniŃi serverul Oracle XE – Start -> Programs -> Oracle Database 10g Express Edition ->
Go To Database HomePage sau tastaŃi în Internet Explorer adresa http://127.0.0.1:8080/apex/
2. PorniŃi mediul de programare NetBeans.
3. CreaŃi un proiect :
• File / New Project (Java Application), nume – Caini ( se deselectează Create Main Class
!!!);
• adăugaŃi proiectului arhiva ojdbc14_g.jar (curs p. 82);
• creaŃi fereastra principală a aplicaŃiei:
Urmând paşii File / New File -> Java Gui Form -> JFrame Form creaŃi clasa
principală (cu numele caini, package evidcaini), derivată din clasa JFrame, care
va conŃine metoda statică main();
daŃi nume ferestrei şi impuneŃi poziŃia în care se va afişa fereastra creată -
Events – windowActivated;
adăugaŃi
this.setLocation(150,150);
this.pack();
• realizaŃi modificările necesare comunicării cu serverul Oracle XE, baza de date caini.
inseraŃi la începutul fişierului caini.java
import java.sql.*;
import oracle.jdbc.*;
import oracle.jdbc.pool.OracleDataSource;
public caini( ) {
try {
OracleDataSource ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:caini/caini@localhost:1521/XE");
cnx = ods.getConnection();
System.out.println("Conectare Ok");
} catch ( SQLException sqlException ) {
System.out.println("Conectare imposibila.");
System.exit( 1 );
}
initComponents();
}
4. RealizaŃi câte-un proiect şi fereastra principală pentru toate bazele de date create în Oracle XE:
Biblio
Aeroport
Banca
103
5. Folosind aplicaŃiile realizate, afişaŃi în fereastra Output a mediului de programare date din baza
de date. Pentru aceasta adăugaŃi constructorului clasei principale două obiecte, comanda, de tip
Statement şi rez, de tip ResultSet astfel:
MulŃimea de selecŃie rez va conŃine rezultatul unei fraze SQL SELECT. În cazul primei aplicaŃii
folosiŃi fraza select * from caine.
AfişaŃi rezultatul:
while (rez.next()) {
System.out.println( rez.getString("rasa") );
}
comanda.close();
sau
Statement comanda = cnx.createStatement();
ResultSet rez = comanda.executeQuery("select rasa,talie from caine, talie where
talie.cod_talie = caine.cod_talie and talie.talie ='mare' ");
while (rez.next()) {
System.out.println(rez.getString("rasa")+" -- "+rez.getString("talie") );
}
comanda.close();
ObservaŃie: Pentru a evita greşelile de scriere, verificaŃi comenzile SQL folosite în cadrul
aplicaŃiilor folosind interfaŃa grafică a serverului Oracle XE.
while (rez.next()) {
System.out.println( rez.getString("cod_cursa")
+" -- "+rez.getString("nume_companie")
+" -- ora sosirii: "+rez.getString("ora_sosire"));
}
comanda.close();
sau
Lista pasagerilor care zboară
la Bucureşti şi compania
corespunzătoare zborului
Laborator nr. 8
3. CreaŃi un prim formular pentru parcurgerea unui tabel din baza de date, de exemplu autori,
astfel:
• AdăugaŃi clasei principale un obiect din clasa JDialog. Pentru aceasta selectaŃi succesiv
fereastra principală şi controlul JDialog din fereastra Palette;
• selectaŃi cu un dublu clic identificatorul noii ferestre în fereastra Inspector;
• adăugaŃi cele două controale de tip JLabel (pentru titlul formularului şi eticheta "autorul"),
un control de tip JTextField şi cele trei controale de tip JButton;
• schimbaŃi textele corespunzătoare acestor controale;
JLabel
JTextField
JButton
• schimbaŃi numele controalelor (clic dreapta pe control în fereastra Inspector -> Change
Variable Name) astfel:
107
• adăugaŃi clasei principale două noi variabile (obiecte), rezultat, din clasa ResultSet
(iniŃializat la deschiderea formularului şi închis la ieşirea din acesta), şi comanda, din clasa
Statement (aceasta va conŃine comenzi SQL individuale care vor fi apoi trimise serverului
Oracle XE ). Pentru adăugarea variabilelor selectaŃi în arborele de definire a proiectului:
Biblio -> Source Packages -> Biblioteca -> Biblio.java ->Biblio -> Fields -> Add Field;
try {
comanda = cnx.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
rezultat = comanda.executeQuery("SELECT * FROM autori");
if (rezultat.next())
{
String nm = rezultat.getString("nume");
numeaut.setText(nm);
}
} catch ( SQLException ex ) {
ex.printStackTrace();
}
• selectaŃi intrarea pautori ( = parcurgere autori) din meniul aplicaŃiei şi adăugaŃi-i o metodă
pentru tratarea evenimentului actionPerformed . Metoda va fi executată la selectarea
opŃiunii şi va provoca afişarea ferestrei de dialog realizate.
Autori.setLocation(120,170);
Autori.setVisible(true);
Autori.pack();
108
}
} catch (SQLException esq) {}
auturm.setEnabled(false);
}
} catch (SQLException esq) {}
109
4. CreaŃi un formular pentru parcurgerea tabelului edituri adăugând o nouă intrare în meniul
formularului principal.
5. AdăugaŃi în tabelul edituri două câmpuri suplimentare: adresa şi telefon, de tip varchar2 (150)
respectiv numeric(10):
6. AdăugaŃi în formularul realizat la punctul precedent alte două casete JTextField, în care să
afişaŃi informaŃii suplimentare despre edituri:.
Obs. :
• declaraŃi două variabile locale de tip String: nm1 şi nm2
String nm = rezultat.getString("nume");
110
8. AdăugaŃi în formularul realizat la punctul precedent alte două controale JTextField, în care să
afişaŃi informaŃii suplimentare despre cărŃi:.
Obs. :
• înlocuiŃi fraza SELECT de la punctul precedent cu alta:
SELECT nume, titlu, an_apar FROM edituri, carti WHERE carti.cod_edit=edituri.cod_edit
• declaraŃi alte două variabile locale de tip String: nm1 şi nm2
String nm = rezultat.getString("titlu");
String nm1 = rezultat.getString("nume");
String nm2 = rezultat.getString("an_apar");
numecarte.setText(nm);
ed.setText(nm1);
an.setText(nm2);
111
• adăugaŃi această secvenŃă de cod codului ce se execută la apăsarea celor două butoane
pentru navigarea printre înregistrările tabelelor autprec respectiv auturm
9. AdăugaŃi proiectului creat pentru exploatarea bazei de date aeroport o bară cu meniuri
derulante conŃinând meniurile: Fisier, Formulare, Rapoarte, Situatii, Help;
10. AdăugaŃi aplicaŃiei un formular cu ajutorul căruia să navigaŃi printre înregistrările tabelului
cursa, afişând informaŃii despre zboruri :
11. AdăugaŃi proiectului creat pentru exploatarea bazei de date caini o bară cu meniuri derulante
conŃinând meniurile: Fisier, Formulare, Rapoarte, Situatii, Help;
12. AdăugaŃi aplicaŃiei un formular cu ajutorul căruia să navigaŃi printre înregistrările tabelului
caine, afişând informaŃii despre rasă, scop, talie şi Ńara de origine: