MokaByte Numero 25  -  Dicembre 98
JDBC 2.0 
di 
Marangoni
Rosanna
Vediamo come sia possibile ininteragire con il sistema AS 400 di IBM per mezzo del toolbox apposito



 

Il nuovo JDK 1.2 ha ampliato le funzionalità e le caratteristiche di JDBC, l’interfaccia java per database SQL. In questo articolo analizzeremo alcune delle novità introdotte in JDBC 2.0. 


Con il nuovo JDK 1.2 (Java Developement Kit) le JDBC API che costituiscono l’interfaccia java ai database, sono state riscritte per migliorare le funzionalità fornite con la versione di JDBC 1.0 e per ottimizzare le prestazioni durante l’esecuzione. Inoltre, sono state introdotte alcune nuove peculiarità che consentono di utilizzare JDBC con nuovi strumenti java quali Java Transaction Service (JTS), the Java Naming and Directory Interface (JNDI), JavaBeans e Enterprise Java-Beans (EJB). 
Sostanzialmente, l’utente che abbia già conosciuto ed utilizzato JDBC non dovrebbe riscontrare grosse differenze rispetto alla versione precedente.
Prima di descrivere quali siano effettivamente queste caratteristiche introdotte nella nuova release, analizziamo brevemente cosa sia JDBC e cosa permette di fare.

JAVA E I DATABASE: NASCE JDBC.

L’attenzione generale delle applicazioni realizzate negli ultimi anni è rivolta verso l’accesso alle basi di dati sia in locale che in remoto. Questo si può notare nel grande sviluppo del commercio elettronico tramite Internet ma soprattutto nella grande diffusione di piccole applicazioni per il singolo utente: dal guestbook presente in molte homepage agli elenchi delle pubblicazioni o delle discografie.
Da questo punto di vista, gli strumenti forniti con Java nelle prime versioni del JDK 1.0 erano molto limitate se non del tutto inesistenti. Al contrario, le nuove API contenute nel JDK 1.1 dal Marzo 1996, hanno introdotto un insieme di interfacce  Java che permettono di utilizzare database di tipo SQL come avviene, ad esempio, con ODBC. Tramite queste interfacce, è possibile collegarsi con estrema semplicità ad un qualsiasi database locale oppure (e qui sta la caratteristica fondamentale di JDBC) a database remoti, indipendentemente dal DBMS utilizzato. Si può quindi dire che queste API forniscono ai programmatori un’interfaccia uniforme per un vasto numero di database relazionali e che forniscono una base comune sulla quale si possono sviluppare tool e interfacce di alto livello indipendenti dal DBMS. A questo scopo, nelle API del JDK 1.1 è stato inserito il package java.sql che fornisce gli strumenti per creare connessioni ai database, interrogazioni SQL e per prelevare ed elaborare i risultati ottenuti.
L’esigenza delle JDBC API, è nata inoltre dall’impossibilità di utilizzare le ODBC API esistenti oppure di realizzare una vera e propria traduzione in Java delle loro funzionalità. Per questo, le JDBC API sono state realizzate sul modello X/Open CLI (Call Level Interface) e seguono la filosofia Java che permette l’utilizzo delle interfacce anche tramite browser e senza necessità di preinstallazione.
Un’altra interessante caratteristica di JDBC, consiste nel fatto che sia stata realizzata tramite Driver Manager permettendo di supportare molti driver per connettersi a DBMS di tipo diverso. Questi driver, scritti interamente in Java (pure or native Java), sono attualmente disponibili per un gran numero di basi di dati facilitando la diffusione di JDBC.

COSA C’E’ DI NUOVO IN JDBC 2.0?

