Le JavaServer Pages - Lezione 6 L’accesso ai Database A cura di Giuseppe De Pietro ([email protected]) Contenuti Al giorno d’oggi la maggior parte degli applicativi Web, anche semplici, hanno la necessità di interagire con un database, e parlando di JSP diventa obbligatorio trattare l’argomento, anche se non in maniera dettagliata, data la vastità dei temi che tratteremo. In questa lezione parleremo di: • JDBC e di come, grazie a questa interfaccia, sia possibile astrarsi dal DBMS (Data Base Management System) utilizzato. • Come installare MySQL e come creare un database. • Come installare MSDE, il motore gratuito di SQL Server 2000. • Eseguiremo operazioni di selezione, aggiunta e modifica record su database di MySQL e MS SQL Server 2000. • Come usare le Stored Procedure con JSP e MS SQL Server 2000 (MySQL non le supporta). Non parleremo degli accessi a database di Access perché Access non è un server di database, anche se Microsoft garantisce la multiutenza. Quindi se ne sconsiglia l’utilizzo per applicativi Web dove l’accesso simultaneo alle risorse è un aspetto importante che influisce molto sulle prestazioni dell’applicazione. Inoltre, mentre per MySQL, SQL Server 2000, ci sono dei driver gratuiti di tipo 4, i più efficienti, per Access invece bisogna affidarsi ai cosiddetti ponti JDBC-ODBC, i meno efficienti in assoluto (esistono dei driver di tipo 4 per Access, ma sono prodotti commerciali che non ho mai testato). Per un elenco completo dei driver a disposizione per Java, collegarsi a: http://servlet.java.sun.com/products/jdbc/drivers JDBC JDBC racchiude una serie di classi che permettono di interfacciarsi con un database relazionale. Con JDBC è possibile astrarsi dal tipo di DBMS che si utilizza, vale a dire che basta caricare il driver specifico e poi non c’è più alcuna differenza nell’accedere ad un tipo di database piuttosto che ad un altro. I programmi scritti con JDBC sono portabili su più sistemi operativi e sono indipendenti dal database relazionale a cui ci si connette, bisogna solo tener conto del diverso “dialetto” SQL parlato dal DBMS. JSP e MySQL Installazione di MySQL MySQL è un DBMS relazionale open source disponibile per diverse piattaforme, Windows, Linux, Solaris, FreeBSD, Mac/OS e altri. JSP – Lezione 6 – L’accesso ai Database 1 Nato per usi interni da TcX una società svedese di consulenza, l’intento primario dei progettisti era quello di creare un prodotto performante, infatti, MySQL fu da subito un prodotto veloce e affidabile e fu impiegato anche in ambito universitario e da alcuni Internet Provider. In realtà le eccellenti prestazioni si devono all’assenza di alcune funzionalità presenti in altri Database: la gestione delle transazioni (introdotte con le tabelle InnoDB nella versione 4), le Stored Procedure, i trigger, chiavi esterne e vincoli di integrità referenziale, e delle differenze del linguaggio SQL rispetto allo standard SQL92. Queste mancanze sono notevoli ma se i nostri progetti possono fare a meno di queste funzionalità, allora MySQL è il prodotto ideale, considerando che è gratuito se utilizzato sul Web. In questa sezione vedremo l’installazione in ambiente Windows e faremo riferimento all’ultima versione stabile del pacchetto, la 4.0.20d (a breve rilascerò una lezione interamente dedicata a JSP e Linux). Dopo aver scaricato e scompattato il file zip dall’indirizzo www.mysql.com, basta mandare in esecuzione il file setup.exe e installare il prodotto nella cartella c:\mysql. Poi da prompt dei comandi bisogna digitare: C:\mysql\bin\mysqld –-install Questo comando installerà MySQL come servizio di Windows che potrà essere gestito da Strumenti di amministrazione • Servizi (assicurarsi che il servizio MySQL sia impostato su avvio automatico). MySQL non prevede alcun interfaccia grafica per la sua gestione, quindi qualsiasi operazione va eseguita da riga di comando. Si consiglia l’utilizzo di tool grafici che velocizzano la gestione dei database. Ce ne sono tanti in circolazione, da quelli gratuiti a quelli commerciali. Tra quelli gratuiti si segnalano MySQL Control Center disponibile sul sito di www.mysql.com e MySQL Front (gratuita solo la versione 2.5) disponibile sul sito www.mysqlfront.de. In ogni caso il funzionamento di questi programmi è molto simile, per cui non faremo riferimento a nessuno in particolare, lasciando a voi la scelta. Gli esempi proposti saranno quindi generalizzati e utilizzabili sia da riga di comando, sia da tool grafici. Creazione del database Per le nostre prove abbiamo bisogno di creare un database. Ne progetteremo uno semplice con solo due tabelle: utenti dove andranno memorizzate le informazioni degli utenti, e una per la tipologia di utenti (insegnanti, alunni, genitori ecc.). Lo schema relazionale è il seguente: JSP – Lezione 6 – L’accesso ai Database 2 Quindi dopo aver creato un nuovo database di nome registro_online, creiamo le tabelle e le popoliamo con dei record. Segue lo script SQL completo: CREATE TABLE tipo_utente ( idtipo char(3) NOT NULL default '0', tipoUtente varchar(20) default NULL, PRIMARY KEY (idtipo) ) TYPE=MyISAM; INSERT INSERT INSERT INSERT INSERT INTO INTO INTO INTO INTO tipo_utente tipo_utente tipo_utente tipo_utente tipo_utente VALUES("INS", VALUES("STU", VALUES("GEN", VALUES("OSP", VALUES("ADM", "Insegnante"); "Studente"); "Genitore"); "Ospite"); "Amministratore"); CREATE TABLE utente ( UserID varchar(20) NOT NULL default '', password varchar(20) NOT NULL default '', cognome varchar(30) default NULL, nome varchar(30) default NULL, tipovia varchar(10) default NULL, Indirizzo varchar(40) default NULL, numcivico varchar(10) default NULL, cap varchar(5) default NULL, citta varchar(40) default NULL, prov char(2) default NULL, idtipo char(3) default NULL, email varchar(35) default NULL, telefono varchar(15) default NULL, cellulare varchar(15) default NULL, PRIMARY KEY (UserID) ) TYPE=MyISAM; INSERT INTO utente VALUES("rossi", "segreta", "Rossi", "Giovanni", "Corso", "Carlo Alberto", "12", "23900", "Lecco", "LC", "INS", "[email protected]", NULL, NULL); INSERT INTO utente VALUES("bianchi", "segreta", "Bianchi", "Michele", "Via", "Roma", "5", "23900", "Lecco", "LC", "STU", "[email protected]", NULL, NULL); INSERT INTO utente VALUES("verdi", "segreta", "Verdi", "Giuseppe", "Piazza", "Roma", "12", "20100", "Milano", "MI", "STU", "[email protected]", "211212", "121121"); Connettersi al database da pagine JSP Per poter utilizzare un database di MySQL da codice Java, abbiamo bisogno del driver JDBC chiamato Connector/J. È un driver gratuito disponibile all’indirizzo http://dev.mysql.com/downloads/connector/j. Faremo riferimento alla versione 3.0.14, la versione per Windows è un file zippato contenente oltre che i file jar necessari, anche la documentazione e vari esempi. Per poter utilizzare il driver in una Web Application, dobbiamo copiare il file mysql-connectorjava-3.0.14-production-bin.jar del pacchetto, nella cartella WEB-INF/lib della nostra applicazione. Ora possiamo cominciare a scrivere il codice necessario a connettersi al database appena creato. Come primo esempio realizzeremo una pagina di autenticazione utente in cui verranno richiesti la UserID e la password, i dati inseriti saranno confrontati con quelli presenti nella tabella utenti e a seconda dell’esito della ricerca, l’accesso dell’utente verrà autorizzato o meno. Le operazioni da effettuare sono: JSP – Lezione 6 – L’accesso ai Database 3 • Recupero dei parametri UserID e password. String nome=request.getParameter("nome"); String pwd=request.getParameter("pwd"); • Caricamento del driver per la connessione al database. Class.forName("com.mysql.jdbc.Driver"); • Apertura connessione. I parametri necessari per questa operazione sono: o Nome del Server su cui risiede MySQL (nel nostro caso localhost). o Nome del database (registro_online). o Nome utente e password registrati sul server di MySQL. Inizialmente MySQL crea un utente di default di nome root e senza password. Si consiglia vivamente di cambiare queste impostazioni. Per questo esempio abbiamo inserito ‘segreta’ come password per l’utente root. Connection cn = DriverManager.getConnection ("jdbc:mysql://localhost/registro_online?user=root&password=segreta"); • Creazione di un oggetto java.sql.Statement necessario per poter effettuare delle query sul database: Statement stmt = cn.createStatement(); • Una query di selezione può restituire dei record che devono essere recuperati da un oggetto di tipo java.sql.ResultSet (la funzione fc() serve per trattare le stringhe in Sql, vedi Lezione 3): String sql="SELECT * FROM utente WHERE UserID=" + fc(nome) + " AND password=" + fc(pwd); ResultSet rs = stmt.executeQuery(sql); • Per estrarre i dati dall’oggetto ResultSet si utilizza il metodo next() che ha una duplice funzione: restituire true se l’oggetto contiene dei record e scorre in avanti l’elenco dei record. Quindi per visualizzare il contenuto completo, si utilizza la sintassi: while(rs.next()) { [...codice...] } Nel nostro caso la query può restituire 0 o 1 record quindi useremo un controllo if al posto di while. Per leggere i dati: String cognome=rs.getString("cognome"); o se non si conosce il nome del campo: String cognome=rs.getString(int indice); Vediamo il codice completo del file esempio6_1.jsp in cui vengono richiesti la userID e la password: JSP – Lezione 6 – L’accesso ai Database 4 <%@ page language="java" %> <html> <head> <title>Accesso ad un Database MySQL</title> </head> <body> <h2>Accesso a un database di MySQL</h2> <form method="post" action="login.jsp"> <fieldset> <legend>Login utente</legend> <label for="nome">Inserisci il nome: </label> <input type="text" name="nome" id="nome"> <br/> <label for="pwd">Password: </label> <input type="password" name="pwd" id="pwd"> <br/><br/> <input type="submit" value="Login" name="invia"> </fieldset> </form> </body> </html> Infine il file login.jsp per la connessione al database e verifica utente. <%@ page language="java" import="java.sql.*" %> <%@ include file="/Lezione3/Include/funzioni.jsp" %> <html> <head><title>Database</title></head> <body><h3>Accesso Utenti registrati</h3> <% String nome=request.getParameter("nome"); String pwd=request.getParameter("pwd"); //caricamento driver Class.forName("com.mysql.jdbc.Driver"); //apertura connessione Connection cn = DriverManager.getConnection("jdbc:mysql://localhost/registro_online?user=root&p assword=segreta"); Statement stmt = cn.createStatement(); String sql="SELECT * FROM utente WHERE UserID=" + fc(nome) + " AND password=" + fc(pwd); ResultSet rs = stmt.executeQuery(sql); if (rs.next()){ //visualizza dati utente out.write("Cognome : "+rs.getString("cognome")+"<br/>"); out.write("Nome : "+rs.getString("nome")+"<br/>"); out.write("Indirizzo: "+rs.getString("tipovia")+" "+rs.getString("indirizzo")+" "+rs.getString("numcivico")+"<br/>"); out.write("Indirizzo: "+rs.getString("cap")+" "+rs.getString("citta")+" "+rs.getString("prov")+"<br/>"); out.write("E-mail : "+nn(rs.getString("email"))+"<br/>"); out.write("Telefono : "+nn(rs.getString("telefono"))+"<br/>"); out.write("Cellulare: "+nn(rs.getString("cellulare"))+"<br/>"); } else{ out.write("Utente non trovato <br/> Ripetere la procedura di login"); } stmt.close(); cn.close(); %> <br/><br/><a href="index.html" title="Torna indietro">Indietro</a> </body></html> JSP – Lezione 6 – L’accesso ai Database 5 Al termine delle operazioni è indispensabile chiudere gli oggetti Statement e Connection per poter liberare le risorse(ResultSet viene automaticamente chiuso insieme all’oggetto Statement). JSP e MS SQL Server 2000 Strumenti necessari Abbiamo visto, nella sezione precedente, come MySQL sia un prestante server di database ma con ridotte funzionalità. In grossi progetti può rendersi indispensabile l’utilizzo di certe funzionalità tipiche di database relazionali di fascia alta (e purtroppo dal prezzo elevato). SQL Server 2000 è l’ultimo prodotto di Microsoft progettato per gestire altissimi volumi di operazioni transazionali in ambienti multiutente e offre pieno supporto a trigger, vincoli di integrità referenziale, stored procedure, oltre che una notevole compatibilità con lo standard SQL92. Se non abbiamo a disposizione una licenza d’uso di SQL Server, possiamo comunque creare e utilizzare dei database in formato SQL Server 2000. Come? Utilizzando MSDE (Microsoft SQL Server Desktop Engine) un motore ridotto del prodotto commerciale, limitato per numero di connessioni simultanee (massimo 5) e per grandezza di database gestibili (massimo 2 GB), inoltre mancano tutti i tool di gestione come Enterpise Manager, Query Analyzer, Profiler ed altri. MSDE è messo a disposizione con Office Professional (2000, XP o 2003) e con Visual Studio.NET oltre che liberamente scaricabile dal sito Microsoft. In questa lezione vedremo come installare MSDE. Dopo aver scaricato il pacchetto compresso autoestraente SQL2KDeskSP3.exe, scompattarlo nella directory c:\ sql2ksp3. Ora si procederà con l’installazione di MSDE impostando come modalità di autenticazione quella di SQL Server e non quella integrata di Windows, l’utente sarà quello di default ‘sa’ con password ‘segreta’ e nome dell’istanza del server sqltest. Aprire il file C:\sql2ksp3\MSDE\setup.ini e modificarlo con i seguenti parametri: [Options] SAPWD="segreta" SECURITYMODE=SQL INSTANCENAME="SQLTEST" Andare da prompt dei comandi nella cartella C:\sql2ksp3\MSDE\ e impostare il comando: setup /settings “C:\sql2ksp3\MSDE\setup.ini” partirà l’installazione di SQL Server Desktop Engine con i parametri memorizzati nel file setup.ini. Terminata l’installazione, è preferibile riavviare il sistema, il servizio di SQL Server partirà automaticamente in background. Non avendo a disposizione Enterprise Manager per gestire il Server SQL, utilizzeremo Access, quindi creiamo un nuovo progetto vuoto che chiameremo registro.adp. Partirà una creazione guidata dove andremo ad inserire i seguenti valori (password=segreta e al posto di DEVMOBILE il nome del vostro computer): JSP – Lezione 6 – L’accesso ai Database 6 Ora possiamo creare le tabelle come se stessimo lavorando con un database di Access, aggiungiamo quindi gli stessi dati del database di MySQL. Prima di poter utilizzare il database da codice Java, abbiamo bisogno dei driver JDBC per SQL Server, è un file .exe che troviamo sul sito Microsoft e contiene sia i file jar che la documentazione. JSP – Lezione 6 – L’accesso ai Database 7 Dopo averli installati copiamo i seguenti file nella directory WEB-INF\lib della nostra Web Application: msbase.jar mssqlserver.jar msutil.jar Ora è tutto pronto, possiamo scrivere il codice Java di connessione a SQL Server. Ripeteremo le stesse operazioni mostrate nell’esempio 6.1, le uniche modifiche da apportare al codice saranno il caricamento del driver: Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver"); e i parametri di connessione al database: Connection cn = DriverManager.getConnection ("jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=registro_online;user=sa ;password=segreta"); e poi grazie a JDBC possiamo lasciare invariato il resto del codice e il tutto funzionerà perfettamente. Le API java.sql È il package che fornisce le interfacce e le classi utili per la gestione dei data source. Sebbene le JDBC API siano utilizzate maggiormente per leggere e scrivere dati da database relazionali, esse forniscono i metodi per accedere a qualsiasi origine dati in formato tabulare. Abbiamo già visto come creare un oggetto Connection che serve per instaurare la connessione fisica al DBMS a seconda al driver caricato. L’interfaccia Statement Qualsiasi comando dovrà essere eseguito tramite l’interfaccia Statement che prevede due metodi principali (in realtà ne mette a disposizione tanti, consultare le API doc di J2SE per un elenco completo): • executeQuery(): permette di effettuare delle operazione di selezione (SELECT) e restituisce un oggetto ResultSet che permette di scorrere i risultati ottenuti. • executeUpdate(): permette di effettuare delle operazioni di inserimento (INSERT) , aggiornamento (UPDATE), o di modifica della struttura del database (CREATE TABLE, CREATE INDEX e così via). Questo metodo restituisce un intero che rappresenta il numero dei record modificati. L’interfaccia ResultSet È l’interfaccia contenente i record restituiti da una query di selezione. Può essere vista come una tabella temporanea residente in memoria che avrà un cursore che, inizialmente, sarà posizionato antecedentemente al primo record restituito. Il metodo next() scorre in avanti il cursore e inoltre restituisce true se il cursore punta ad un record, false se non punta a nessun record. Per prelevare i valori di un campo possiamo utilizzare il metodo: getTipo(String nomeCampo) o getTipo(int indiceColonna) JSP – Lezione 6 – L’accesso ai Database 8 dove Tipo è il tipo di dati restituito tra quelli base (String, Boolean, Byte, Date, Int, Float e molti altri) e indiceColonna è il numero della colonna desiderata (1 per la prima colonna). L’interfaccia PreparedStatement Estende l’interfaccia Statement, e rappresenta una query precompilata. Incrementa le prestazioni se una stessa query deve essere eseguita più volte nella stessa pagina e permette inoltre una maggiore leggibilità del codice. La stringa SQL va passata al momento della creazione dell’oggetto: PreparedStatement stmt = cn.prepareStatement(sql); È possibile parametrizzare i criteri di selezione di una query: SELECT * FROM tabella WHERE userid=? AND password=? E poi passare i parametri con: stmt.setString(1,nome); stmt.setString(2,pwd); Vediamo l’esempio completo con la pagina login_ps.jsp: <%@ page language="java" import="java.sql.*" %> <%@ include file="/Lezione3/Include/funzioni.jsp" %> <html> <head><title>Database</title></head> <body> <h3>Accesso Utenti registrati</h3> <%String nome=request.getParameter("nome"); String pwd=request.getParameter("pwd"); PreparedStatement stmt = null; ResultSet rs = null; //caricamento driver Class.forName("com.mysql.jdbc.Driver"); //apertura connessione Connection cn = DriverManager.getConnection("jdbc:mysql://localhost/registro_online?user=root&p assword=segreta"); String sql="SELECT Cognome, Nome, Tipovia, Indirizzo, NumCivico, cap, citta, prov, tipo_utente.tipoutente, email, telefono "; sql+=" FROM utente INNER JOIN tipo_utente ON utente.idtipo=tipo_utente.idtipo"; sql+=" WHERE UserID= ? AND password= ?"; stmt = cn.prepareStatement(sql); stmt.setString(1,nome); stmt.setString(2,pwd); rs = stmt.executeQuery(); if (rs.next()){ //visualizza dati utente out.write("Cognome : "+rs.getString("cognome")+"<br/>"); out.write("Nome : "+rs.getString("nome")+"<br/>"); out.write("Indirizzo: "+rs.getString("tipovia")+" "+rs.getString("indirizzo")+" "+rs.getString("numcivico")+"<br/>"); out.write("Indirizzo: "+rs.getString("cap")+" "+rs.getString("citta")+" "+rs.getString("prov")+"<br/>"); out.write("E-mail : "+nn(rs.getString("email"))+"<br/>"); out.write("Telefono : "+nn(rs.getString("telefono"))+"<br/>"); out.write("Tipo Utente: "+nn(rs.getString("tipoutente"))+"<br/>"); } else{ JSP – Lezione 6 – L’accesso ai Database 9 // utente non trovato out.write("Utente non trovato <br/> Ripetere la procedura di login"); } stmt.close(); cn.close(); %> <br/><br/> <a href="index.html" title="Torna indietro">Indietro</a> </body> </html> Modifica dati Vediamo ora come utilizzare l’interfaccia PreparedStatement per la modifica dei dati. Il codice completo della pagina esempio6_4.jsp che permette di modificare i dati della tabella utenti: <%@ page language="java" %> <%@ page import="java.sql.*" %> <%@ include file="/Lezione3/Include/funzioni.jsp" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="IT"> <head> <title>Modifica dati</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> </head> <body> <h2>Accesso a un database di MySQL</h2> <h3>Utilizzo della classe PreparedStatement</h3> <form method="post"> <fieldset> <legend>Inserimento dati nuovo utente</legend> <label for="userid">User ID: </label> <input type="text" name="userid" id="userid"> <br/> <label for="password">Password: </label> <input type="password" name="password" id="password"> <br/> <label for="cognome">Cognome: </label> <input type="text" name="cognome" id="cognome"> <br/> <label for="nome">Nome: </label> <input type="text" name="nome" id="nome"> <br/> <label for="tipovia">Tipo Via: </label> <input type="text" name="tipovia" id="tipovia"> <br/> <label for="indirizzo">Indirizzo: </label> <input type="text" name="indirizzo" id="indirizzo"> <br/> <label for="numcivico">N° Civico: </label> <input type="text" name="numcivico" id="numcivico"> <br/> <label for="cap">Cap: </label> <input type="text" name="cap" id="cap"> <br/> <label for="citta">Citt&agrave;: </label> <input type="text" name="citta" id="citta"> JSP – Lezione 6 – L’accesso ai Database 10 <br/> <label for="prov">Provincia: </label> <input type="text" name="prov" id="prov"> <br/> <label for="idtipo">Tipo Utente: </label> <select name="idtipo"> <option value="STU">Studente</option> <option value="INS">Insegnante</option> <option value="GEN">Genitore</option> <option value="ADM">Amministratore</option> </select> <br/> <label for="email">E-Mail: </label> <input type="text" name="email" id="email"> <br/> <label for="telefono">Telefono: </label> <input type="text" name="telefono" id="telefono"> <br/> <label for="cellulare">Cellulare: </label> <input type="text" name="cellulare" id="cellulare"> <br/> <br/> <input type="submit" value="Invia" name="invia"> </fieldset> </form> <% if (request.getParameter("invia")!=null){ String sql; String userid=request.getParameter("userid"); //apertura connessione Class.forName("com.mysql.jdbc.Driver"); Connection cn = DriverManager.getConnection("jdbc:mysql://localhost/registro_online?user=root&p assword=segreta"); //verifica che non ci sia un altro id user sql="SELECT userid FROM utente WHERE userid=" + fc(userid); Statement stmt=cn.createStatement(); ResultSet rs=stmt.executeQuery(sql); if (rs.next()){ // userID esistente (deve essere univoco) out.write("UserID esistente. Immettere un codice identificativo diverso"); } else{ //inserisce i dati sql="INSERT INTO utente (userid,password,cognome,nome,tipovia,indirizzo,numcivico,cap,citta,prov,idtipo ,email,telefono,cellulare) "; sql+=" VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; PreparedStatement stmtIns = cn.prepareStatement(sql); stmtIns.setString(1,userid); stmtIns.setString(2,request.getParameter("password")); stmtIns.setString(3,request.getParameter("cognome")); stmtIns.setString(4,request.getParameter("nome")); stmtIns.setString(5,request.getParameter("tipovia")); stmtIns.setString(6,request.getParameter("indirizzo")); stmtIns.setString(7,request.getParameter("numcivico")); stmtIns.setString(8,request.getParameter("cap")); stmtIns.setString(9,request.getParameter("citta")); stmtIns.setString(10,request.getParameter("prov")); stmtIns.setString(11,request.getParameter("idtipo")); JSP – Lezione 6 – L’accesso ai Database 11 stmtIns.setString(11,request.getParameter("idtipo")); stmtIns.setString(12,request.getParameter("email")); stmtIns.setString(13,request.getParameter("telefono")); stmtIns.setString(14,request.getParameter("cellulare")); stmtIns.executeUpdate(); out.write("Inserimento eseguito con successo"); } rs.close(); cn.close(); } %> </body> </html> L’interfaccia CallableStatement L’interfaccia PreparedStatement oltre che rendere più leggibile il codice, migliora le prestazioni solo se la stessa query viene eseguita più volte nella pagina, mentre tutte le nuove richieste comportano la creazione di un nuovo oggetto PreparedStatement, e ciò non produce alcun miglioramento. Esiste un altro metodo per migliorare le prestazioni: la compilazione di una query a livello di DBMS. Questa tecnica è possibile solo con i database che supportano le stored procedure, ovvero delle query memorizzate e precompilate direttamente dal Database Server. I vantaggi di questa tecnica sono notevoli, qualsiasi chiamata alla procedura SQL sarà eseguita molto più velocemente di una query normale, lo svantaggio è che occupano più spazio e quindi è preferibile usarle solo in caso di selezioni frequenti. In Java è possibile gestire queste funzioni con l’interfaccia CallableStatement che eredita da PreparedStatement. MySQL non gestisce le stored procedure quindi faremo un esempio con SQL Server 2000. Creiamo una stored procedure di nome autenticazione e si occuperà di verificare l’esistenza di un utente nel database. I parametri che accetterà sono la UserID e la password: Create Procedure autenticazione @userid varchar(20), @password varchar(20) AS SELECT Cognome, Nome, Tipovia, Indirizzo, NumCivico, cap, citta, prov, tipo_utente.tipoutente, email, telefono FROM utente INNER JOIN tipo_utente ON utente.idtipo=tipo_utente.idtipo WHERE UserID= @userid AND password= @password GO E ora vediamo l’esempio 6.5 che ci mostra come richiamare una Stored Procedure usando l’interfaccia CallableStatement. <%@ page language="java" import="java.sql.*" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="IT"> <head> <title>Utilizzo di Stored Procedure</title> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /> </head> <body> <h2>Utilizzo di Stored Procedure</h2> JSP – Lezione 6 – L’accesso ai Database 12 <form method="post" > <fieldset> <legend>Login utente</legend> <label for="nome">Inserisci il nome: </label> <input type="text" name="nome" id="nome"> <br/> <label for="pwd">Password: </label> <input type="password" name="pwd" id="pwd"> <br/><br/> <input type="submit" value="Login" name="invia"> </fieldset> </form> <% if (request.getParameter("invia")!=null){ String nome=request.getParameter("nome"); String pwd=request.getParameter("pwd"); CallableStatement stmt = null; ResultSet rs = null; //caricamento driver Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver"); //apertura connessione Connection cn = DriverManager.getConnection("jdbc:microsoft:sqlserver://localhost:1433;Database Name=registro_online;user=sa;password=segreta"); stmt = cn.prepareCall("{call autenticazione(?,?)}"); stmt.setString(1,nome); stmt.setString(2,pwd); rs = stmt.executeQuery(); if (rs.next()){ //visualizza dati utente out.write("Cognome : "+rs.getString("cognome")+"<br/>"); out.write("Nome : "+rs.getString("nome")+"<br/>"); out.write("Indirizzo: "+rs.getString("tipovia")+" "+rs.getString("indirizzo")+" "+rs.getString("numcivico")+"<br/>"); out.write("Indirizzo: "+rs.getString("cap")+" "+rs.getString("citta")+" "+rs.getString("prov")+"<br/>"); out.write("E-mail : "+rs.getString("email")+"<br/>"); out.write("Telefono : "+rs.getString("telefono")+"<br/>"); out.write("Tipo Utente: "+rs.getString("tipoutente")+"<br/>"); } else{ // utente non trovato out.write("Utente non trovato <br/> Ripetere la procedura di login"); } stmt.close(); cn.close(); } %> </body> </html> JSP – Lezione 6 – L’accesso ai Database 13