Integrarea SQL




Structured Query Language (SQL) este limbajul standard pentru accesarea bazelor de date realationale deşi nu este la oră actuală un standard aşa cum ar trebui să fie. Una din probleme sunt tipurile de date folosite de diferite SGBD-uri, care uneori variază şi variaţiile pot fi semnificative. JDBC se ocupă cu definireă unui set de identificatori de tip generici în clasa java.sql.
Un alt aspect de dificultate pentru SQL este faptul că cu toate că majoritatea SGBD-urilor folosesc o formă standard de SQL pentru functionarea standard, nu sunt conforme cu sintaxa şi semantica standard pentru SQL, mai recentă pentru mai multe funcţionalităţi. De exmplu nu toate bazele de date suportă proceduri stocate şi outer join, şi cele care o fac nu sunt consistente intre ele. Se speră că aceă parte a SQL care este în realitate un standard se va extinde pentru a include mult mai multe functionalităţi dar în acelasi timp API -ul JDBC trebuie să suporte SQL aşa cum este.
1. O metodă prin care JDBC tratează aceast problemă este prin permiterea oricărei interogări sub formă de şir de caractere să fie transmisă unui driver de SGBD. Această înseamnă că o aplicaţie este liberă să folosească atât funcţionalitate JDBC, dar apare riscul apariţiei unor erori pe unele SGBD-uri. De fapt o aplicaţie care conţine interogări nu trebuie să fie neaparat SQL ci poate fi şi o derivaţie a SQL destinată pentru SGBD-uri specifice cum sunt interogări de document sau imagine.



2. O a două metodă prin care JDBC lucrează cu probleme de integrare ă SQL este prin furnizareă unei clauze de ieşire asemanătoare ODBC. Sintaxa de ieşire furnizează un standard JDBC, pentru mai multe domenii în care SQL nu poate actiona ca un standard.
3. Pentru aplicaţii complexe, JDBC realizează integrarea SQL în al treilea mod şi furnizează informaţii descriptive despre SGBD prin interfaţa DatabaseMetaData astfel incât aplicaţiile să se poată adapta necesităţilor şi facilităţilor fiecărui SGBD. Utilizatorii finali obişnuiti nu işi pun probleme despre metadatele utilizate.

Deoarce JDBC este folosit că bază pentru dezvoltarea unor instrumente de acces la baze de date are de asemenea de rezolvat şi problema conformităţii cu orice aplicaţii ce sunt realizate în ele. Realizarea JDBC Compliant(TM) a fost creată pentru a realiza un nivel mai înalt de funcţionalitate JDBC pentru utilizatori. Pentru a folosi această variantă un driver trebuie să suporte măcar ANSI SQL-2 Entry Level. Dezvoltatorii de drivere pot realiza acest deziderat prin testareă componentelor care vin cu JDBC.

Conectabilitatea bazelor de date Java (JDBC)

S-a estimat că jumatate din software-uri includ operatii de tip client server. JDBC este conceput a fi independent de platforma , astfel nu trebuie să ne preocupe baza de date pe care o folosim în timp ce programam. Apelul la metoda pe care il facem, corespunde cu operatiile logice pe care vrem să le facem pentru a colecta date dintr-o baza de date: conectarea la baza de date, executarea de interogari ,si afisarea rezultatului .
Pentru a permite aceasta independenta de platforma, JDBC asigura un driver manager care mentine în mod dinamic toate obiectele driver de care au nevoie interogarile bazei de date. Daca avem trei tipuri diferite de baze de date la care vrem să ne conectam, vom avea nevoie de trei obiecte driver diferite. Pentru a deschide o baza de date trebuie să cream un "URL de baza de date", care specifica urmatoarele elemente :
1. faptul că folosim JDBC cu un "jdbc"
2. subprotocolul - numele driver-ului sau a mecanismului de conectare la baza de date. Datorita faptului că design-ul lui JDBC a fost inspirat din ODBC , primul subprotocol valabil este "jdbc-odbc bridge", specificat prin "odbc'.
3. identificatorul bazei de date . Acesta variaza în funcţie de driver-ul bazei de date utilizat, dar de obicei asigura un nume logic care e bazat de software-ul de administrare a bazei de date într-un director unde tabelele bazei de date sunt localizate.
Pentru că identificatorul bazei de date să aiba inteles trebuie inregistrat numele care utilizeaza software-ul de utilizare a bazei de date. Toate aceste informaţii sunt combinate într-un singur string "URL-ul bazei de date". De exemplu pentru conectare prin subprotocolul ODBC la o baza de date indentificata sub forma "personal" baza de date URL poate fi :
String dbUrl = "jdbc:odbc:personal";