Dopo questa breve introduzione sull’evoluzione di JDBC, ci possiamo concentrare sullo scopo di questo articolo, ossia sulle novità introdotte nella nuova versione del JDK.
Come già accennato, in sostanza la struttura delle JDBC API non ha subito grosse variazioni; un utente che abbia già utilizzato JDBC 1.0 non dovrebbe riscontrare grandi differenze. Al contrario, sono state introdotte delle nuove funzionalità per semplificare l’aggiornamento delle tuple di una base di dati, la loro visualizzazione e l’integrazione con l’intera piattaforma Java..
E’ però, da evidenziare che le JDBC 2.0 API sono composte da due parti complementari quali JDBC 2.0 Core API (trattate in questo articolo) e le JDBC 2.0 Standard Extension che contengono le specifiche riguardanti il nuovo package javax.sql.
Il package java.sql contiene tutte le modifiche che sono state effettuate sulle interfacce e sulle classi già esistenti in JDBC 1.0 e le nuove interfacce. Al contrario, il package javax.sql è stato intodotto per contenere quelle parti delle JDBC 2.0 API che sono strettamente correlate agli altri componenti della piattaforma Java e che sono essi stessi standard extension come JNDI e JTS, connection pooling e rowset.
Per quanto riguarda le Core API, si può dire che sono state modificate gran parte delle classi e delle interfacce contenute nelle JDBC 1.0 API, anche se sostanzialmente l’impostazione è rimasta la stessa. Inoltre, sono state aggiunte nuove classi e interfacce per poter incrementare le funzionalità disponibili. Di seguito, elenchiamo le modifiche e le aggiunte che sono state eseguite.
Le classi e interfacce in grassetto sono state introdotte nelle nuove API, quelle in italic sono state modificate mentre quelle in carattere normale sono rimaste inalterate.

 

java.sql.Array

java.sql.BatchUpdateException

java.sql.Blob

java.sql.CallableStatement

java.sql.Clob

java.sql.Connection

java.sql.DatabaseMetaData

java.sql.DataTruncation

java.sql.Date

java.sql.Driver

java.sql.DriverManager

java.sql.DriverPropertyInfo

java.sql.PreparedStatement

java.sql.Ref

java.sql.ResultSet

java.sql.ResultSetMetaData

java.sql.SQLData

java.sql.SQLException

java.sql.SQLInput

Java.sql.SQLOutput

java.sql.SQLWarning

java.sql.Statement

java.sql.Struct

java.sql.Time

java.sql.Timestamp

java.sql.Types

Riassumendo, le caratteristiche introdotte sono le seguenti:
  • Scrollable Result Set: per rendere più agile lo scorrimento delle tuple del database;

  • Updatable Result Set: un nuovo modo per eseguire l’aggiornamento e la modifica del database senza ricorrere alle query SQL;

  • Possibilità di inserire o cancellare delle tuple dalla base di dati senza l’utilizzo delle query SQL;
  • Possibilità di modificare la base dati tramite procedure Batch;
  • Utilizzo dei tipi di dati SQL3;
  • Inserimento di Standard Extension Features, ossia del package javax.sql che permette l’utilizzo di JDBC con JNDI (Java Naming and Directory Interface) e fornisce strumenti quali il Connection Pooling, il Rowset e il Distributed Transaction Support per l’utilizzo del protocollo two-fase commit e l’integrazione con i JavaBeans. Di questo ci occuperemo nel prossimo aricolo.
Prima di analizzare le nuove caratteristiche, ripriendiamo brevemente come si esegue una connessione ad un database utilizzando JDBC.

LA CONNESSIONE AL DATABASE.

Prima di ottenere la connessione al database, è necessario ricordarsi di importare il package java.sql in modo da poter utilizzare le classi e le interfacce di JDBC. Per questo, nelle linee di codice del programma dedicate all’importazione dei package, andrà specificato:

import java.sql.*;
Ottenere una connessione al database tramite JDBC è abbastanza semplice ed indipendente da quale tipo di DBMS si stia utilizzando. E’ necessario solamente indicare all’applicazione, tramite il DriverManager, quale driver utilizzare e farsi rilasciare un oggetto Connection che servirà per dialogare con la base dati. E’ da notare che per identificare il database è necessario specificare l’URL, ossia l’indirizzo verso il quale tentare la connessione. Questa stringa può variare in base al tipo di driver utilizzato, e, alcune volte, può richiedere anche la specificazione di login e password dell’utente. 
Le linee di codice che realizzano queste procedure iniziali per un database ODBC sono le seguenti:
 

Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

String url = "jdbc:odbc:NomeDatabase";

Connection con = DriverManager.getConnection(url, "Login", "Password");

Se si dovesse utilizzare un driver per Database MSQL, le linee di connessione sarebbero:
 

new MsqlDriver();

String url = " jdbc:msql:NomeEPercorsoDatabase";

Connection con = DriverManager.getConnection(url);

Ovviamente, la ricerca di un driver e il tentativo di connessione potrebbero non andare a buon fine e generare, di conseguenza, un’eccezione. Per questo, è necessario inserire le istruzioni appena viste, in un try-catch in questo modo:
 

try { 

 Class.forName("myDriver.ClassName"); 

} catch(java.lang.ClassNotFoundException e) {}

