Java EE 1
Laboratorio di Ingegneria del Software
Andrea Bei
CBD ((Component
p
Based Development)
p
)
interfaccia
„
componente
La definizione secondo il glossario "UML-User Guide" :
"Un componente è una parte fisica e sostituibile di un sistema che
implementa un insieme di interfacce."
… L’implementazione (classi utilizzate) è nascosta
…
„
Lo sviluppo a componenti incrementa la qualità del SW
…
„
Ovvero: Manutenibilità, Leggibilità, Riusabilità, Portabilità,
Affidabilità
Applicazioni progettate secondo il paradigma a componenti
sono chiamate component-based
2
Application Server (AS)
„
Le applicazioni component based possono essere installate in
component container ( o più semplicemente container)
„
Un AS è costituito da un insieme di container per componenti di
diverso tipo (EJB Container, WEB Container, WEB Server)
„
Lo scopo principale di un container è gestire il ciclo di vita dei
componenti (creazione, distruzione, pooling, passivazione, …)
„
Tra gli altri principali servizi offerti dagli application server
…
…
…
…
„
Gestione
Gestione
Gestione
Gestione
dello stato
della sicurezza
dell’accesso ai dati
delle transazioni
Per essere installato (il termine corretto è deploy) su un AS un
componente deve aderire ad opportune specifiche
3
Applicazioni di classe Enterprise
„
Sono sistemi informatici utilizzati in medie o grandi organizzazioni a
supporto di sistemi informativi critici. Ad esempio:
…
…
…
„
ERP (Enterprise Resource Planning): Contabilità, Personale, Inventario,
.Controllo di gestione
C
CRM
(C
(Customer Relationship
l i
hi Management):
) sistemi
i
i per lla gestione
i
d
deii
clienti, dei contatti ed il tracciamento degli eventi associati ai clienti
SRM (Service Request Management): gestione e processamento di richieste
Una applicazione
U
li
i
di classe
l
E
Enterprise
t
i d
deve avere lle seguenti
ti
caratteristiche:
…
Performante: deve servire più richieste concorrenti (multiuser) in maniera
efficiente. Tale caratteristica si ottiene attraverso i servizi di caching e
pooling.
pooling
…
Distribuita: i componenti devono poter essere distribuiti su server diversi
…
Scalabile: ll’applicazione
applicazione deve garantire il mantenimento dei tempi di
risposta all’aumentare degli utenti concorrenti. (ad es: deve essere
possibile scalare orizzontalmente mediante il clustering)
…
Sicura: gli utenti devono essere autenticati e autorizzati
Affidabile
Portabile
Transazionale
…
…
…
4
Java EE
„
Java Enterprise Edition è un insieme di tecnologie e API
„
Supporta un approccio component-based per la progettazione, lo
sviluppo, l’assemblaggio
l assemblaggio e la messa in esercizio di applicazioni di classe
enterprise
„
Definisce le specifiche per i vendor di application server Java EEcompliant
„
Comprende le seguenti principali tecnologie/API
…
…
…
…
…
…
…
…
…
…
…
…
…
…
JSP Java Server Pages
JSF Java Server Faces
Java Servlets Servlet API
Web Services
EJB Enterprise JavaBeans
JNDI Java Naming and Directory Interface
JDBC 2.0
2 0 Extensions
E t
i
J
Java
Database
D t b
Connectivity
C
ti it Extensions
E t
i
RMI-IIOP RMI over Internet Inter-Orb Protocol
JMS Java Message Service
Java Mail Java Mail
JAF JavaBeans Activation Framework
JTA Java Transaction API
XML Extensible Markup Language
JMX Java Management Extensions
5
Application Server
„
Tra gli application server Java EECompliant più conosciuti:
… IBM
WebSphere
… Oracle WebLogic Server
… JBoss (Open Source)
… Glassfish (Open Source)
… Tomcat (Open Source)
„
Tutti gli AS elencati sopra sono dotati di
Web Container + EJB Container tranne
Tomcat
6
Componenti e strati Java EE
„
„
„
La piattaforma Java EE supporta il pattern architetturale Layer
Il numero di Layer (o Tier) adottati è una scelta di progettazione
Un modello classico di applicazione Java EE prevede almeno 4 Layer
I – Presentazione o Client Tier:
Componenti client:
„
Applicazioni e Thin Client (CL)
„
HTML (CL)
II – Applicazione o Web Tier
Componenti Web:
„
Servlet JSP JSF JavaBean,
Servlet,JSP,JSF,
JavaBean
POJO (AS)
III - Logica di business o Business
Tier Componenti di business:
„
EJB (Enterprise Java Bean) e
POJO (AS)
IV – Persistenza o EIS Tier
Componenti EIS (Enterprise Information Systems)
„
I sistemi per la persistenza dei dati DB, ORM (Object Relational Mapping)
7
Componenti e strati J2EE
„
„
Un modello completo prevede la suddivisione del layer logica di
business nei due layer Servizi e Dominio. Si ottengono 5 Layer
Tale modello è molto diffuso ed è quello di riferimento per il
corso
Livello
Responsabilità
Tecnologia
Presentazione
User Interface
p
Client
Componenti
HTML/Javascript/Swing
Applicazione
sintassi,interazione con lo strato
dei servizi
servizi, workflow degli use
case (Controller di sessione)
Componenti Web Servlet, JSP,
JSF JavaBean
JSF,
Servizi
transazioni, logica di business e di
workflow
Componenti di Business
EJB (Session bean) e POJO
D i i
Dominio
ti
modello
d ll di d
dominio,
i i
semantica,
logica business di dominio
Componenti
C
ti di Business
B i
(EJB) Entity bean e POJO
Persistenza
Accesso e gestione dati
Componenti EIS
RDBMS/ODBMS/ORM
8
Componenti e strati J2EE
„
E’ possibile usare l’architettura di riferimento in maniera
flessibile. Es:
…
Unire differenti strati logici usando una sola tecnologia.
„
…
Applicazione Web con strati di servizio e dominio realizzati con
semplici JavaBean. Non vengono utilizzati EJB nel Business Tier
Usare solo un sottoinsieme degli strati
„
Applicazione Client
Client-Server
Server senza l’utilizzo
l utilizzo del Web Tier. Lo strato di
presentazione è realizzato con classi Swing, gli strati di
applicazione, servizio, dominio sono realizzati con EJB o semplici
JavaBean
9
„
Sfruttando le tecnologie offerte dalle piattaforme Java SE+
Java EE è possibile sviluppare applicazione con caratteristiche
"Enteprise"
Le tecnologie fondamentali sono: JDBC, Servlet, JSP, EJB,
JNDI
Presentazione
J2EE Application Server
Applicazione
Persistenza
JDBC
„
Componenti e strati J2EE
Servizi
Dominio
JNDI
10
Il percorso didattico
Presentazione
Persistenza
Architettura "semplice"
1.
2
2.
Presentazione
Presentazione
JDBC
Servlet
Persistenza
J2EE Application Server
Architettura "media" complessità
1.
JSP
2.
MVC
Persistenza
Architettura completa:
1.
EJB
2.
JNDI
„
„
Gli strati di applicazione, servizi e dominio sono implementati dalle tecnologie
presenti nel tier 2
11
A destra gli argomenti che sono via via spiegati a partire dalla architettura "semplice"
„
Architettura "semplice", Lo strato di
presentazione
t i
Presentazione (Client Tier)
… Browser
„
(Thin Client)
Interpreta le pagine HTML generate
dinamicamente dai componenti
p
web
… Applet
(Thin/Thick Client)
Piccole applicazioni Java realizzate mediante le
API Swing
„ Sono eseguite all’"interno"
all interno del browser (su una
JVM associata al browser)
„ Sono classi che estendono java.applet.Applet o
javax swing JApplet
javax.swing.JApplet
„
12
„
Lo strato di persistenza
P
Persistenza
i t
(EIS Ti
Tier))
… E’
lo strato responsabile della persistenza dei dati.
…E
E’ implementato da sistemi EIS (Enterprise
Information System). Questi possono essere:
„
„
DBMS (relazionali (RDBMS), a oggetti (ODBMS), …)
Sistemi ORM (Object Relational Mapping) (es: Hibernate)
…
„
creano una rappresentazione a oggetti di dati memorizzati in
database relazionali
Sistemi Informativi p
preesistenti ((Sistemi Legacy)
g y)
… Nel
caso comune in cui il sistema EIS coincide con
un RDBMS la comunicazione tra lo strato di
business (servizio + dominio) e lo strato di
persistenza avviene mediante JDBC
13
JDBC
„
„
„
JDBC (Java DataBase Connectivity) è una API per
l’accesso a DataBase relazionali
Permette ad applicazioni JAVA di eseguire istruzioni SQL
su database relazionali e gestire i risultati restituiti.
JDBC definisce delle classi per rappresentare:
…
…
…
…
„
„
connessioni a database
istruzioni SQL
result sets (insieme dei record restituiti da una Query SQL)
database metadata ((dati che descrivono la struttura del DB),
),
ecc.
è organizzata in diversi "strati": l’applicazione vede solo
lo strato superiore, che è indipendente dal database che
viene interrogato
il compito di interfacciarsi effettivamente con il
database è delegato ad una serie di driver sottostanti,
che possono essere scritti in codice Java o nativo.
nativo
14
JDBC
Presentazione
Applicazione
li
i
Servizi
Dominio
Persistenza
15
ODBC
„
ODBC (Open DataBase Connectivity) è una API
Microsoft per l’accesso a RDBMS
„
Nei sistemi operativi Microsoft è presente il Data Source
Administrator che permette di dichiarare al sistema
operativo le fonti dati ODBC usate
„
Una fonte dati ODBC è caratterizzata da:
… un
… un
nome: il DSN (Data Source Name)
driver ODBC per la comunicazione con il DBMS (Oracle, SQL
Server, Access)
… il riferimento ad un database (il nome del DB)
„
Le applicazioni instaurano una connessione con il
database riferendosi al nome della fonte dati ODBC
relativa
relativa.
16
„
JDBC
JDBC-ODBC Bridge Driver:
… implementa un "ponte" di comunicazione tra JDBC e ODBC;
… Permette ad applicazioni
pp
JAVA ((tramite JDBC)) di accedere a
database registrati via ODBC
„
„
API Native: convertono chiamate JDBC in chiamate alle
API proprietarie dei vari DBMS (Oracle, Sybase,
Informix DB2
Informix,
DB2, Postgres,
Postgres MySQL)
Driver 100% JAVA
Basati su un protocollo indipendente dal DBMS (JDBC-Net):
traducono le chiamate JDBC in un protocollo indipendente dal
DBMS. Tale protocollo viene poi ritradotto da un server nel
protocollo specifico del DBMS. Il server permette di connettere
una applicazione sviluppata interamente in JAVA ai vari DBMS.
… Basati
B
ti sull protocollo
t
ll del
d l DBMS:
DBMS traducono
t d
le
l chiamate
hi
t JDBC nell
protocollo usato dal DBMS. Questo permette una chiamata
diretta dal client al server DBMS
…
17
JDBC
18
JDBC: Classi, interfacce e metodi principali
„
Classe java.sql.DriverManager:
Cl
j
lD i
M
ffornisce
i
lle ffunzionalità
i
lità base
b
di un
gestore di driver. I metodi sono:
…
…
…
…
…
…
„
Connection getConnection(url,user,password): crea una connessione con un DB
void setLoginTimeout(int): imposta il timeout di connessione
i t getLoginTimeout():
int
tL i Ti
t() restituisce
tit i
il ti
timeoutt di connessione
i
setLogStream( PrintStream ): imposta lo Stream di log
PrintStream getLogStream(): accede allo Stream di Log
void println(String): scrive un messaggio sul Log
Interfaccia java.sql.Connection: rappresenta una connessione con uno
specifico database. I metodi sono:
…
…
…
…
…
…
void close(): chiude la connessione
Statement createStatement(): crea e restituisce un oggetto di tipo Statement
DatabaseMetaData getMetaData(): restituisce informazioni sulla struttura del
database
setAutoCommit(boolean): indica se presente o no l’autocommit (default=true)
commit():
it() rende
d effettive
ff tti
le
l iistruzioni
t
i i SQL eseguite
it d
dall’ultimo
ll’ lti
commit
it
rollback(): annulla le istruzioni SQL eseguite dall’ultimo commit
19
JDBC: Classi, interfacce e metodi principali
„
Classe java.sql.Statement:
java sql Statement: un oggetto di tipo Statement è usato
per eseguire delle istruzioni SQL. I metodi sono:
…
…
…
…
…
…
„
ResultSet executeQuery( String ): esegue una Query SQL. Restituisce
un oggetto di tipo ResultSet che rappresenta il risultato della Query
int executeUpdate( String ): esegue una istruzione SQL che modifica la
struttura o i dati del database( CREATE, INSERT, ecc..). int è il numero
di righe modificate
boolean execute( String ): esegue un comando SQL di interrogazione o
modifica
ResultSet getResultSet(): restituisce il risultato dell’ultima istruzione
SQL eseguita con execute (null se l’istruzione era di modifica)
int getUpdateCount(): restituisce il numero di righe coinvolte
nell’ultima istruzione SQL eseguita con execute.
void
o d setQueryTimeout(int)
se Que y
eou (
) e int ge
getQueryTimeout():
Que y
eou () accesso a
al timeout
eou
Classe java.sql.ResultSet: un oggetto di tipo ResultSet rappresenta
il risultato di una Query. I metodi sono:
…
…
…
…
getXXX("Nome Campo") con XXX=Float,String,Byte,Short;Long …..
Restituisce
est tu sce del
de record
eco d corrente
co e te il valore
a o e del
de campo
ca po passato come
co e
argomento
next() : Aggiorna il puntatore al record corrente facendolo avanzare di
un record
in JDBC2.0 ci sono anche: absolute(int), relative(int) e previous()
20
Connessione con un DBMS
JDBC ODBC Driver / API Native
JDBC-ODBC
Per effettuare una connessione con un DBMS è necessario:
„ Effettuare l’import delle classi del package java.sql
„ Caricare il driver di accesso a DB con ll’istruzione
istruzione
Class.forName(<path completo della classe che implementa il driver>);
individua carica ed esegue il link della classe passata come
parametro
„
Instaurare la connessione con il DBMS con l’istruzione:
Connection con = DriverManager.getConnection(url, <login>,
<password>);
url è di tipo String ed ha la sintassi "jdbc:<subprotocol>:<subname>"
dove:
<subprotocol>: è il sottoprotocollo (es: odbc)
< b
<subname>:
> serve ad
d identificare
id tifi
la
l sorgente
t dei
d i dati.
d ti
21
„
Connessione con un DBMS
esempi
Es: connessione con il DBMS Access libreria.mdb associato ad una fonte
dati ODBC chiamata "libreria" con login="libreria" e password="libreria"
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
l
f
(
jdb
db
db db
i
)
String url="jdbc:odbc:libreria";
Connection con =DriverManager.getConnection(url, "libreria",
"libreria");
„
Es: connessione con il DBMS open source Postgres "mynewdb" sulla
macchina 192.168.0.3 (www.postgresql.org)
Class.forName(
Cl
f N
( "org.postgresql.Driver"
"
t
l D i
" )
);
String url = "jdbc:postgresql://192.168.0.3/mynewdb";
Connection con = DriverManager.getConnection( url, USER , PASS );
22
Connessione con un DBMS esempi
„
Es: connessione con db Oracle
1.
Copiare i file contenenti i driver (scaricabili dal sito Oracle) classes12.zip,
jndi.zip in $ORACLE_HOME/jdbc/lib/
2.
aggiornare il CLASSPATH inserendo
"$ORACLE_HOME/jdbc/lib/classes12.zip:$ORACLE_HOME/jdbc/lib/jndi.zip"
1.
Eseguire la connessione al DataBase
Class.forName("oracle.jdbc.driver.OracleDriver");
String
url="jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=150.146.1.98)
(PORT=1521))(CONNECT_DATA=(SID=ID_DB)))";
Connection con =DriverManager.getConnection(url, "login", "password");
23
Istruzioni SQL
Stabilita una connessione è possibile eseguire istruzioni SQL
„
…
creare un oggetto di tipo Statement. Se la connessione è descritta
dall’oggetto con l’istruzione è:
Statement stmt = con.createStatement();
…
invocare i metodi dell’oggetto Statement:
„
int executeUpdate("<istruzione
executeUpdate( <istruzione SQL>
SQL>"):
): per istruzioni di tipo CREATE,
DROP, DELETE, INSERT, UPDATE
stmt.executeUpdate("create table Anagrafica"+
"( Nome varchar(32)," +
" Cognome
varchar(32))");
„
ResultSet executeQuery("<istruzione SQL>") è usato per query
stmt.executeQuery("select
Q
y(
* from Libro"+
" where Titolo like \"Moby Dick%\" ");
24
Accesso al risultato delle query
„
Il metodo executeQuery restituisce un oggetto di tipo ResultSet
„
Un ResultSet è l’insieme di record che costituiscono il risultato di
una query.
Su quest’insieme viene mantenuto un puntatore alla posizione
corrente.
…l p
puntatore viene p
posto sul p
primo record alla p
prima invocazione del
metodo next.
…
String query = "SELECT Titolo, ISBN FROM Libro";
ResultSet rs = stmt
stmt.executeQuery(query);
executeQuery(query);
while (rs.next()) {
String s = rs.getString("Titolo");
String c = rs.getString("ISBN");
System out println(s + "
System.out.println(s
" + c);
}
25
Esempio
p
import java.sql.*;
class provaJDBC {
public static void main(String arg[]) throws Exception
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
String url="jdbc:odbc:libreria";
Connection con=DriverManager.getConnection(url,"libreria","libreria");
Statement stmt = con.createStatement();
stmt.executeUpdate("create table Anagrafica"+
( Nome varchar(32),"
( ), +
"(
" Cognome varchar(32))");
stmt.executeUpdate("insert into Anagrafica values (‘Giacomo’,’Leopardi’)");
ResultSet rs=stmt.executeQuery("select Nome,Cognome from Anagrafica");
while (rs.next())
(rs next())
{
System.out.println(rs.getString("Nome")+"
"+rs.getString("Cognome"));
}
}}
26
Prepared statement
„
„
„
„
è una istruzione SQL precompilata dal DBMS
l’esecuzione di una query è più efficiente (si
risparmia il passo di compilazione del DBMS)
conviene quando occorre eseguire molte volte la
stessa query
e’’ possibile
ibil il passaggio
i di parametrii
PreparedStatement updateSales =
con.prepareStatement( "UPDATE COFFEES
SET SALES = ? WHERE COF_NAME LIKE ? ");
updateSales.setInt(1, 75);
updateSales.setString(2, "Colombian");
int n=updateSales.executeUpdate();
(1) creazione:
i parametri sono
specificati con "?"
(2) passaggio
parametri:
posizionale
(3) esecuzione
g
n=numero di righe
modificate
27
Prepared statement
PreparedStatement updateSales;
String updateString = "update COFFEES " + "set SALES =
? where COF_NAME like ?";
updateSales
d t S l
= con.prepareStatement(updateString);
St t
t( d t St i )
int [] salesForWeek = {175, 150, 60, 155, 90};
String [] coffees = {"Colombian", "French_Roast",
"Espresso", "Colombian_Decaf", "French_Roast_Decaf"};
int len = coffees
coffees.length;
length;
for(int i = 0; i < len; i++)
{
updateSales.setInt(1, salesForWeek[i]);
updateSales.setString(2, coffees[i]);
updateSales.executeUpdate();
}
28
Transazioni
„
una transazione è un insieme di operazioni su un database
che soddisfa le seguenti proprietà (ACID)
1.
Atomicity
…
2.
Consistency:
…
3.
l’esecuzione della transazione fa transitare il db da uno stato
consistente ad un altro stato consistente (durante l’esecuzione è
possibile la "non consistenza"))
p
Isolation
…
4
4.
le operazioni vengono eseguite in modo atomico
"tutte a buon fine o nessuna"
le transazioni concorrenti sono isolate l’una dall’altra. L’una non
deve vedere i dati che l’altra sta modificando.
Durability
…
i dati sopravvivono a crash. Esiste un log transazionale che registra
tutte le operazioni eseguite sul db. E’ possibile risalire ad un punto
di consistenza.
29
Transazioni
„
„
I comandi
di classici
l
i id
deii DBMS per la
l gestione
ti
delle
d ll transazioni
t
i i
sono:
COMMIT
…
…
„
rende definitivo sul DB ciò che è stato fatto dalla transazione
chiude la transazione
ROLLBACK
…
annulla sul DB ciò che è stato fatto dalla transazione.
…
riporta il DB allo stato consistente in cui era prima che iniziasse
la transazione
…
per soddisfare la Atomicity e la Consistency viene eseguito se una
d ll operazioni
delle
i id
della
ll ttransazione
i
non va a b
buon fine
fi
30
Transazioni ed eccezioni
disabilito ’AutoCommit
try {
t
con.setAutoCommit(false);
PreparedStatement updateSales = con.prepareStatement(
"UPDATE COFFEES SET SALES = ?
se arrivo qui le operazioni
WHERE COF NAME LIKE ?");
?")
SQL sono andate
d t a buon
b
updateSales.setInt(1, 50);
fine. eseguo il COMMIT e
updateSales.setString(2, "Colombian");
chiudo la transazione.
updateSales.executeUpdate();
PreparedStatement updateTotal = con.prepareStatement(
"UPDATE COFFEES SET TOTAL = TOTAL + ? WHERE COF_NAME LIKE
?");
updateTotal.setInt(1,
pdateTotal setInt(1 50);
50)
updateTotal.setString(2, "Colombian");
se qualche operazione
updateTotal.executeUpdate();
SQL non va a buon fine
con.commit();
viene catturata
con setAutoCommit(true)
con.setAutoCommit(true);
l’
l’eccezione.
i
}
eseguo il ROLLBACK e
catxh (SQLException e){
annullo la transazione
if (con!=null) con.roolback()}
31
Es: sito WEB di una catena di librerie
„
„
„
Ogni libreria possiede un accesso WEB
Il fornitore del servizio fornisce un WEB Server che pubblica su WEB i
dati relativi ai libri venduti (Autore, Titolo, Prezzo, Disponibilità nei vari
punti vendita, ecc.)
I dati sui libri e sulla loro disponibilità vengono inseriti da un operatore
di ogni libreria in base ai libri acquistati e venduti
Cliente
libreria 1
libreria 2
Application
DBMS Server
Internet
lib i N
libreria
32
Esempio: sito WEB di una catena di libreri
Use Case Diagram
g
33
Esempio: sito WEB di una catena di librerie
nome
Prezzo
Titolo
Editore
Anno
copie
Cod libreria
LIBRERIA
LIBRO
(1,1)
GENERE
(1 1)
(1,1)
(1,n)
(1,n)
(1,1)
ISBN
C d
Cod_genere
G
Genere
Schema ER
( può essere fatto
in UML !)
(1,n)
AUTORE
Cod_autore
Cognome
Nome
Anno di nascita
Luogo di nascita
34
Esempio: sito WEB di una catena di libreri
Architettura Applicativa (Package Diagram)
„
Strato di dominio
…
In questo caso è un semplice Facade verso il DB. Deve:
„
„
…
E’ composto da
„
„
„
„
Incapsulare le istruzioni (SQL) di comunicazione con il DB
Offrire al livello superiore metodi indipendenti dal paradigma relazionale
classi dette "DAO"
DAO (Data Access Object): incapsulano la logica di
connessione e le istruzioni SQL (in questo caso una sola)
classi dette Value Objects o DTO (Data Transfer Object) sevono per
rappresentare "a oggetti" i dati relazionali
Strati di
d servizio/applicazione
/
l
Strato di persistenza (un db MS Access)
Servizio/
Applicazione
Dominio
Persistenza
35
Esempio: sito WEB di una catena di
librerie
Class Diagram
Dominio
DAO
Value
Obj t
Objects
36
Esempio: sito WEB di una catena di librerie
I metodi principali della classe Libreria
„
„
„
„
„
„
„
„
public Libreria(fonteDatiODBC, userODBC, passwordODBC): costrutt.
public Collection ricercaPerGenere(String genere): restituisce una
Collection di oggetti di tipo Libro con il genere passato come parametro.
public Collection ricercaPerAutore(String nome): restituisce una
Collection di oggetti di tipo Libro scritti dall’autore passato come param.
public Collection ricercaPerTitolo(String titolo):restituisce una
Collection contenente gli oggetti di tipo Libro che hanno il titolo passato
come parametro.
public void inserisciLibro(Libro l): insert nel database dei dati
gg
Libro
dell’oggetto
private int inserisciAutore(Autore a): insert nel database dei dati
dell’oggetto Autore. Ritorna il codiceAutore, un numero che identifica
univocamente l’autore.
public void aggiornaCopie(String
p
gg
p (
g ISBN,String
,
g lib,int
,
copie):
p )
Aggiorna le copie del libro ISBN della libreria lib. Copie può essere
positivo o negativo
public Libro getSchedaLibro(String ISBN): restituisce l’ oggetto di
tipo Libro che ha come ISBN il codice passato come parametro
37
Implementazione:il DB Access libreria.mdb
AUTORE
Cod_autore
Cognome
0 Melville
1 Hesse
H
3 Dick
4 Hofstader
5 Russel
6 Pirsig
7 Clarke
Nome
Herman
H
Herman
Philip
Douglas
Bertrand
Robert
Arthur
COPIE
Libreria
1
1
1
2
2
3
ISBN
88-347-0098-8
88-450-0701-1
88 460 0739 2
88-460-0739-2
88-450-0701-1
88-459-0699-X
88-459-0734-1
Anno di nascita
1819
1847
1920
1945
1872
1928
1917
Luogo di nascita
New York
E
Estonia
i
New York
New York
New York
Minnesota
Inghilterra
LIBRERIA
Copie
10
16
30
15
20
40
Cod_Libreria
Nome
1 Feltrinelli
2 Apogeo
A
3 Ricordi
38
Implementazione:il DB Access libreria.mdb
LIBRO
ISBN
88-347-0098-8
88-450-0701-1
88-459-0468-7
88-459-0699-X
88-459-0734-1
88-459-0755-4
88-459-1095-4
88-460-0739-2
88-7819-669-X
Titolo
Ubik
Storia della filosofia occidentale
Amicizia
Knulp
Lo Zen e l'arte della manutenz…
Goedel, Escher, Bach
Moby Dick
Lila
2001: Odissea nello spazio
Editore Anno Cod_autor Cod genere
Fanucci
1969
3
2
Mondadori 1977
5
0
Newton
1920
1
1
Newton
1915
1
1
Adelphi
1974
6
1
Adelphi
1992
4
0
Adelphi
1851
0
1
Adelphi
1985
6
1
Mondadori 1968
7
2
Prezzo
L 20
L.
20.000
000
L. 15.000
L. 5.000
L. 5.000
L. 18.000
L. 20.000
L. 18.000
L. 15.000
L. 16.000
GENERE
Cod_genere
Cod
genere
0
1
2
3
Genere
Saggio
Romanzo
Fantascienza
Giallo
39
Value Objects: Libro
class Libro {
String ISBN;
String titolo;
String editore;
int anno;
Autore autore;
String genere;
int prezzo;
// serve ha mantenere tutte le informazioni di
//un Libro compreso i dettagli sull’autore
Libro (String ISBN, String titolo, String editore, Int anno,
Autore autore, String genere, Int prezzo) {
this.ISBN=ISBN;
this titolo titolo
this.titolo=titolo;
..
this.autore=autore;
}
public String getISBN()
{ return ISBN;}
public void setISBN(String ISBN)
{ this
this.ISBN=ISBN;}
ISBN ISBN } ...
40
Value Objects: Autore
class Autore {
// serve ha mantenere tutte le informazioni
// su un autore
String nome;
String
g cognome;
g
;
int dataDiNascita;
String luogoDiNascita;
g nome,
, String
g cognome,
g
, int dataDiNascita,
,
Autore (String
String luogoDiNascita)
{
this.nome=nome;
this.cognome=cognome;
g
g
;
...
}
public String
p
g getNome()
g
{ return nome;}
public void setNome(String nome)
{ this.nome=nome;}
}
...
41
Libreria: implementazione del
costruttore
import java.sql.*;
import java.io.*;
class Libreria
{
Connection con=null;
Statement stmt=null;
String fonteDatiODBC=null;
fonteDatiODBC null;
String userODBC=null;
String passwordODBC=null;
import java.util.*;
Libreria(String fonteDatiODBC
fonteDatiODBC,String
String userODBC
userODBC, String passwordODBC)
// costruttore
{
this.fonteDatiODBC= fonteDatiODBC;
this userODBC= userODBC;
this.userODBC=
this.passwordODBC= passwordODBC;
}
42
Libreria:implementazione di metodi di
utilità
...
private ResultSet executeQuery(String Query)
{ // questo metodo serve solo per catturare le eccezioni del metodo
// executeQuery
ResultSet rs=null;
try
{ rs=stmt.executeQuery(Query); }
catch(SQLException e)
{
System.out.println("Problemi con l'esecuzione della Query SQL: "+
Query);}
return(rs);
}
43
Libreria:implementazione di metodi di
utilità
private void createConnection() {
try
{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
// carico il driver JdbcOdbc
} catch(ClassNotFoundException
p
e)
{ System.out.println("Driver Jdbc-Odbc non presente"+e.getMessage()); }
String url="jdbc:odbc:"+fonteDatiODBC;
Try
{
con = DriverManager.getConnection(url, userODBC, passwordODBC); //eseguo la connessione
stmt=con.createStatement();
// creo un oggetto di tipo Statement
} catch(SQLException e) {
System.out.println("Problemi
i l (
bl i nella
ll apertura di sessione
i
con la
l fonte
f
dati
d i "+
fonteDatiODBC+"\n"+"verificare l'esistenza della fontedati e la correttezza di User e
Password");} }
private void closeConnection() {
C
Con.close();
l
()
Con=null;
Stmt=null}
44
Libreria:implementazione di ricercaPerGenere
public Collection ricercaPerGenere(String genere) {
createConnection();
String Query="SELECT ISBN,Titolo,Editore,Anno,Genere,Prezzp,
"
Cognome,Nome,Anno_di_Nascita,"
"
Luogo_di_Nascita "+
"FROM G
Genere, Lib
Libro , A
Autore"+
t
"
"WHERE Genere.Cod_genere=Libro.Cod_genere "+
"AND Genere.genere = '"+genere+"'"+
"AND Libro.cod_autore=Autore.cod_autore";
Collection a = new ArrayList();
ResultSet rs=null;
rs=executeQuery(Query);
try {
while (rs.next()) {
Autore autore=
new Autore(rs.getString(7),rs.getString(8), rs.getString(9), rs.getString(10));
Libro libro=
new Libro(rs.getString(1),rs.getString(2),rs.getString(3),rs.getString(4),
rs.getString(5), rs.getString(6),autore);
a.add(libro);
}
} catch(SQLException e) {System.out.println("Errore nella navigazione del
ResultSet");}
closeConnection();
return a;}
45
Libreria: implementazione di inserisciAutore
private int inserisciAutore(Autore a) { // la classe Autore ha solo metodi setter e
createConnection();
// getter per le variabili cognome, nome,
int cod_autore=0;
// annoDiNascita, luogoDiNascita
String query="SELECT * "+
// verifico se l’autore è già presente
"FROM Autore "+
WHERE Nome='"+a
Nome= +a.getNome()+
getNome()+"' and Cognome='"+a
Cognome= +a.getCognome()+
getCognome()+"’";
;
"WHERE
try {
ResultSet rs=executeQuery(Query);
if (rs.next()) {
cod_autore=rs.getInt("Cod_autore");
closeConnection();
return(cod_autore);
// se è gia presente retituisco il codice relativo
}
query="SELECT MAX(Cod_autore) FROM Autore";
// altrimenti seleziono il massimo Cod autore
ResultSet rs=executeQuery(Query);
rs executeQuery(Query);
rs.next();
cod_autore=rs.getInt(1)+1;
// il nuovo Cod_autore è il max + 1
Query="INSERT INTO AUTORE (cod_autore,Cognome,Nome,Anno_di_nascita,Luogo_di_nascita) "+
" VALUES ("+cod_autore+",'"+a.getCognome()+"','"+a.getNome()+"',"+
a getAnnoDiNascita()+" '"+a getLuogoDiNascita()+"')"
a.getAnnoDiNascita()+",'"+a.getLuogoDiNascita()+"')";
int rc=executeUpdate(Query);
} catch(SQLException e)
{System.out.println("Errore nella navigazione del ResultSet");}}
closeConnection();}
46
Libreria: implementazione di inserisciLibro
public void inserisciLibro(Libro l) { // la classe Libro ha solo metodi
createConnection();
// setter e getter per le variabili ISBN,Titolo, .
String stmt="SELECT * "+
"FROM Libro "+
g
();
"WHERE ISBN='"+l.getISBN();
try {
ResultSet rs=executeQuery(stmt);
if (!rs.next())
// se non è gia presente lo inserisco
{
stmt="SELECT
st
t S
C Cod Ge
Genere)
e e) "+
// se
seleziono
e o o il cod
codice
ce genere
ge e e dalla
da a descrizione
desc
o e
" FROM Genere"+
// suppongo che i generi siano precaricati nel DB
" WHERE Genere.Genere="+l.getGenere();
ResultSet rs=executeQuery(stmt);
rs.next();
int codGenere=rs.getInt(1);
codGenere rs.getInt(1);
int codAutore=inserisciAutore(L.getAutore()); //inser. l’autore se manca o ricavo il
codice
stmt="INSERT INTO Libro (ISBN,Titolo,Editore,Anno,Cod_Autore,Cod_Genere,Prezzo)"+ "
VALUES
("+l.getISBN()+","+l.getTitolo()+","+l.getEditore()+","+l.getAnno()+","+codAutore+
" "+codGenere+" "+l getPrezzo()+")"
","+codGenere+","+l.getPrezzo()+")";
int rc=executeUpdate(stmt);
} catch(SQLException e) {System.out.println("Errore nella navigazione del
ResultSet");}}
closeConnection();}
47
Libreria: implementazione di
gg
p
aggiornaCopie
public void aggiornaCopie(String ISBN,String lib,int copie)
{
createConnection();
// ricavo il codice libreria
String
i
stmt= "SELECT Cod
d Libreria
ib
i "+
"FROM Libreria "+
"WHERE Libreria.Nome="+lib;
try {
ResultSet rs=executeQuery(stmt);
Q
y(
);
rs.next();
int codLibreria=rs.getInt(1);
String stmt="UPDATE Copie SET Copie = Copie+"+copie+
" WHERE ISBN='"+ISBN+"' AND"+
"
Libreria
Libreria="+codLibreria;
"+codLibreria
if (executeUpdate(stmt)==0) // il negozio non aveva nemmeno una copia
{
// inserisco una riga con il numero di copie
stmt="INSERT INTO Copie ( ISBN, Libreria, Copie ) "+
"VALUES('"+ISBN+"',"+lib+","+copie+")";
int rc=executeUpdate(stmt);
}} catch(SQLException e)
{System.out.println("Errore nella navigazione del ResultSet");}
closeConnection();}
48
Un esempio di uso della classe
Libreria
import java.sql.*; import java.io.*;import java.util.*;
import Libreria;
import Libro;
import Autore;
class provaJDBC{
public static void main(String args[])
throws Exception
{
Libreria l=new Libreria("libreria","libreria","libreria");
System.out.println(" prima dell’inserimento ");
Collection c=l.ricercaPerGenere("Romanzo");
Iterator i = c.iterator();
while (i.hasNext()) {
Libro libro = (Libro)i.next();
System.out.println(libro.getTitolo()+" "+ libro.getISBN());
}
Autore autore=new Autore();
autore.setCognome("Pennac");
(
)
autore.setNome("Daniel");
autore.setAnnoDiNascita(1944);
autore.setLuogoDiNascita("Casablanca");
49
Un esempio di uso della classe
Libreria
Libro lib=new Libro();
lib.setISBN("88-07-70072-7");
lib.setTitolo("Signor Malaussene");
lib.setEditore("Feltrinelli");
lib.setAnno(1995);
lib.setGenere("Romanzo");
lib.setPrezzo(20.000);
lib setAutore(autore) ;
lib.setAutore(autore)
l.inserisciLibro(lib);
System.out.println(" dopo l’inserimento ");
c=l.ricercaPerGenere("Romanzo");
Iterator i = c.iterator();
while (i.hasNext()) {
Libro libro = (Libro)i.next();
System.out.println(libro.getTitolo()+" "+
libro.getISBN());
}
}
}
50
Esecuzione di provaJDBC
p
J
C:\jdk1.3.1_03>java provaJDBC
prima dell'inserimento
Lo Zen e l'arte della manutenzione della motocicletta 88-459-0734-1
Lila 88-460-0739-2
Moby Dick 88-459-1095-4
Knulp 88-459-0699-X
88 459 0699 X
Amicizia 88-459-0468-7
dopo l'inserimento
Lo Zen e l'arte della manutenzione della motocicletta 88-459-0734-1
Lila 88-460-0739-2
Moby Dick 88-459-1095-4
Knulp 88-459-0699-X
Amicizia 88-459-0468-7
Signor Malaussene 88-07-70072-7
C:\jdk1.3.1_03>
51
Impostazione della fonte dati
"libreria"
libreria
1)
Add di una nuova fonte dati dal Data Source Administrator
52
Impostazione della fonte dati
"libreria"
libreria
2) si seleziona il Driver per Access
53
Impostazione della fonte dati
"libreria"
libreria
3) sii iinserisce
i
il nome d
della
ll ffonte
t d
dati
ti (lib
(libreria).
i ) Si S
Seleziona
l i
il fil
file
libreria.mdb dal tasto "Seleziona…" e si seleziona il tasto "Avanzate …"
54
Impostazione della fonte dati
"libreria"
libreria
4) si inseriscono
login e password
(libreria,libreria)
55