Daca ne conectam printr-o reţea, baza de date va conţine de asemenea informaţii de identificare a calculatorului aflat la distanta. când dorim conectarea la baza de date facem apel la metoda statica DriverManager.getConnection( ) şi că parametrii introducem url, nume de user şi parola. Obţinem un obiect Connection pe care apoi il folosim pentru interogarea şi manipularea bazei de date. Urmatorul exemplu deschide o baza de date ce conţine informaţii de contactare şi cauta prenumele persoanei introdusa în linia de comanda.. Selecteaza numai numele persoanelor care au adresa email, apoi afiseaza toate persoanele cu acest prenume
Exemplu:
//face cautare intr-o baza de date dupa email, folosind JDBC
import java.sql.*;
public class Lookup {
public static void main(String[] args)
throws SQLExcepţion, ClassNotFoundExcepţion {
String dbUrl = \"jdbc:odbc:personal\";
String user = \"\";
String password = \"\";
Try {
// incarca driverul
Class.forName(
\"sun.jdbc.odbc.JdbcOdbcDriver\");
Connection c = DriverManager.getConnection(
dbUrl, user, password);
Statement s = c.createStatement();
// SQL code:
ResultSet r =
s.executeQuery(
\"SELECT FIRST, LAST, EMAIL \" +
\"FROM personal.csv personal \" +
\"WHERE \" +
\"(LAST=\'\" + args[0] + \"\') \" +
\" AND (EMAIL Is Not Null) \" +
\"ORDER BY FIRST\");
while(r.next()) {
// Capitalization doesn\'t matter:
System.out.println(
r.getString(\"Last\") + \", \"
+ r.getString(\"fIRST\")
+ \": \" + r.getString(\"EMAIL\") );
}
s.close(); // Also closes ResultSet
} catch (Excepţion e ) {
e.printStackTrace () ;
}
} }

Explicaţia codului:
In acest exemplu baza de date nu are protectie cu parola, deci numele de utilizator şi parola sunt string-uri goale. Odata conectarea realizata cu DriverManager.getConnection() se poate folosi obiectul rezultat Connection pentru crearea unui obiect Statement folosind metoda createStatement(). Cu Statement-ul obţinut se poate apela executeQuerry() caruia i se va da un string care conţine un statement SQL-92 standard. Metoda executeQuerry() returneaza un obiect ResultSet care este asemanator unui iterator : metoda next() - muta iteratorul la inregistrarea urmatoare din statement sau returneaza false daca s-a ajuns la sfarsit. Intotdeauna se va obţine un obiect ResultSet de la executeQuerry() chiar daca aceasta cerere resulta o inregistrare goala ( acesta este o excepţie care nu este prelucrata) . De remarcat este faptul că trebuie apelat next() inca odata inainte de a incerca citirea oricarei inregistrari. Daca rezultatul este gol, apelul lui next() va returna false. Pentru fiecare inregistrare rezultata putem selecta campurile folosind numele campului sub forma de string. De asemenea denumirile campurilor nu sunt CASE SENSITIVE. Determinam tipul returnat prin apelul la getInt(), getString(), getFloat(). în aceasta faza avem informaţiile din baza de date în format nativ JAVA şi putem utiliza folosind cod java normal. Cu JDBC intelegerea codului este relativ simplu, problemă este legata de a face să funcţioneze pe sisteme particulare.

Motivul ce creaza confuzie este faptul că trebuie să ne dam seama cum să facem că driver-ul JDBC să faca incarcarea corect, şi cum să configuram o baza de date ce utilizeaza software de administrare a bazei de date. Desigur, acest proces poate varia în mod radical de la un calculator la altul.


Pasul 1. Gasirea driver-ului JDBC
Exemplul anterior conţine urmatoarea secventa :
Class.forName ("sun. jdbc.odbc.JdbcOdbcDriver");
La instalarea JDK 1.1 nu exista fişierul JdbcOdbcDriver.class. Daca la incarcare se detecteaza că declaratia este gresita, se va lansa excepţia.

Pasul2 Configurarea bazei de date
Prin deschiderea control panel-ului observam doua icon-uri "ODBC". Selectam cel de "32bit ODBC", celalalt fiind destinat compabilitatii inverse , cu 16 bit ODBC.
La deschiderea icon-ului apare un tabel ce conţine : "User DSN , System DSN, File DSN, etc.. ", DSN insemnand Data Source Name , adica denumirea sursei de date .
Astfel se poate observa că pentru bridge-ul JDBC- ODBC , singurul loc unde este importanta setarea bazei de date este "System DSN" . De asemenea, vom dori testarea configuratiei şi să cream interogari . Pentru aceasta, avem nevoie de configurarea bazei de date în "File DSN". Astfel Microsoft Query Tool va gasi baza de date. Importanta mai mare o are baza de date care este folosita. Standardul ODBC suporta un număr de formate diferite pentru fişiere , incluzand chiar şi Dbase.De asemenea, include şi formatul ASCII separat prin virgula.

Am considerat baza de date "personal"pe care l-am exportat în format ASCII separat de virgula . în "File DSN" se alege driver-ul de text să gestioneze acest fişier , dupa care se deselectează "use current directory", pentru a putea specifica driver-ului locul unde s-a exportat fişierul de date. Fiecare fişier conţine de obicei un singur tabel, iar declaratiile SQL pot da rezultate care sunt culese din mai multe tabele , ale bazei de date, (numit join).Baza de date ce conţine un singur tabel , este numita flat file database. Majoritaea problemelor legate de depozitarea şi regasirea datelor , presupun folosirea de baze de date ce au mai multe tabele care sunt legate prin join. , numite baze de date relationale.



Pasul 3 . Testarea configuratiei
Pentru realizarea acestui lucru avem nevoie de o modalitate de descoperire daca baza de date este vizibila într-un program ce face interogarea.
Connection c = DriverManager.getConnection( dbUrl, user, password) ;
Daca apare excepţia, inseamna că configurarea nu a fost buna.
Pasul 4. Generarea de interogare SQL
Interogarea creata cu ajutorul Microsoft Query ne-a aratat doar că baza de date este acolo, dar a creat în mod automat un cod SQL ce este necesar de inserat în programul Java. S-a dorit crearea unei interogari care să asigure cautarea inregistrarilor în funcţie de prenumele pe introdus în linia de comanda ce apare la rularea programului. Se caută un prenume specific , Petre. De asemenea, s-a dorit gasirea prenumelui persoanelor ce aveau atasata şi adresa de e-mail. Se parcurg etapele:
- Se foloseşte Query Wizard pentru a crea o noua interogare. Se selectează baza de date "personal ", ceea ce este echivalent cu deschiderea conectarii prin specificarea Url-ului bazei de date.
- Se selectează tabelul "personal" din baza de date, iar din table se alege coloanele First, Last, Email.
- In "Filter Data", se alege Last, se selectează "equals", cu argumentul Eckel. Dacă se apasa butonul Add, apoi
- Se alege Email şi se selecteaza "is not null"
- In "sort by " se alege First. Se apasa butonul SQL, care va genera codul SQL care va fi copiat.

SELECT personal.First, personal.Last, personal.Email FROM personal .csv personal
WHERE (personal.Last = 'Eckel') AND
( personal.Email Is Not Null )
ORDER BY personal.First

La interogarile mai complexe, se poate gresi usor, dar cu ajutorul lui Query Tool, se pot testa interogarile, şi genera automat codul corect.

Pasul 5 . Modificarea şi copierea în interogare
Se poate observa codul ce difera de cel folosit în program, deoarace Query Tool foloseste calificari complete pentru toate denumirile, chiar şi în situatia în care baza de date are un singur tabel (ca şi în cazul prezentat). Daca avem mai multe tabele, calificarea previne producerea de coliziuni intre coloanele diferitelor tabele ale aceleiasi baze de date care au aceeasi denumire. Dar pentru că în aceasta interogare se include un singur tabel, putem elimina calificarile unor denumiri.

SELECT Firs, Last, Email
FROM personal.csv personal
WHERE (Last = 'Eckel') AND
(Email Is Not Null)
ORDER BY First

De asemenea vrem să se faca o cautare dupa prenumele introdus în linia de comanda. Cu aceste modificari, şi transformand declaratiile SQL într-un String creat în mod dinamic, se obţine :

"SELECT First, Last , Email" +
"FROM personal.csv personal" +
"WHERE" +
"(Last = ' " + args [0] + " ' )" +
"AND (Email Is Not Null) " +
"ORDER BY First ";

De asemenea, SQL-ul are o alta modalitate de a insera denumiri intr-o interogare , denumita stored procedures, care are avantaje legate de viteza.