try {

String url = "jdbc:odbc:NomeDatabase";

Connection con = DriverManager.getConnection(url, "Login", "Password");

} catch(SQLException ex) {}

All’interno del secondo try-catch, andranno inserite anche tutte le istruzioni che intendiamo eseguire sul database, quali un’interrogazione, una modifica o qualsiasi altra operazione.

L’OGGETTO Statement.

Una volta ottenuta la connessione al database, è necessario creare un oggetto Statement che permetta di sottoporre al DBMS le nostre instruzioni SQL. Il modo più semplice per ottenere uno Statement,  data una connessione con, è il seguente:

 

Statement st = con.createStatement();

In seguito, tramite i metodi st.executeQuery() e st.executeUpdate() si possono eseguire operazioni rispettivamente di interrogazione o modifica (creazione tabelle, inserimento dati, cancellazione dati, etc.) sulla base di dati. 
Esistono 3 tipi di Statement: Statement, PreparedStatement, CallableStatement. Senza occuparci nel dettaglio delle differenze che intercorrono tra i tre diversi tipi di oggetto, possiamo dire che il loro scopo è comunque quello di poter fornire dei metodi per interagire con la base di dati e che quello che li caratterizza è solamente la possibilità o meno di “preparare” una Query pre-compilata nella quale è sufficiente solo inserire i parametri.

LO SCROLLABLE RESULT SET

L’esecuzione del metodo st.executeQuery() su un oggetto Statement, crea un nuovo oggetto chiamato ResultSet contenente la tabella che costituisce il risultato dell’interrogazione sulla base dati. Fino alla versione 1.0, l’unico modo per scorrere il ResultSet era il metodo next() che spostava il puntatore alle tuple del ResultSet restituendo un booleano per indicare se fosse raggiunta o meno la fine della tabella. Nel caso di una semplice base di dati composta da una Tabella AZIONI contenente i campi NOME (String) e PREZZO (Float), una query poteva essere realizzata in questo modo:

 

String query = "SELECT NOME, PREZZO FROM AZIONI";

ResultSet rs = st.executeQuery(query);

  while (rs.next()) {

  String name = rs.getString("NOME");

  Float price = rs.getFloat("PREZZO");

  System.out.println(name + "   " + price);

}

Come si può notare, il ciclo scorre il ResultSet dall’inizio alla fine, preleva i dati tramite i metodi getXXX e quindi li stampa a video.
Questo oggetto è stato ampliato nella nuova versione delle JDBC API in modo da poter scorrere i risultati in entrambi i sensi; quindi verso il basso e verso l’alto tramite l’introduzione del metodo rs.previous(). Inoltre sono stati inseriti altri metodi interessanti quali:
  • absolute(int i): per spostarsi in una tupla tramite il suo indice;
  • relative(int i): per spostarsi di i tuple dalla tupla corrente;
  • isFirst(): ritorna un booleano che indica se l’indice è posizionato sulla prima tupla; 
  • isLast(): ritorna un booleano che indica se l’indice è posizionato sull’ultima tupla; 
  • isBeforeFirst(): ritorna un booleano che indica se l’indice è posizionato prima della prima tupla;
  • isAfterLast(): ritorna un booleano che indica se l’indice è posizionato dopo l’ultima tupla; 
  • getRow(): ritorna un intero che indica il numero di tuple nella Tabella risultato.
Per ottenere un ResultSet di tipo Scrollable, è sufficiente inserire nella definizione il comando ResultSet.TYPE_SCROLL_INSENSITIVE come nel codice seguente:
 

Statement st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE);

ResultSet srs = st.executeQuery("SELECT NOME, PREZZO FROM AZIONI");

srs.afterLast();

while (srs.previous()) {

 String name = srs.getString("NOME");

 float price = srs.getFloat("PREZZO");

 System.out.println(name + "     " + price);

}

Ricordiamo che è buona norma inserire alla fine del corpo del programma (prima dell’ultimo catch, per intenderci) le linee di codice che permettono la chiusura rispettivamente del ResultSet, Statement e Connection.
 

uprs.close();

stmt.close(); 

con.close(); 

L’oggetto ResultSet può essere reso nuovamente non-scrollable tramite l’argomento TYPE_FORWARD_ONLY. Inoltre esistono due tipi di ResultSet scrollable: Sensitive e Insensitive. La differenza tra i due tipi di oggetto, consiste nella capacità o meno di vedere le modifiche effettuate sul database mentre il ResultSet è aperto. Ci occuperemo di questo nella parte dedicata alla Visualizzazione delle modifiche.

