Documente Academic
Documente Profesional
Documente Cultură
Cuprins
1 Fundamente ale limbajului Java
1.1 Clase si obiecte.
Interfete si clase abstracte . . . . . . . . .
1.2 Incapsularea, mostenirea si polimorfismul .
1.3 Compilarea si executia unui program Java
1.4 Pachete . . . . . . . . . . . . . . . . . . .
1.5 Arhive jar . . . . . . . . . . . . . . . . . .
1.6 Colectii si clase generice . . . . . . . . . .
1.7 Tratarea exceptiilor . . . . . . . . . . . . .
1.8 Executie concurenta si sincronizare . . . .
1.9 Aplicatii cu baze de date . . . . . . . . . .
1
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
. 1
. 3
. 6
. 6
. 8
. 8
. 11
. 12
. 15
.
.
.
.
.
.
.
.
.
.
21
21
22
23
27
29
.
.
.
.
33
34
38
41
43
.
.
.
.
4 Entit
ati JPA
45
4.1 Clasa corespunzatoare unei tabele . . . . . . . . . . . . . . . . 45
4.2 Fatada componentei de tip entitate . . . . . . . . . . . . . . . 47
i
ii
CUPRINS
4.3
4.4
4.5
4.6
4.7
4.8
4.9
4.10
. . .
. . .
. . .
. . .
. . .
. . .
JPA
. . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
49
50
50
52
54
58
61
61
Anexe
73
73
B Studiu de caz
77
Bibliografie
99
List
a de figuri
1.1
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
23
27
28
32
32
3.1
4.1
4.2
5.1
5.2
5.3
5.4
5.5
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
64
65
66
70
70
iii
iv
DE FIGURI
LISTA
Capitolul 1
Fundamente ale limbajului Java
1.1
Clase si obiecte.
Interfete si clase abstracte
In toate limbajele de programare modelarea domeniului aplicatiei se face folosind variabile de diferite tipuri (numere ntregi sau reale, caractere, siruri
de caractere). O variabila reprezinta un nume atribuit unei zone de memorie,
astfel ncat continutul acesteia (siruri de zero sau unu) sa fie interpretat ntrun anumit mod de catre program. Java nu face exceptie n ceea ce priveste
definirea variabilelor, nsa, n afara de clasicele variabile de tip numeric sau
caractere, foloseste variabile cu tipuri de date definite de catre utilizatori. De
fapt, majoritatea variabilelor definite ntr-un program Java sunt instante
ale unor tipuri de date definite de catre programator, numite clase. Clasele
sunt tipuri de date definite de c
atre programator. Instantele claselor se numesc obiecte.
Clasele permit modelarea aplicatiei foarte aproape de lumea reala, n
comparatie cu modelarea prin numere si caractere. O clasa este un model
general pentru un grup de obiecte din lumea reala. Exemple de clase ntrun sistem de administrare a activitatii unei universitati: Student, Profesor,
Curs, Orar. Exemple de obiecte n acelasi sistem: popescu, ionescu, bazeDeDate, orarAnDoiGrupaC. O clasa este caracterizata prin campuri(atribute)
si metode(operatii). Campurile definesc proprietatile unei multimi de obiecte
iar metodele definesc comportamentul acestora. De exemplu clasa Curs ar
putea contine campurile numeCurs, titular, nrCredite si metodele inscrieS1
tudent, alocaSala.
Un obiect este o entitate tangibila din lumea reala, creat pe baza sablonului
reprezentat de clasa. Un obiect contine structura(campurile) si comportamentul(metodele) unei clase. Un obiect este o instant
a a unei clase.
O clasa abstracta este o clasa care contine cel putin o metoda abstracta,
adica o metoda fara implementare. O clasa abstracta nu poate fi instantiata,
iar subclasele ei trebuie sa implementeze metodele abstracte.
In Java, o interfata este o clasa care declara metode, fara a le defini.
Toate metodele unei interfete sunt metode abstracte. Deasemenea,
toate campurile unei interfete reprezinta constante. O clasa derivata dintr-o
interfata trebuie sa defineasca toate metodele declarate n interfata.
Supranc
arcarea metodelor
Se poate folosi acelasi nume pentru metode diferite ale unei clase, cu conditia
ca listele de argumente ale acestor metode sa fie diferite. Numele unei metode mpreuna cu lista de argumente ale acesteia definesc semn
atura unei
metode, care identifica n mod unic metodele unei clase.
Constructori
Atunci cand sunt create instante ale unei clase (obiecte) este apelata n mod
automat o metoda a clasei respective, numita constructor. Un constructor
este o metod
a f
ar
a rezultat care are acelasi nume cu numele clasei.
Constructorii pot fi suprancarcati, deci se pot defini mai multi constructori
pentru o clasa, fiecare avand o alta lista de argumente.
Accesul la c
ampurile de date si apelul metodelor
Pentru a folosi un camp al unui obiect se utilizeaza operatorul punct asezat
ntre numele obiectului si numele campului. De exemplu, o1.nume se refera
la campul(atributul) nume al obiectului o1.
Apelul unei metode membre a unei clase se realizeaza printr-o referinta la
o instanta a clasei respective, urmata de operatorul punct si numele metodei.
1.2
Conceptele de baz
a ale program
arii orientate pe obiecte sunt
ncapsularea, mostenirea si polimorfismul.
Incapsularea este mecanismul care permite ascunderea datelor si a
metodelor n obiecte, definind reguli de acces la acestea. In general atributele obiectelor sunt private, adica ele pot fi citite si scrise doar prin
intermediul unor metode, si nu direct. Deasemenea obiectele definesc metode private, care nu pot fi apelate decat de catre alte metode ale aceluiasi
obiect. Principiul de programare folosit este acela ca nu trebuie facute publice decat acele metode ale obiectelor care definesc modul de comunicare al
acestora cu instante ale altor clase.
Mostenirea este o relatie ntre clase, prin care o clasa declara o alta ca
fiindu-i parinte. Clasa copil(subclasa, clasa derivata) mosteneste toate
proprietatile clasei parinte(superclasei, clasei de baza), adica toate campurile
si metodele acesteia. Subclasa poate defini atribute si metode aditionale si
redefini operatii specificate de catre clasa parinte n cazul n care este necesara o implementare diferita. O clasa poate fi derivata dintr-o singura alta
clasa (cu alte cuvinte o clasa poate avea o singura superclasa), nsa poate
implementa oricate interfete.
Polimorfismul reprezinta posibilitatea de a transmite un mesaj cu acelasi
nteles unor obiecte care implementeza operatia ceruta n moduri diferite.
Din punct de vedere conceptual, apelul unei metode a unui obiect este privit ca reprezentand transmiterea unui mesaj catre acel obiect. Pentru a
explica polimorfismul, sa consideram clasa Baza si subclasele Derivata1 si
Derivata2 ale acesteia. Sa presupunem ca fiecare subclasa defineste cate o
metoda afiseaza. In momentul compilarii unui program Java n care se transmite mesajul afiseaza unui obiect de tip Baza nu se stie care dintre metode
va fi apelata: cea definita n clasa Derivata1 sau cea definita n clasa Derivata2. Doar n momentul executiei, atunci cand se cunoaste subclasa careia i
apartine instanta catre care se trimite mesajul, se decide care dintre metode
sa fie apelata.
Programul urmator ilustreaza atat polimorfismul, cat si unele dintre con-
class Program{
public static void main(String[] args){
//creaza obiectul b1, instanta a clasei Baza
Baza b = new Baza();
//creaza obiectul d1, instanta a clasei Derivata1
Derivata1 d1 = new Derivata1();
//creaza obiectul d2, instanta a clasei Derivata2
Derivata2 d2 = new Derivata2();
b.afiseaza(); //din Baza
d1.afiseaza(); //din Derivata1
d2.afiseaza(); //din Derivata2
b = d1;
b.afiseaza(); //din Derivata1
b = d2;
b.afiseaza(); //din Derivata2
}
}
Programul anterior, memorat n fisierul Program.java, este compilat si
executat folosind urmatoarele comenzi:
C:\ProgrameJava>javac Program.java
C:\ProgrameJava>java Program
Baza
Derivata1
Derivata2
Derivata1
Derivata2
1.3
Pentru aceasta carte am lucrat cu Java EE 6 si serverul de aplicatii GlassFish V3, care se descarca de la adresa http://java.sun.com. Dupa
instalare se poate verifica existenta mediului Java prin executia comenzii:
java -version
Primul pas n dezvoltarea unui program Java consta n editarea unui fisier
text continand codul programului. Fisierul trebuie sa aiba extensia .java,
de exemplu, numele fisierului ar putea fi PrimulProgram.java. Compilarea
programului se face utilizand comanda javac:
javac PrimulProgram.java
In urma compilarii rezulta un fisier executabil de catre masina virtuala
Java (JVM). Acest fisier are extensia .class. Programul este executat utilizand interpretorul de Java (comanda java):
java PrimulProgram
1.4
Pachete
Un grup de clase care servesc unui anumit tip de aplicatie sunt pastrate n
Java n acelasi director si alcatuiesc un pachet. Numele pachetului este un
sir de nume de directoare separate prin puncte, care reprezinta ierarhia de
directoare (calea) pana la subdirectorul n care sunt memorate clasele din
pachet. De exemplu, fisierele din pachetul cu numele programeJava.unu pot
fi memorate n directorul C:\cristina\programeJava\unu, cu conditia ca directorul C:\cristina sa fie specificat n variabila de mediu CLASSPATH.
Fie ca exemplu fisierul Salut.java din directorul C:\cristina\programeJava\unu.
1.4. PACHETE
package programeJava.unu;
public class Salut {
public static void main(String args[]){
System.out.println("Salut!");}}
Salut.java
1.5
Arhive jar
Arhivele Java (fisiere cu extensia jar) sunt folosite pentru a mpacheta ntrun singur fisier mai multe clase Java (fisiere cu extensia class). Algoritmul
de compresie folosit este algoritmul ZIP standard. In afara de clasele Java,
o arhiva de tip jar mai poate contine un director cu numele META-INF, n
care se pastreaza anumite fisiere de configurare si fisierul MANIFEST.MF cu
atribute referitoare la acel pachet (numele autorului, clasa principala, structura de directoare, etc.). Atat pentru crearea si actualizarea arhivelor jar,
cat si pentru extragerea fisierelor din arhiva, se foloseste comanda jar, care
face parte din Java Development Kit. O arhiva JAR poate fi folosita direct
n CLASSPATH, fara a fi necesara dezarhivarea si listarea n CLASSPATH
a tuturor componentelor din arhiva. Un fisier JAR poate fi executabil.
Figura 1.1 ilustreaza optiunile comenzii jar.
1.6
1.6. COLECT
II SI CLASE GENERICE
10
C:\ProgrameJava\unu>java Colectii
1
Popescu Cristina
Gogu
Pentru a mbunatati securitatea din punctul de vedere al verificarii tipurilor au fost introduse n Java 5.0 clasele generice. Principalul rol al
acestora este de a permite scrierea de colectii sigure din punctul de vedere al
tipurilor. Iata n continuare programul Colectii, rescris pentru a folosi tipul
generic ArrayList<Studenti>, o lista ale carei elemente nu pot fi decat
referinte catre instante ale clasei Student. Incercarea de a adauga n lista
elemente de alt tip va fi semnalata de catre compilator prin eroare, asa cum
se vede mai jos.
import java.util.ArrayList;
class Colectii2{
public static void main(String[] args){
ArrayList<Studenti> studenti = new ArrayList<Studenti>();
studenti.add(1);
Studenti me = new Studenti("Popescu","Cristina",31);
studenti.add(me);
String nume = "Gogu";
studenti.add(nume);
for(int i=0; i<studenti.size(); i++){
System.out.println(studenti.get(i));
}
}
}
Colectii2.java
11
C:\ProgrameJava\unu>javac Colectii2.java
Colectii2.java:9: cannot find symbol
symbol : method add(int)
location: class java.util.ArrayList<Studenti>
studenti.add(1);
Colectii2.java:13: cannot find symbol
symbol : method add(java.lang.String)
location: class java.util.ArrayList<Studenti>
studenti.add(nume);
2 errors
1.7
Tratarea exceptiilor
12
Fiecarui bloc try trebuie sa i corespunda cel putin un bloc catch sau un
bloc finally. Un bloc finally contine instructiuni care se executa indiferent
daca apare sau nu o exceptie. Deoarece secventa de program plasata n interiorul unui bloc try poate genera mai multe tipuri de exceptii se pot folosi
blocuri catch multiple, fiecare corespunzand unui anumit tip de eroare. Blocurile catch trebuie sa apara imediat dupa blocul try caruia i corespund si
este necesar sa fie plasate unul dupa celalalt.
O exceptie poate fi lansata explicit folosind cuvantul cheie throw urmat
de operatorul new, numele exceptiei si mesajul de eroare afisat la interceptarea acesteia.
throw new ExceptiaMea(Mesaj din ExceptiaMea);
Pentru anumite categorii de exceptii, numite exceptii verificate, dupa lansare compilatorul Java verifica existenta unui bloc catch corespunzator. Daca
o metoda lanseaza o exceptie verificata, dar nu o trateaza, este obligatoriu sa
o includa n lista sa de exceptii. Lista de exceptii a unei metode este introdusa de cuvantul cheie throws n antetul metodei, dupa lista de parametri.
IOException, SQLException, ClassNotFoundException sunt printre clasele de
exceptii verificate din Java.
public String cauta(int index) throws SQLException {...}
O clasa proprie pentru manipularea exceptiilor poate fi creata prin derivarea clasei Exception.
public class ExceptiaMea extends Exception {...}
1.8
Executie concurent
a si sincronizare
SI SINCRONIZARE
1.8. EXECUT
IE CONCURENTA
13
14
1.9. APLICAT
II CU BAZE DE DATE
15
1.9
16
1.9. APLICAT
II CU BAZE DE DATE
17
apeland metoda executeUpdate(), tot prin intermediul unui obiect de tip Statement.
Imediat dupa executia unei interogari, n tabela rezultat cursorul (pozitia
curenta n tabela) este pozitionat pe prima nregistrare a acestei tabele. Metoda next() are ca rezultat o valoare booleana care indica existenta a cel
putin nca unei nregistrari dupa nregistrarea curenta din tabela (instanta a
clasei ResultSet) corespunzatoare. Metoda getString() a clasei ResultSet are
ca rezultat valoarea din coloana cu numele care i se transmite ca parametru.
Interactiunea programului Java cu sistemul DBMS se ncheie cu nchiderea
conexiunii, folosind metoda close() a clasei Connection. Instantele clasei ResultSet definite pentru o anumita conexiune sunt nchise automat la nchiderea
conexiunii respective, nsa nchiderea explicita a tuturor obiectelor de tip ResultSet folosite este o buna practica de programare.
Java DB
Java DB este o versiune a sistemului Derby(Apache) pentru baze de date.
Aceasta versiune este dezvoltata n ntregime n tehnologie Java si este n
prezent mpachetata n serverul de aplicatii GlassFish.
Executia comenzilor SQL
Instrumentul pe care l avem la dispozitie pentru executia comenzilor SQL n
Java DB, atat a comenzilor de interogare cat si a celor de creare a tabelelor
si manipulare a datelor, se numeste ij . Interfata utilizatorului cu ij este
linia de comanda.
Pe calculatorul meu, ij se gaseste n directorul C:\Sun\SDK\javadb\bin.
Pentru a deschide o conexiune la baza de date, a crea o tabela si a insera
valori n aceasta am executat urmatoarele comenzi:
C:\Sun\SDK\javadb\bin>ij
ij>connect jdbc:derby:student;
create=true; user=profesor;
18
1.9. APLICAT
II CU BAZE DE DATE
19
}
try{
dbConnection=DriverManager.getConnection(dbUrl);
Statement stmt= dbConnection.createStatement();
ResultSet rs =
stmt.executeQuery(
" SELECT * FROM student");
while (rs.next()) {
System.out.println (
rs.getString ("nume") + "," +
rs.getString ("prenume") + "," +
rs.getString ("email"));
}
stmt.close();
}
catch(SQLException e) {
e.printStackTrace();
}
finally{rs.close();dbConnection.close();}
}
}
O aplicatie client-server
Programul se executa precizand n linia de comanda pentru masina virtuala Java calea catre driverul Java DB pentru SQL(derby.jar), ca n exemplul de mai jos:
java -classpath .;C:\Sun\SDK\javadb\lib\derby.jar Student
20
Capitolul 2
Arhitectura aplicatiilor Java EE
2.1
Java EE(Enterprise Edition) reprezinta o tehnologie de programare a sistemelor bazate pe servere de aplicatii. Aceasta tehnologie foloseste diferite
tipuri de componente software administrate de catre serverul de aplicatii,
care actioneaza ca intermediari ntre programele clientilor si alte servere specializate (de exemplu servere de baze de date). Daca Java este un limbaj de
programare, Java EE este un standard care specifica, pe de o parte, modul de
realizare a sistemelor bazate pe servere de aplicatii, pe de alta parte modul de
functionare al serverului de aplicatii si serviciile pe care acesta trebuie sa
le puna la dispozitie, asfel ncat aplicatia sa fie independenta de serverul de
aplicatii. Am inclus cuvantul servicii ntre ghilimele, astfel ncat el sa nu
duca cititorul cu gandul la notiunea de servicii Web, ci sa fie luat n sensul
sau mai general, de functii sau metode pe care aplicatiile le au la dispozitie
n mediul creat de serverul de aplicatii. Cu alte cuvinte, principiul write
once, run anywhere este valabil si n privinta aplicatiilor Java EE, n sensul
ca orice aplicatie care este scrisa n conformitate cu standardul trebuie sa
functioneze la fel de bine pe Oracle WebLogic, IBM WebSphere, Sun GlassFish, etc. (Am enumerat cele mai cunoscute servere de aplicatii de astazi.)
Arhitectura sistemelor dezvoltate n tehnologia discutata aici este dezvoltata pe trei niveluri: client, server de aplicatii, baza de date, si reprezinta
o evolutie a arhitecturilor mai vechi, de tip client-server. Avand n vedere
ca n interiorul serverului de aplicatii exista doua containere, unul care ad21
22
2.2
2.3
Pentru a apela metode ale unei componente aflate pe aceeasi masina virtuala Java, un program client va folosi o interfata locala (o interfata Java
standard care contine metodele componentei). O interfata locala poarta ad-
24
Adnotarile(annotations) reprezint
a o modalitate de a marca anumite elemente ale
programelor Java cu scopul de a controla executia unei aplicatii. Le puteti privi ca fiind
comentarii disponibile n momentul executiei, destinate masinii virtuale Java. Din punct de
vedere sintactic, o adnotare este un nume, care reprezint
a n general tipul unei componente
(de exemplu Stateful, Stateless, Resource, Table, Column, etc.), prefixat cu simbolul @ si
care se scrie naintea modificatorilor de acces care preced declaratiile claselor.
26
27
2.4
Gestiunea tranzactiilor
28
tranzactiei) si durabila (nainte de ncheierea tranzactiei, modificarile efectuate de aceasta vor fi scrise ntr-o memorie fizica, astfel ncat sa poata fi
recuperate chiar n cazul unei caderi a sistemului) (ACID).
Intr-o componenta de tip sesiune sau bazata pe mesaje care nu specifica tipul de gestiune a tranzactiilor, codul pe care l scrieti nu va contine
instructiuni care sa marcheze nceputul sau sfarsitul tranzactiilor, acestea
fiind setate de catre container. Containerul va ncepe, suspenda si ncheia
tranzactiile n functie de valoarea unui atribut specificat pentru fiecare metoda
cu adnotarea @TransactionAttribute. Valoarea acestui atribut poate fi
una dintre urmatoarele: REQUIRED, REQUIRES NEW, MANDATORY,
NOT SUPPORTED, SUPPORTS, NEVER.
Interfata de programare JTA (Java Transaction API) defineste metode
pentru initierea si terminarea explicita a tranzactiilor (begin, commit, rollback).
2.5
29
Putin
a istorie
Documentele JSP sunt pagini HTML n care sunt incluse secvente de cod
Java si XML. JSP-urile sunt transformate de catre serverul Web n servleturi, avantajul lor fiind acela al scrierii ntr-o maniera mai simpla a aplicatiei.
Servlet-urile sunt clase Java care se executa pe serverul Web n momentul primirii unei cereri de la un client (browser Web), reprezentand astfel o
modalitate de a genera n mod dinamic continutul paginilor Web. Servleturile sunt implementarea Java a standardului Common Gateway Interface
(CGI), care specifica modul de comunicare ntre clientii si serverele de Web,
atunci cand raspunsul transmis clientului de catre server se obtine n urma
executiei pe server a unui program cu parametri primiti de la client. Servleturile sunt gestionate de servere Web special concepute pentru a folosi aceasta
tehnologie (e.g. Tomcat).
Tehnologia JavaServer Pages (JSP) foloseste un limbaj de expresii
(Expression Language, prescurtat EL) pentru a folosi date ale unor obiecte
externe. La nceput acest limbaj s-a numit JavaServer Pages Standard Tag
Library (JSTL). De exemplu, expresia ${student.nume} este folosita pentru a cauta componenta student si a apela metoda citesteNume a acesteia,
afisand n pagina valoarea atributului(campului) nume(numele studentului).
Tehnologia JavaServer Faces (JSF) adauga tehnologiei JSP un model
de componente de interfata cu utilizatorul (componente UI) care include:
un set de clase care definesc componente grafice de interfata (componente UI).
un mecanism pentru tratarea evenimentelor generate de catre componentele UI.
un mecanism de validare a datelor corespunzatoare componentelor UI.
Pentru tehnologia JavaServer Faces a fost creat un nou limbaj de expresii
care permite:
30
O pagin
a JSP simpl
a
<%@page import="student.AfiseazaStudent"%>
<html>
<head>
<title>Prima pagina JSP</title>
</head>
<body>
<%
javax.naming.InitialContext ctx =
new javax.naming.InitialContext();
AfiseazaStudent beanInstance = (AfiseazaStudent)
ctx.lookup(AfiseazaStudent.class.getName());
String result = beanInstance.afiseaza(777);
%>
<%= result %>
</body>
</html>
student.jsp
31
Directivele reprezinta intructiuni care sunt prelucrate de catre server (containerul JSP) atunci cand pagina este compilata. De exemplu cu directiva
page se definesc atribute valabile pentru ntreaga pagina JSP. Atributul import, similar cu instructiunea import din Java, reprezinta o lista de clase
care pot fi folosite n declaratiile, expresiile si fragmentele de cod Java din
interiorul paginii JSP.
Fragmentele de cod Java ncep cu secventa de caractere < % si se ncheie
cu secventa % >.
Expresiile ncep cu secventa de caractere < % = si se ncheie cu secventa
% >. Expresiile sunt evaluate la run time si rezultatul lor inserat n iesirea
servlet-ului (afisat).
Module Web
Un modul web al unei aplicatii de tip Enterprise este mpachetat ntr-o arhiv
a Java cu extensia war. Structura generala a unei arhive WAR este
ilustrata n Figura 2.4. Daca modulul web contine numai pagini JSP si pagini statice fisierul de configurare (deployment descriptor) web.xml nu este
necesar. Acesta este folosit doar n cazul tehnologiei JavaServer Faces, pentru specificarea unor informatii de securitate sau daca se doreste modificarea
unor configurari realizate prin adnotari la nivelul componentelor web.
Comanda folosita pentru crearea arhivei este urmatoarea:
C:\WebApps>jar cvf StudentApp.war student.jsp WEB-INF/lib/
In WEB-INF/lib exista arhiva StudentApp.jar, continand componenta
AfiseazaStudent, pe care am construit-o folosind comanda:
C:\EJB>jar cf StudentApp.jar student\
32
Capitolul 3
Componente de tip sesiune
Componentele de tip sesiune sunt folosite n Java EE pentru a implementa
asa-numitele reguli de business, adica acele operatii, functii, actiuni specifice domeniului aplicatiei. Componentele de tip sesiune sunt folosite n cadrul
conversatiilor (sesiunilor) clientilor cu serverul.
Exista trei categorii de componente de tip sesiune:
componente de tip sesiune cu stare(stateful session beans)
componente de tip sesiune f
ar
a stare(stateless session beans)
componente singulare(singleton session beans)
In cazul componentelor de tip sesiune fara stare, sesiunea (conversatia)
clientului cu serverul este alcatuita dintr-un singur apel de metoda.
Daca, n logica procesului de business implementat, invocarea unei metode este dependenta de apelul sau precedent, sunt folosite componentele de
tip sesiune cu stare, n cazul carora sesiunea poate contine mai multe apeluri
(ale aceleiasi metode sau ale unor metode diferite ale aceleiasi componente)
iar starea asociata clientului este mentinuta n componenta pe tot parcursul
sesiunii (de la un apel de metoda la altul). Exemplul clasic l constituie implementarea unui cos de cumparaturi ntr-o aplicatie de comert electronic. Clasa
CosDeCumparaturi va cotine o metoda adaugaInCos; aceasta metoda
trebuie sa cunoasca starea clientului anterioara fiecarui apel (continutul
33
34
cosului de cumparaturi). Altfel spus, serverul trebuie sa-i aloce unui client aceeasi instanta a clasei care implementeaza cosul de cumparaturi, de
fiecare data cand clientul apeleaza metoda adaugaInCos. Astfel, implementarea se face printr-o componenta de tip sesiune cu stare. (Imaginati-va
un cumparator ntr-un supermarket, care ar pune articolele pe care le ia de
pe rafturi, de fiecare data n alt cos! Acest scenariu ar corespunde n Java
EE folosirii componentelor fara stare.) Prin contrast, verificarea validitatii
unui card de credit, de exemplu, nu presupune alocarea aceleiasi instante a
unei componente de tip sesiune unui client care solicita aceasta operatie n
mod repetat. Verificarea validitatii unui card de credit se poate implementa
prinr-o componenta de tip sesiune fara stare.
3.1
A
STARE
3.1. COMPONENTE DE TIP SESIUNE, FAR
STUDENTID
111
222
333
444
555
777
NUME
Popescu
Ionescu
Petrescu
Vasilescu
Georgescu
Bond
PRENUME
Ion
Vasile
Petre
Mihai
Gogu
James
35
EMAIL
ipop@mycomp.com
vion@mycomp.com
ppet@mycomp.com
mvas@mycomp.com
ggeo@mycomp.com
jbond@mycomp.com
Definitia interfetei
package student;
import javax.ejb.Remote;
@Remote
public interface AfiseazaStudent{
public String afiseaza(int sid);
}
AfiseazaStudent.java
Definitia clasei
package student;
import java.sql.*;
36
import javax.ejb.*;
import javax.annotation.Resource;
@Stateless(name="AfiseazaStudent")
public class AfiseazaStudentBean implements AfiseazaStudent{
@Resource(name="jdbc/student")
private javax.sql.DataSource ds;
private Connection con;
private Statement st;
private ResultSet rs;
public String afiseaza(int sid)
{
try{
con = ds.getConnection();
st = con.createStatement();
rs = st.executeQuery
("SELECT * FROM student WHERE studentid = " + sid);
rs.next();
return rs.getString("nume")+ "," +
rs.getString ("prenume") + "," +
rs.getString ("email");
}
catch(Exception e){
return e.toString();
}
}
}
AfiseazaStudentBean.java
Pentru a putea executa interogari SQL, programul trebuie sa se conecteze la serverul de baze de date, apeland metoda getConnection() a clasei
DataSource din pachetul javax.sql. Transmiterea unei interogari SQL catre
serverul de baze de date se face prin intermediul unei instante a clasei Statement, care defineste metoda executeQuery(). Pentru a crea o instanta a
A
STARE
3.1. COMPONENTE DE TIP SESIUNE, FAR
37
38
3.2
Definitia interfetei
package examen;
import javax.ejb.Remote;
@Remote
public interface ExamenOnline{
public String afiseazaIntrebare();
}
ExamenOnline.java
Definitia clasei
package examen;
import javax.ejb.*;
@Stateful
public class ExamenOnlineBean implements ExamenOnline{
private int nrIntrebare=0;
public String afiseazaIntrebare(){
++nrIntrebare;
switch(nrIntrebare){
case 1: return "Cine a inventat ciocolata?";
case 2: return "In ce an s-a nascut Einstein?";
case 3: return "Cate planete sunt in sistemul nostru solar?";
default: return "Nu mai sunt intrebari"; }//switch}}
ExamenOnlineBean.java
39
40
import javax.naming.InitialContext;
public class ExamenOnlineClient{
public static void main(String[] args) throws Exception
{
InitialContext ctx = new InitialContext();
ExamenOnline beanInstance = (ExamenOnline)
ctx.lookup("examen.ExamenOnline");
for(int i=0; i<5; i++)
System.out.println(beanInstance.afiseazaIntrebare());}}
ExamenOnlineClient.java
3.3
41
package single;
import javax.ejb.Singleton;
@Singleton(name="Contor")
public class ContorBean implements Contor{
private int numara = 0;
public int citesteContor(){
return numara++;
}
}
ContorBean.java
42
package clienti;
import single.Contor;
import javax.naming.InitialContext;
public class SingleClient{
public static void main(String[] args) throws Exception{
InitialContext context = new InitialContext();
Contor contor = (Contor)context.lookup("single.Contor");
System.out.println(contor.citesteContor());
}}
SingleClient.java
3.4
Ciclul de viat
a al componentelor de tip
sesiune
O component
a de tip sesiune f
ar
a stare este creat
a la initiativa
containerului EJB. Containerul mentine un rezervor (pool) de instante
ale componentelor de acest tip, astfel ncat atunci cand un client apeleaza
o metoda a unei componente de tip sesiune fara stare este aleasa o instanta
a componentei din rezervor si invocata metoda acesteia. Acest lucru este
posibil deoarece starea componentei nu trebuie mentinuta dupa ncheierea
executiei metodei. Distrugerea componentelor de tip sesiune fara stare este
deasemenea efectuata prin decizia containerului EJB, de exemplu pentru eliberarea unor resurse de memorie sau atunci cand o anumita componenta nu
este utilizata un timp mai ndelungat. Astfel, o componenta de tip sesiune
fara stare se poate gasi n timpul ciclului sau de viata doar ntr-una din doua
stari: inexistenta si n astepare(ready).
O metoda a unei componente de tip sesiune fara stare poate fi marcata
cu una dintre adnotarile @PostConstruct sau @PreDestroy, ceea ce va
face ca ele sa fie apelate imediat dupa instantierea componentei, respectiv
nainte de distrugerea ei.
Spre deosebire de cazul componentelor fara stare, ciclul de viat
a al
componentelor de tip sesiune cu stare este initiat de c
atre clienti
prin solicitarea unei referinte la o instant
a a unei componente. Pe
durata ciclului sau de viata, o componenta de tip sesiune cu stare poate fi
trecuta de catre container din starea ready, n care componenta se afla n
memoria principala, ntr-o stare pasiva(inactiva), n memoria secundara a
serverului. Re-activarea are loc atunci cand un client apeleaza o metoda a
44
Capitolul 4
Entit
ati JPA
4.1
Clasa corespunz
atoare unei tabele
I JPA
CAPITOLUL 4. ENTITAT
46
javax.persistence.Entity;
javax.persistence.Table;
javax.persistence.Id;
javax.persistence.Column;
java.io.Serializable;
@Entity
@Table(name="STUDENT")
public class Student implements Serializable{
@Id
@Column(name="STUDENTID", nullable=false)
private int studentId;
@Column(name="NUME")
private String nume;
@Column(name="PRENUME")
private String prenume;
@Column(name="EMAIL")
private String email;
public Student(){
}
public long citesteStudentId(){
return studentId;
}
4.2. FAT
ADA COMPONENTEI DE TIP ENTITATE
47
4.2
I JPA
CAPITOLUL 4. ENTITAT
48
Definitia interfetei
package doi;
import javax.ejb.Remote;
import doi.Student;
@Remote
public interface CautaStudent{
public String cauta(int id);
}
CautaStudent.java
Definitia clasei
package doi;
import
import
import
import
import
javax.ejb.Stateless;
javax.annotation.Resource;
javax.persistence.PersistenceContext;
javax.persistence.PersistenceUnit;
javax.persistence.EntityManager;
II DE PERSISTENT
49
import javax.persistence.EntityManagerFactory;
import doi.Student;
@Stateless(name="CautaStudent")
public class CautaStudentBean implements CautaStudent{
@PersistenceContext(unitName="StudentPersistUnit")
EntityManager em;
public String cauta(int id){
Student s = em.find(Student.class,id);
return s.citesteNume();
}
}
CautaStudentBean.java
4.3
Definirea unit
atii de persistent
a
I JPA
CAPITOLUL 4. ENTITAT
50
arhivei WAR[1].)
4.4
4.5
Un exemplu de client
package clienti;
import doi.CautaStudent;
import javax.naming.InitialContext;
import doi.Student;
51
52
I JPA
CAPITOLUL 4. ENTITAT
->C:\glassfishv3\glassfish\lib\javaee.jar;. ->
->clienti.EntityBeanStudentClient
Apr 21, 2010 5:12:26 PM
com.sun.enterprise.transaction.JavaEETransactionManagerSimplified
initDelegates
INFO: Using
com.sun.enterprise.transaction.jts.JavaEETransactionManagerJTSDelegate
as the delegate
Hi, Bond!
4.6
Ciclul de viat
a al entit
atilor JPA
In timpul ciclului sau de viata o instanta a unei entitati JPA poate fi ntr-una
dintre urmatoarele patru stari: noua (new), asociata (managed), detasata
(detached) sau stearsa (removed).
Crearea instantelor entitatilor JPA si trecerea acestora dintr-o stare n
alta are loc ca urmare a unor apeluri de metode ale unei instante de tip
EntityManager. Gestiunea instantelor entit
atilor JPA se face prin
intermediul unui obiect de tip EntityManager.
Metoda EntityManager.find() executa o instructiune SELECT asupra bazei de date, folosind cheia primara a entitatii careia i este aplicata.
Rezultatul metodei este o entitate cu o identitate persistenta, asociata cu
un context de persistenta, aflata n starea managed. In aceeasi stare (managed) va trece o entitate noua, atunci cand asupra ei este invocata una
dintre metodele EntityManager.persist()sau EntityManager.merge().
La executia operatiilor EntityManager.persist() sau EntityManager.merge()
asupra bazei de date va fi executata o instructiune INSERT.
Executia metodei EntityManager.remove() marcheaza o entitate JPA
pentru stergere, trecand-o n starea removed, n care entitatea are nca
o identitate persistenta si este asociata cu un context de persistenta. La
executia unei metode EntityManager.flush(), entitatile marcate pentru
stergere (aflate n starea removed) vor fi sterse din baza de date prin executia
unei comenzi DELETE. Daca EntityManager.persist() este apelata asupra instantei unei entitati JPA aflata n starea removed, aceasta va trece n
AL ENTITAT
ILOR JPA
4.6. CICLUL DE VIAT
A
53
Figura 4.2: Starile unei entitati JPA pe durata ciclului sau de viata
starea managed.
O entitate detasat
a are o identitate persistenta, nsa nu este asociata
cu un context de persistenta, rezultand de exemplu n urma unei tranzactii
ncheiate cu commit sau rollback. La executia EntityManager.merge()
asupra unei entitati detasate aceasta trece n starea managed iar baza de
date va fi actualizata prin executia comenzii UPDATE.
Starile entitatilor persistente sunt sincronizate cu baza de date atunci
cand tranzactiile cu care acestea sunt asociate executa commit. Pentru a
forta sincronizarea cu baza de date se poate folosi metoda EntityMana-
I JPA
CAPITOLUL 4. ENTITAT
54
ger.flush().
4.7
Fiecare entitate JPA trebuie sa aiba o cheie primara, pentru a putea fi identificata n mod unic. Atunci cand cheia primara este compusa din mai multe
atribute este necesar sa fie definita o clasa corespunzatoare acesteia. Clasa
corespunzatoare cheii primare a unei entitati JPA este specificata folosind
adnotarea @IdClass n fata numelui clasei corespunzatoare entitatii JPA.
Clasa corespunzatoare unei chei primare trebuie sa ndeplineasca urmatoarele
conditii([2]):
Sa fie definita public.
Sa implementeze interfata Serializable.
Sa aiba un constructor public fara parametri.
Sa implementeze metodele hashCode si equals.
Numele si tipurile campurilor din cheia primara trebuie sa fie aceleasi n
clasa corespunzatoare cheii primare si n clasa corespunzatoare entitatii
JPA. In clasa corespunzatoare entitatii JPA, campurile care fac parte
din cheia primara vor fi marcate cu adnotarea @Id.
Campurile din clasa corespunzatoare cheii primare vor fi definite public sau protected, daca este folosit accesul bazat pe valorile din aceste
campuri (property-based access).
Exemplu
ij> CREATE TABLE Grades(
> studentID INTEGER NOT NULL,
> cursID INTEGER NOT NULL,
> semestrul1 INTEGER,
> semestrul2 INTEGER,
> laborator INTEGER,
> CONSTRAINT pk_SidCid PRIMARY KEY(studentID,cursID));
0 rows inserted/updated/deleted
javax.persistence.Entity;
javax.persistence.Table;
javax.persistence.Id;
javax.persistence.IdClass;
javax.persistence.Column;
javax.persistence.NamedQuery;
java.io.Serializable;
@Entity
@Table(name="GRADES")
@IdClass(GradesPK.class)
@NamedQuery(name="Grades.forOneStudent",
query="select o from Grades o where o.studentId=:param")
public class Grades implements Serializable{
@Id
@Column(name="STUDENTID", nullable=false)
private int studentId;
@Id
@Column(name="CURSID", nullable=false)
55
56
I JPA
CAPITOLUL 4. ENTITAT
package celeste;
import java.io.Serializable;
public class GradesPK implements Serializable{
public int studentId;
public int cursId;
public GradesPK(){
//constructor public fara parametri
}
public int hashCode(){
return super.hashCode();
}
public boolean equals(Object other){
if(!(other instanceof GradesPK)){
return false;}
GradesPK celalalt = (GradesPK)other;
return(celalalt.studentId==studentId
&&
celalalt.cursId==cursId);
}
}
GradesPK.java
57
I JPA
CAPITOLUL 4. ENTITAT
58
...
public List<Grades> getGradesforOneStudent(int idStud){
List<Grades> note =
(List<Grades>)em.createNamedQuery("Grades.forOneStudent").
setParameter("param",idStud).getResultList();
return note;
}
...
FatadaCursuriBean.java
4.8
ILE JPA
4.8. SPECIFICAREA RELAT
IILOR DINTRE ENTITAT
59
I JPA
CAPITOLUL 4. ENTITAT
60
3
4
4
5
5
5
5
6
7
7
7
|3
|3
|1
|1
|2
|3
|4
|4
|1
|3
|4
18 rows selected
...
@Entity
@Table(name="CURSURI")
...
public class Cursuri implements Serializable{
...
@ManyToMany
@JoinTable(name="STUD_CURS",
joinColumns=
@JoinColumn(name="CURSID",referencedColumnName="CURSID"),
inverseJoinColumns=
@JoinColumn(name="STUDENTID",referencedColumnName="STUDENTID"))
//name=numele coloanei din tabela STUD_CURS (tabela de join)
//referencedColumnName=numele coloanelor din tabelele
//CURSURI, respectiv STUDENTI
private Set<Studenti> studenti;
...
}
ILE JPA61
4.9. IMPLEMENTAREA RELAT
IILOR DE MOSTENIRE DINTRE ENTITAT
4.9
4.10
Limbajul JPQL
62
I JPA
CAPITOLUL 4. ENTITAT
Capitolul 5
Componente bazate pe mesaje
O componenta bazata pe mesaje (message-driven bean, MDB) este o componenta fara stare care consuma mesaje dintr-o coada JMS (Java Message
Service). Standardul JMS este parte integranta din Java EE si implementeaza suportul pentru comunicatii asincrone pe aceasta platforma. Mai concret, este vorba despre dirijarea mesajelor catre destinatii denumite cozi si
distribuirea acestor mesaje catre consumatori.
O componenta MDB defineste o metoda, onMessage(), care este apelata
de catre containerul EJB ori de cate ori este primit un mesaj n coada la
care este asociata componenta(Fig.5.1). O component
a de tip MDB nu
poate fi apelat
a direct de c
atre clienti.
5.1
Crearea resurselor
64
5.2
Prima component
a bazat
a pe mesaje
javax.ejb.MessageDriven;
javax.jms.MessageListener;
javax.jms.Message;
javax.jms.TextMessage;
java.util.logging.Logger;
@MessageDriven(name="PrimaCBM",mappedName="jms/Queue")
public class PrimaCBM implements MessageListener {
static final Logger registru = Logger.getLogger("PrimaCBM");
public PrimaCBM(){}
BAZATA
PE MESAJE
5.2. PRIMA COMPONENTA
65
66
5.3
Trimiterea mesajelor
67
javax.jms.ConnectionFactory;
javax.jms.Queue;
javax.jms.Connection;
javax.jms.Session;
javax.jms.MessageProducer;
javax.jms.TextMessage;
javax.jms.Message;
import javax.naming.InitialContext;
68
mesaj.setStringProperty("text","Testez CBM");
expeditor.send(mesaj);
System.out.println("Am trimis mesajul:"+mesaj.getStringProperty("text"));
expeditor.close();
sesiune.close();
conexiune.close();
}
catch(Exception e){System.out.println("Exceptie: " + e.toString());}
} // main
} // class
CBMClient.java
69
70
Anexe
71
Anexa A
Definirea unei surse de date n
GlassFish
Crearea si distrugerea conexiunilor la o baza de date poate fi costisitoare,
ceea ce justifica mentinerea unui rezervor de conexiuni (connection pool),
o multime de conexiuni reutilizabile, pentru o anumita baza de date, pregatite
n prealabil si administrate de catre serverul de aplicatii. Definitia unei surse
de date n GlassFish trebuie sa fie precedata de definitia rezervorului de conexiuni folosit de aceasta. Am definit rezervorul de conexiuni si sursa de date
folosind consola grafica pentru administrare a serverului, asa cum se vede n
figurile A.1 si A.2.
Pentru ca definitia unui rezervor de conexiuni pe o baza de date Java
DB sa fie completa trebuie definite si urmatoarele proprietati: DatabaseName, User, Password, PortNumber, ServerName. Mai jos este specificat ca
exemplu un set de valori pentru aceste proprietati.
DatabaseName = C:\Sun\SDK\javaDB\bin\student
User = profesor
Password = parolaprofesor
PortNumber = 1527
ServerName = localhost
73
74
75
76
Anexa B
Fragment dintr-un sistem de
e-learning
Crearea bazei de date
Folosim o baza de date cu patru tabele, Studenti, Profesori, Cursuri si
Note, ntre care exista relatiile prezentate n Tabela B.1.
C:\Sun\SDK\javadb\bin>ij
ij version 10.4
ij> connect jdbc:derby:celeste;
create=true;user=dba;password=paroladba
> as conex1;
ij> CREATE TABLE Studenti(
> studentID INTEGER PRIMARY KEY,
> nume VARCHAR(30),
> prenume VARCHAR(30),
> email VARCHAR(40));
0 rows inserted/updated/deleted
Studenti
Profesori
Studenti
Cursuri
Cursuri
Note
M:M
1:M
1:1
78
79
0 rows selected
ij>
ij> INSERT INTO Studenti VALUES
> (1,Ion,Ionescu,iion@celeste.ro);
1 row inserted/updated/deleted
ij> INSERT INTO Studenti VALUES
> (2,Petre,Petrescu,ppet@celeste.ro);
1 row inserted/updated/deleted
ij> INSERT INTO Studenti VALUES
> (3,Cristina,Cristescu,cris@celeste.ro);
1 row inserted/updated/deleted
ij> INSERT INTO Studenti VALUES
> (4,Ioana,Ionescu,ioio@celeste.ro);
1 row inserted/updated/deleted
ij> INSERT INTO Studenti VALUES
> (5,Vasile,Vasilescu,vasi@celeste.ro);
1 row inserted/updated/deleted
ij> INSERT INTO Studenti VALUES
> (6,Gelu,Popescu,gepo@celeste.ro);
1 row inserted/updated/deleted
ij> INSERT INTO Studenti VALUES
> (7,Andrei,Andreescu,andre@celeste.ro);
1 row inserted/updated/deleted
ij> SELECT * FROM Studenti;
STUDENTID |NUME
|PRENUME
|EMAIL
---------------------------------------------------------------------1
|Ion
|Ionescu
|iion@celeste.ro
2
|Petre
|Petrescu
|ppet@celeste.ro
3
|Cristina
|Cristescu
|cris@celeste.ro
4
|Ioana
|Ionescu
|ioio@celeste.ro
5
|Vasile
|Vasilescu
|vasi@celeste.ro
6
|Gelu
|Popescu
|gepo@celeste.ro
7
|Andrei
|Andreescu
|andre@celeste.ro
7 rows selected
ij> INSERT INTO Note VALUES
80
> (1,9,10,10);
1 row inserted/updated/deleted
ij> INSERT INTO Note VALUES
> (2,8,7,8);
1 row inserted/updated/deleted
ij> INSERT INTO Note VALUES
> (3,10,10,10);
1 row inserted/updated/deleted
ij> INSERT INTO Note VALUES
> (4,7,6,7);
1 row inserted/updated/deleted
ij> INSERT INTO Note VALUES
> (5,5,5,5);
1 row inserted/updated/deleted
ij> INSERT INTO Note VALUES
> (6,10,9,10);
1 row inserted/updated/deleted
ij> INSERT INTO Note VALUES
> (7,7,5,9);
1 row inserted/updated/deleted
ij> SELECT * FROM Note;
STUDENTID |SEMESTRUL1 |SEMESTRUL2 |LABORATOR
----------------------------------------------1
|9
|10
|10
2
|8
|7
|8
3
|10
|10
|10
4
|7
|6
|7
5
|5
|5
|5
6
|10
|9
|10
7
|7
|5
|9
7 rows selected
ij> INSERT INTO Profesori VALUES
> (1,Ionescu,Cristina);
1 row inserted/updated/deleted
ij> INSERT INTO Profesori VALUES
> (2,Teodorescu,Mihai);
81
1 row inserted/updated/deleted
ij> INSERT INTO Profesori VALUES
> (3,Popescu,Paul);
1 row inserted/updated/deleted
ij> SELECT * FROM Profesori;
PROFESORID |NUME
|PRENUME
------------------------------------------------------------------------1
|Ionescu
|Cristina
2
|Teodorescu
|Mihai
3
|Popescu
|Paul
3 rows selected
ij> INSERT INTO Cursuri VALUES
> (1,Proiectarea bazelor de date,3);
1 row inserted/updated/deleted
ij> INSERT INTO Cursuri VALUES
> (2,Programare orientata pe obiecte,1);
1 row inserted/updated/deleted
ij> INSERT INTO Cursuri VALUES
> (3,Dezvoltarea aplicatiilor Web,1);
1 row inserted/updated/deleted
ij> INSERT INTO Cursuri VALUES
> (4,Retele de calculatoare,2);
1 row inserted/updated/deleted
ij> INSERT INTO Cursuri VALUES
> (5,Sisteme de gestiune a bazelor de date,3);
1 row inserted/updated/deleted
ij> SELECT * FROM Cursuri;
CURSID
|NUME
|PROFESORID
-------------------------------------------------------------------------1
|Proiectarea bazelor de date
|3
2
|Programare orientata pe obiecte
|1
3
|Dezvoltarea aplicatiilor Web
|1
4
|Retele de calculatoare
|2
5
|Sisteme de gestiune a bazelor de date
|3
82
5 rows selected
Definirea entit
atilor JPA
Studenti
package celeste;
import
import
import
import
import
import
import
import
javax.persistence.Entity;
javax.persistence.Table;
javax.persistence.Id;
javax.persistence.Column;
javax.persistence.OneToOne;
javax.persistence.JoinColumn;
javax.persistence.NamedQuery;
java.io.Serializable;
@Entity
@Table(name="STUDENTI")
@NamedQuery(name="Studenti.note",
query="select o.note from Studenti o " +
"where o.studentId = :param")
public class Studenti implements Serializable{
@Id
@Column(name="STUDENTID", nullable=false)
private int studentId;
@Column(name="NUME")
private String nume;
@Column(name="PRENUME")
private String prenume;
@Column(name="EMAIL")
83
private String email;
@OneToOne
@JoinColumn(name="STUDENTID",referencedColumnName="STUDENTID")
private Note note;
public Studenti(){
}
public long citesteStudentId(){
return studentId;
}
public void scrieStudentId(int i){
studentId=i;
}
public String citesteNume(){
return nume;
}
public void scrieNume(String n){
nume=n;
}
public String citestePrenume(){
return prenume;
}
public void scriePrenume(String p){
prenume=p;
}
public String citesteEmail(){
return email;
}
public void scrieEmail(String e){
email=e;
}
}
Studenti.java
84
Cursuri
package celeste;
import
import
import
import
import
import
import
import
import
import
import
import
javax.persistence.Entity;
javax.persistence.Table;
javax.persistence.Id;
javax.persistence.Column;
javax.persistence.NamedQuery;
javax.persistence.NamedQueries;
javax.persistence.ManyToOne;
javax.persistence.ManyToMany;
javax.persistence.JoinColumn;
javax.persistence.JoinTable;
java.io.Serializable;
java.util.List;
@Entity
@Table(name="CURSURI")
/*@NamedQuery(name="Cursuri.numeTitular",
query="select o.profesor from Cursuri o " +
"where o.cursId = :param")
*/
/*
@NamedQuery(name="Cursuri.studentiInscrisi",
query="select o.studenti from Cursuri o " +
"where o.cursId = :param")
*/
@NamedQueries({
@NamedQuery(name="Cursuri.numeTitular",
query="select o.profesor from Cursuri o " +
"where o.cursId = :param"),
@NamedQuery(name="Cursuri.studentiInscrisi",
query="select o.studenti from Cursuri o " +
"where o.cursId = :param")
})
85
public class Cursuri implements Serializable{
@Id
@Column(name="CURSID", nullable=false)
private int cursId;
@Column(name="NUME")
private String nume;
//@Column(name="PROFESORID")
//private String profesorId;
@ManyToOne
@JoinColumn(name="PROFESORID",referencedColumnName="PROFESORID")
private Profesori profesor;
@ManyToMany
@JoinTable(name="STUD_CURS",
joinColumns=
@JoinColumn(name="CURSID",referencedColumnName="CURSID"),
inverseJoinColumns=
@JoinColumn(name="STUDENTID",referencedColumnName="STUDENTID"))
//name=numele coloanei din tabela
//STUD_CURS (tabela de join)
//referencedColumnName=numele coloanelor din tabelele
//CURSURI, respectiv STUDENTI
private List<Studenti> studenti;
public Cursuri(){
}
public long citesteCursId(){
return cursId;
}
public void scrieCursId(int i){
cursId=i;
}
86
Profesori
package celeste;
import
import
import
import
import
javax.persistence.Entity;
javax.persistence.Table;
javax.persistence.Id;
javax.persistence.Column;
java.io.Serializable;
@Entity
@Table(name="PROFESORI")
public class Profesori implements Serializable{
@Id
@Column(name="PROFESORID", nullable=false)
private int profesorId;
@Column(name="NUME")
87
private String nume;
@Column(name="PRENUME")
private String prenume;
public Profesori(){
}
public long citesteProfesorId(){
return profesorId;
}
public void scrieProfesorId(int i){
profesorId=i;
}
public String citesteNume(){
return nume;
}
public void scrieNume(String n){
nume=n;
}
public String citestePrenume(){
return prenume;
}
public void scriePrenume(String p){
prenume=p;
}
}
Profesori.java
Note
package celeste;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Id;
88
import javax.persistence.Column;
import java.io.Serializable;
@Entity
@Table(name="NOTE")
public class Note implements Serializable{
@Id
@Column(name="STUDENTID", nullable=false)
private int studentId;
@Column(name="SEMESTRUL1")
private int semestrul1;
@Column(name="SEMESTRUL2")
private int semestrul2;
@Column(name="LABORATOR")
private int laborator;
public Note(){
}
public long citesteStudentId(){
return studentId;
}
public void scrieStudentId(int i){
studentId=i;
}
public int citesteSemestrul1(){
return semestrul1;
}
public void scrieSemestrul1(int n){
semestrul1=n;
}
public int citesteSemestrul2(){
return semestrul2;
89
}
public void scrieSemestrul2(int n){
semestrul2=n;
}
public int citesteLaborator(){
return laborator;
}
public void scrieLaborator(int l){
laborator=l;
}
}
Note.java
90
package celeste;
import
import
import
import
javax.ejb.Stateless;
javax.annotation.Resource;
javax.persistence.PersistenceContext;
javax.persistence.EntityManager;
import java.util.List;
@Stateless(name="FatadaCursuri")
public class FatadaCursuriBean implements FatadaCursuri{
@PersistenceContext(unitName="CelestePersistUnit")
EntityManager em;
public String cautaTitular(int id){
Profesori titular = (Profesori)em.createNamedQuery("Cursuri.numeTitular").
setParameter("param",id).getSingleResult();
return titular.citesteNume();
}
public List<Studenti> cautaStudenti(int idCurs){
List<Studenti> listaStudenti = (List<Studenti>)em.createNamedQuery
("Cursuri.studentiInscrisi").setParameter("param",idCurs).getResultList();
return listaStudenti;
}
public Note cautaNote(int idStud){
Note note = (Note)em.createNamedQuery("Studenti.note").
setParameter("param",idStud).getSingleResult();
91
return note;
}
public List<Grades> getGradesforOneStudent(int idStud){
List<Grades> note = (List<Grades>)em.createNamedQuery("Grades.forOneStudent").
setParameter("param",idStud).getResultList();
return note;
}
}
FatadaCursuriBean.java
Compilarea entit
atilor si componentelor fatadei
C:\EJB>set CLASSPATH=.;C:\glassfishv3\glassfish\lib\javaee.jar
C:\EJB>javac -d . celeste/*.java
Definirea unit
atii de persistent
a
<persistence>
<persistence-unit name="CelestePersistUnit">
<description>
Cristinas ELEarning SysTEm.
</description>
<jta-data-source>jdbc/celeste</jta-data-source>
<class>celeste.Studenti</class>
<class>celeste.Cursuri</class>
<class>celeste.Profesori</class>
<class>celeste.Note</class>
<class>celeste.Grades</class>
</persistence-unit>
</persistence>
persistence.xml
92
Construirea arhivei
C:\EJB>jar cvf CelesteApp.jar celeste/FatadaCursuri.* ->
->celeste/FatadaCursuriBean.* celeste/Studenti.* celeste/Cursuri.* c
eleste/Profesori.* celeste/Note.* META-INF/persistence.xml
added manifest
adding: celeste/FatadaCursuri.class(in = 223) (out= 184)(deflated 17%)
adding: celeste/FatadaCursuri.java(in = 186) (out= 126)(deflated 32%)
adding: celeste/FatadaCursuriBean.class(in = 1062) (out= 584)(deflated 45%)
adding: celeste/FatadaCursuriBean.java(in = 600) (out= 302)(deflated 49%)
adding: celeste/Studenti.class(in = 1219) (out= 596)(deflated 51%)
adding: celeste/Studenti.java(in = 920) (out= 335)(deflated 63%)
adding: celeste/Cursuri.class(in = 1352) (out= 704)(deflated 47%)
adding: celeste/Cursuri.java(in = 1121) (out= 439)(deflated 60%)
adding: celeste/Profesori.class(in = 1056) (out= 549)(deflated 48%)
adding: celeste/Profesori.java(in = 784) (out= 303)(deflated 61%)
adding: celeste/Note.class(in = 1195) (out= 591)(deflated 50%)
adding: celeste/Note.java(in = 957) (out= 343)(deflated 64%)
adding: META-INF/persistence.xml(in = 353) (out= 173)(deflated 50%)
93
Exemple de clienti
package clienti;
import
import
import
import
import
import
import
celeste.FatadaCursuri;
javax.naming.InitialContext;
celeste.Cursuri;
celeste.Profesori;
celeste.Studenti;
celeste.Note;
celeste.Grades;
import java.util.List;
import java.util.ListIterator;
public class CelesteClient1{
public static void main(String[] args) throws Exception
{
InitialContext ctx = new InitialContext();
FatadaCursuri beanInstance = (FatadaCursuri)
ctx.lookup(FatadaCursuri.class.getName());
String myName=beanInstance.cautaTitular(1);
System.out.println("Hi, "
+ myName + "!");
List<Studenti> studenti = beanInstance.cautaStudenti(1);
94
Note note=beanInstance.cautaNote(1);
System.out.println("Notele: Sem.1: "+note.citesteSemestrul1()+
" Sem.2: "+note.citesteSemestrul2()+
" Lab.: "+note.citesteLaborator());
//Notele studentului cu studentId=2
List<Grades> grades = beanInstance.getGradesforOneStudent(2);
ListIterator listIterator2 = grades.listIterator();
System.out.println("Notele studentului cu studentId=2");
while(listIterator2.hasNext()){
Grades linie = (Grades)listIterator2.next();
System.out.print("ID Curs:"+linie.citesteCursId());
System.out.print(" Nota 1:"+linie.citesteSemestrul1());
System.out.print(" Nota 2:"+linie.citesteSemestrul2());
System.out.println(" Nota lab.:"+linie.citesteLaborator());
}
}
}
CelesteClient1.java
95
C:\EJB>java -classpath ->
->C:\glassfishv3\glassfish\lib\appserv-rt.jar;->
C:\glassfishv3\glassfish\lib\javaee.jar;. clienti.CelesteClient1
96
97
98
Bibliografie
[1] ***: The Java EE 5 Tutorial, http:// java.sun.com/ javaee/ 5/ docs/
tutorial/ doc/ index.html.
[2] ***: The Java EE 6 Tutorial, Volume I, http:// java.sun.com/ javaee/
6/ docs/ tutorial/ doc/ index.html.
[3] ***: glassfish: EJB FAQ, https:// glassfish.dev.java.net/ javaee5/ ejb/
EJB FAQ.html.
[4] Stefan Tanasa, Cristian Olaru, Stefan Andrei: JAVA de la 0 la expert,
Ed. Polirom, Iasi, 2003.
[5] Stefan Tanasa, Cristian Olaru: Dezvoltarea aplicatiilor Web folosind
JAVA, Ed. Polirom, Iasi, 2005.
[6] ***: jar - The JAR File Tool, Java Tool Tutorials - Herongs Tutorial Notes, http://www.herongyang.com/Java-Tools/jar-The-JAR-FileTool.html.
[7] Cristina Fierbinteanu: Programare orientata pe obiecte: Java, Editura
Universitatii Titu Maiorescu, Bucuresti, 2008.
[8] Jim Keogh: Java fara mistere, Ed.Rosetti Educational, Bucuresti, 2006.
[9] Michael J. Hernandez: Proiectarea bazelor de date, Ed. Teora, Bucuresti,
2003.
[10] Kathy Sierra, Bert Bates: Atac la Java (Head First Java Second Edition), Ed. Teora USA, 2006.
[11] Richard Monson-Haefel, Bill Burke: Enterprise JavaBeans 3.0, 5th Edition, OReilly Media, Inc., 2006.
99
100
BIBLIOGRAFIE
[12] Cristian
Frasinaru:
Curs
practic
de
Java,
http://profs.info.uaic.ro/
acf/java/Cristian FrasinaruCurs practic de Java.pdf, Ed. Matrix Rom, 2005.