L’UPDATABLE RESULT SET

Un’altra caratteristica inserita nell’oggetto Result Set, consiste nella possibilità di modificare i dati di una Tabella senza ricorrere ad una query SQL.
Ad esempio: per modificare il prezzo di un’azione, nelle JDBC API 1.0, sarebbe stato necessario l’utilizzo del metodo executeUpdate().

 

st.executeUpdate("UPDATE AZIONI SET PREZZO = 10.99" + "WHERE NOME = ‘XYZ’");

Con l’Updatable ResultSet, è invece sufficiente spostarsi sulla riga voluta (è quindi necessario che il ResultSet sia anche Scrollable) e quindi lanciare il metodo updateXXX corrispondente al tipo di dato da modificare. 
Il codice per ottenere uno Scrollable and Updatable ResultSet, si deve inserire il parametro ResultSet.CONCUR_UPDATABLE come argomento durante l’esecuzione del metodo createStatement() sulla Connessione. Per rimuovere la possibilità di modificare il ResultSet si deve specificare ResultSet.CONCUR_READ_ONLY. Di default, se non viene specificato nessun paramentro a riguardo, il ResultSet viene creato non Updatable.
Un esempio di utilizzo potrebbe essere:
 

Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, 

ResultSet.CONCUR_UPDATABLE);

ResultSet uprs = st.executeQuery("SELECT NOME, PREZZO FROM AZIONI");

uprs.last();

uprs.updateFloat("PREZZO", 10.99);

uprs.updateRow();

Il metodo updateRow() serve per rendere effettive le modifiche inserite nel metodo updateXXX. Esiste anche il metodo cancelRowUpdates() che annulla le modifiche indicate con updateXXX(), ma questo è possibile solamente prima di un updateRow(). Una volta confermate le modifiche sul database, infatti, non sarà più possibile annullarle.

INSERIRE E CANCELLARE TUPLE SENZA UTILIZZARE CODICE SQL

Oltre alla modifica dei dati, è anche possibile inserire e cancellare delle tuple dalle tabelle del Database, senza utilizzare delle query SQL. Ribadiamo comunque, che è sempre possibile utilizzare l’SQL per questi tipi di aggiornamenti proprio come avveniva nella precedente verisione di JDBC. Proprio per questo motivo il codice già realizzato con JDBC 1.0 continua ad essere compilato ed eseguito anche dalle nuove API.
Un esempio di query SQL per l’inserimento di una tupla nella tabella AZIONI potrebbe essere il seguente:

 

stmt.executeUpdate("INSERT INTO AZIONI " + "VALUES ('XYZ', 10.99)");

Con le nuove funzionalità di JDBC sono stati introdotti i metodi moveToInsertRow(), moveToCurrentRow(), insertRow() e deleteRow() che possono essere utilizzati al posto dell’SQL.
Ad esempio  per inserire una tupla, sarà necessario posizionarsi sulla riga da inserire tramite il metodo moveToInsertRow(). Quindi, tramite il metodo updateXXX(), si dovranno inserire i dati dei campi. L’effettivo inserimento avviene tramite il metodo insertRow() che provvede alla scrittura della nuova tupla sul database.
 

Statement st = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,

         ResultSet.CONCUR_UPDATABLE);

ResultSet uprs = st.executeQuery("SELECT * FROM AZIONI");

uprs.moveToInsertRow();

uprs.updateString("NOME", "XYZ");

uprs.updateFloat("PREZZO", 10.99);

uprs.insertRow();

Per riposizionarsi sulla riga corrente prima dell’inserimento, esiste il metodo moveToCurrentRow(). E’ importante notare che questo metodo è utilizzabile solo se si è posizionati sulla riga di inserimento.
In modo del tutto analogo, il metodo deleteRow() permette la cancellazione di una tupla. In questo caso, per posizionarsi sulla tupla da eliminare, può essere d’aiuto utilizzare i metodi visti per lo Srollable ResultSet quali previous(), absolute(), relative(), etc.

LA VISUALIZZAZIONE DELLE MODIFICHE

Per quanto riguarda l’aggiornamento del ResultSet, devono essere puntualizzate alcune cose: fin tanto che il ResultSet non viene chiuso e quindi ricreato, le modifiche effettuate sul database non sono visibili. Questo potrebbe rivelarsi un grosso inconveniente dal punto di vista della consistenza dei dati.
Questo problema può essere ovviato tramite l’utilizzo di un ResultSet Scroll-sensitive. Questo tipo di ResultSet, considera gli aggiornamenti e le modifiche effettuate sul database anche se già aperto, ma solamente per quanto riguarda le tuple che sono in esso contenute. Tutto quello che avviene sul resto dei dati non viene visualizzato. Quello che può creare delle situazioni inaspettate, è il fatto che ogni tipo di driver configura i ResultSet in modo diverso rendendo differenti le capacità e le possibilità a loro associate. Per questo, è stata creata l’interfaccia DatabaseMetaData che possiede i metodi per vedere quali tipi di ResultSet sono supportati dal driver JDBC (es.: DatabaseMetaData.supportsResultSetType()). E’ anche possibile impostare l’isolation level per una transazione tramite il metodo 

 

con.setTransactionIsolation(TRANSACTION_READ_COMMITTED);

dove con rappresenta un oggetto Connection. Tramite questo isolation level, il ResultSet non visualizzerà i cambiamenti prima che questi non siano stati effettivamente inviati al database, ma questo può creare problemi di inconsistenza del database.
L’interfaccia DatabaseMetaData offre la capacità di determinare con procisione le capacità esatte supportate da un Result Set tramite i metodi:
  • othersUpdatesAreVisible;
  • othersDeletesAreVisible;
  • othersInsertsAreVisible.
In questo modo, posso specificare il grado di visibilità delle modifiche effettuate da altri. Per quanto riguarda le proprie modifiche, è possibile visualizzarle senza chiudere e riaprire il ResultSet, tramite i metodi:
  • ownUpdatesAreVisible;
  • ownDeletesAreVisible;
  • ownInsertsAreVisible.
A questo punto, le modifiche ai valori delle colonne, saranno reperibili tramite i metodi getXXX() dopo aver eseguito un updateXXX(). L’esempio seguente  mostra come si può determinare se un ResultSet di tipo TYPE_SCROLL_SENSITIVE può vedere le proprie modifiche.
 

DatabaseMetaData dmd;

if ( dmd.ownUpdatesAreVisible(ResultSet.TYPE_SCROLL_SENSITIVE)){

 //le modifiche sono visibili

}

Inoltre, se una modifica è visibile, esistono anche i metodi rs.wasUpdated(), wasDeleted() e wasInserted() che servono per determinare se una tupla è stata modificata da un’operazione di modifica, cancellazione o inserimento da quando il ResultSet è stato aperto.
Per essere sicuri di rendere visibili tutte le modifiche riguardanti una tupla precisa del ResultSet, comprese le più recenti, si può utilizzare anche il metodo ResultSet.refreshRow().

MODIFICA  DELLA BASE DATI TRAMITE PROCEDURE BATCH

Nelle JDBC 1.0 API, era possibile unire diverse query in modo tale che fossero tutte eseguite in una transazione sola. Questo era consentito grazie all’impostazione a false dell’setAutoCommit(), che di default è true, e che permette di inserire diverse update che vengono effettivamente eseguite solamente col metodo com.commit(). Il codice che permette di realizzare questo è:

 

con.setAutoCommit(false);

Statement st = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,

         ResultSet.CONCUR_UPDATABLE);

. . . //operazioni di update

con.commit();

con.setAutoCommit(true);

Nonostante sia ancora possibile utilizzare questo espediente, le JDBC 2.0 API mettono a disposizione un sistema nuovo che prevede l’impostazione una sequenza Batch direttamente da Statement. Ponendo sempre l’autoCommit a false, si possono associare ad uno Statement delle operazioni tramite il metodo st.addBatch(querySQL), per poi eseguirle con st.executeBatch().
E’ interessante notare che esecuteBatch(), ritorna un array di interi che indicano quante tuple sono state modificate per ogni operazione contenuta nella procedura Batch.
 

con.setAutoCommit(false);

Statement st = con.createStatement(); 

st.addBatch("INSERT INTO AZIONI" + "VALUES('ABC', 5.11)");

st.addBatch("INSERT INTO AZIONI " + "VALUES('DEF', 6.00)");

int [] updateCounts = st.executeBatch();

Per azzerare la lista dei comandi, è disponibile anche il metodo clearBatch(). 
Come si può facilmente notare, l’esecuzione di molte istruzioni in una procedura può comportare dei problemi di inconsistenza che non erano stati previsti. Questi errori portano alla generazione di eccezioni diverse in base alla natura stessa degli inconvenienti che sono stati generati. Ad esempio: se un’operazione contenuta nella procedura dovesse ritornare un ResultSet, questo, ovviamente, non potrebbe essere inserito nell’array di updateCount. In questo caso viene generata un’SQLException.
Se, al contrario, un’operazione non può essere eseguita per qualche motivo, allora viene generata una BatchUpdateException. 

UTILIZZO DEI TIPI DI DATI SQL3

I tipi di dati che vengono comunemente definiti SQL3 fanno parte delle nuove specifiche ANSI/ISO SQL standard. Le nuove JDBC 2.0 API, si sono adeguate a questo nuovo standard introducendo anche i metodi per la trattazione di questi tipi di dati che, quindi, possono essere utilizzati e manipolati come tutti gli altri tipi di dati che erano già presenti.
Le interfaccie che sono state introdotte per i corrispondenti tipi di dati, sono le seguenti:
 
 
 
 
 

  • Blob: per il tipo di dato Blob (Binary Large Object), che può memorizzare una grande quantità di dati come semplici bytes;
  • Clob: per il tipo Clob (Character Large Object) che può memorizzare una grande quantità di dati espressi in caratteri;
  • Array: per il tipo Array che permette di utilizzare un array come valore di una colonna; 
  • Struct e Ref: per utilizzare tipi di dati definiti dall’utente (UDT, User Defined Types) di tipo strutturato o distinto, che possono essere trattati come semplici valori di una colonna.
Per ognuno di questi tipi di dati, sono stati introdotti i metodi corrispondenti getXXX, setXXX e updateXXX in modo da renderli uniformi a quelli già esistenti. Ad esempio, se volessimo inserire nel nostro database una descrizione delle azioni, potremmo utilizzare un tipo di dato Clob. La modifica e l’utilizzo di questo tipo di dato può essere eseguita con le stesse procedure già esaminate:
Clob descrizione = rs.getClob(“DESCR”);
Per quanto riguarda gli UDT, possiamo dire che sono molto simili ai tipi strutturati presenti in java e che corrispondono all’istruzione SQL CRATE TYPE. Un esempio potrebbe essere rappresentato dalle coordinate di un punto. In questo caso si utilizza una struttura dati che è costituita da due valori: la coordinata x e la coordinata y.
L’unica cosa da notare è che nel caso delle Struct, è necessario eseguire il casting che trasformi l’oggetto restituito da getObject() in un oggetto Struct.
 

Struct point= (Struct) rs.getObject(“POINT”)

CONCLUSIONI

Come abbiamo potuto notare in questo articolo, la filosofia di JDBC di essere semplice da usare continua ad essere seguita fedelmente. Infatti, non solo sono state mantenute le caratteristiche di JDBC 1.0 per garantire una certa continuità, ma si è favorita ulteriormente l’indipendenza dai DBMS utilizzati e la capacità di modificare e trattare i dati. I nuovi metodi e le nuove interfacce, permettono di utilizzare il database nella maniera più semplice possibile, fornendo anche nuovi strumenti per “bypassare” le istruzioni SQL.
Inoltre le JDBC 2.0 API, hanno dimostrato anche di sapersi aggiornare in base al cambiamento degli standard, come è avvenuto per SQL3, e di sapersi integrare con l’intera piattaforma java e le sue nuove funzionalità.

BIBLIOGRAFIA

[1] Giovanni Puliti, “Il nuovo JDK 1.2”, Dev Settembre 1998.
[2] Massimo Carli, “JDBC: Java e la connessone ai Database”, Appunti delle lezioni di Linguaggi e Traduttori, Università degli Studi di Padova.
[3] Sun Microsystems Inc., “JDBCTM 2.0 API ”, 30 Maggio 1998, www.javasoft.com. www.javasoft.com.
[4] Sun Microsystems Inc., “The Java Tutorial”.
 


 
 
Marangoni Rosanna e' diplomanda in Ingegneria Informatica ed Automatica presso l'Universita' degli Studi di Padova con una tesi sulla multimedialita' nella comunicazione aziendale. Nel periodo 1997/98, ha sostenuto due esami su JAVA e da allora continua ad interessarsi degli sviluppi successivi.

 
 


 


MokaByte Web  1998 - www.mokabyte.it 
MokaByte ricerca nuovi collaboratori. Chi volesse mettersi in contatto con noi può farlo scrivendo a mokainfo@mokabyte.it