Differences
This shows you the differences between two versions of the page.
| Both sides previous revision Previous revision Next revision | Previous revision | ||
|
laboratoare:laborator02 [2015/10/22 22:57] Andrei Roșu-Cojocaru |
laboratoare:laborator02 [2015/11/04 12:15] (current) Andrei Roșu-Cojocaru |
||
|---|---|---|---|
| Line 779: | Line 779: | ||
| Operațiile de comparare sunt realizate asupra valorilor la nivel de obiecte Java și nu asupra modului în care acestea sunt reprezentate în sursa de date. Din acest motiv, în clasele de tip entitate trebuie să se utilizeze tipuri de date derivate din ''Object'' care pot avea valoarea ''NULL'' și nu tipuri de date primitive care nu au această proprietate. | Operațiile de comparare sunt realizate asupra valorilor la nivel de obiecte Java și nu asupra modului în care acestea sunt reprezentate în sursa de date. Din acest motiv, în clasele de tip entitate trebuie să se utilizeze tipuri de date derivate din ''Object'' care pot avea valoarea ''NULL'' și nu tipuri de date primitive care nu au această proprietate. | ||
| + | |||
| + | <html> | ||
| + | <center> | ||
| + | </html> | ||
| ^ **TEST CONDIȚIONAL** ^ **T**rue ^ **F**alse ^ **U**nknown ^ | ^ **TEST CONDIȚIONAL** ^ **T**rue ^ **F**alse ^ **U**nknown ^ | ||
| Line 784: | Line 788: | ||
| | ''IS FALSE'' | False | True | False | | | ''IS FALSE'' | False | True | False | | ||
| | expresia este necunoscută | False | False | False | | | expresia este necunoscută | False | False | False | | ||
| + | |||
| + | <html> | ||
| + | </center> | ||
| + | </html> | ||
| **4**. **GROUP BY**: grupează valorile furnizate conform unor criterii bazate pe un set de proprietăți; | **4**. **GROUP BY**: grupează valorile furnizate conform unor criterii bazate pe un set de proprietăți; | ||
| Line 1095: | Line 1103: | ||
| ==== Eclipse Mars (4.5) ==== | ==== Eclipse Mars (4.5) ==== | ||
| - | ==== Netbeans 8.0.2 ==== | + | În mediul integrat de dezvoltare Eclipse, activarea JPA se face din meniul contextual (accesibil prin click dreapta pe denumirea sa, în //Package Explorer//) al proiectului, în care pot fi configurate proprietățile acestuia. |
| + | |||
| + | În secțiunea //Project Facets// se bifează opțiunea //JPA//. Tot aici poate fi vizualizată și versiunea curentă a acestei interfețe de programare a aplicațiilor. | ||
| + | |||
| + | {{ :laboratoare:laborator02:eclipse01.png?nolink&700 }} | ||
| + | |||
| + | În secțiunea //JPA//, pot fi controlate următoarele proprietăți: | ||
| + | * furnizorul JPA (în cazul de față, Hibernate, acesta fiind configurat din fișierul ''persistence.xml'', dacă nu există o astfel de valoare în lista de opțiuni, lăsându-se valoarea implicită //Generic 2.1//) precum și versiunea curentă a interfeței de programare a aplicațiilor; | ||
| + | * biblioteca ce oferă funcționalitatea referitoare la accesul la date (se poate alege valoarea //Disable Library Configuration// în situația în care se folosește un sistem de tip Maven); | ||
| + | * conexiunea la baza de date (acesta poate fi de asemenea configurat în fișierul ''persistence.xml''); | ||
| + | * mecanismul prin care sunt gestionate clasele persistente (descoperire automată pe baza adnotărilor, respectiv precizarea lor în fișierul ''persistence.xml''); | ||
| + | * locația la care pot fi accesate clasele metamodel. | ||
| + | |||
| + | {{ :laboratoare:laborator02:eclipse02.png?nolink&700 }} | ||
| + | |||
| + | ==== NetBeans 8.0.2 ==== | ||
| + | |||
| + | În mediul integrat de dezvoltare NetBeans, nu este necesară activarea JPA, acest lucru realizându-se în momentul în care este detectat fișierul ''persistence.xml'' în directorul ''resources/META-INF'' din codul sursă. | ||
| + | |||
| + | {{ :laboratoare:laborator02:netbeans01.png?nolink }} | ||
| + | |||
| + | Acesta poate fi editat atât în mod vizual (//Design//) cât și în mod text (//Source//). | ||
| + | |||
| + | Pot fi configurate: | ||
| + | * denumirea unității de persistență; | ||
| + | * biblioteca ce asigură funcționalitatea de acces la date; | ||
| + | * URL-ul pentru asigurarea conexiunii la baza de date; | ||
| + | * strategia de generare a tabelelor (//Create//, //Drop and Create//, //None//); | ||
| + | * strategia de validare (//Auto//, //Callback//, //None//); | ||
| + | * mecanismul de gestiune a zonei de memorie tampon partajate (//All//, //None//, //Enable Selective//, //Disable Selective//, //Unspecified//); | ||
| + | * clasele entitate care vor fi gestionate (pentru acestea, se indică calea lor completă, inclusiv pachetul din care fac parte). | ||
| + | |||
| + | {{ :laboratoare:laborator02:netbeans02.png?nolink&700 }} | ||
| ===== Activitate de Laborator ===== | ===== Activitate de Laborator ===== | ||
| Line 1102: | Line 1142: | ||
| student@aipi2015:~$ git clone https://www.github.com/aipi2015/Laborator02.git | student@aipi2015:~$ git clone https://www.github.com/aipi2015/Laborator02.git | ||
| </code> | </code> | ||
| + | |||
| + | <note important>Modificați în fișierul ''persistence.xml'' din directorul ''resources%%/%%META-INF'' informațiile necesare obținerii drepturilor de acces la baza de date (nume de utilizator, parola).</note> | ||
| + | |||
| + | **1**. Să se implementeze metoda ''getPersistentEntitySize()'' din clasa ''PersistentEntityManager'' a pachetului ''ro.pub.cs.aipi.lab02.businesslogic'' care furnizează numărul de obiecte al unei entități persistente. | ||
| + | |||
| + | <spoiler|Indicații de Rezolvare> | ||
| + | Metoda statică ''getEntityManagerFactory()'' din clasa ''Utilities'' furnizează o fabrică pentru obiecte de gestiune a entităților, unică la nivelul întregii unități de persistență. Resursele ocupate de obiectul de tip ''EntityManager'' trebuie eliberate (prin apelul metodei ''close()'') dacă acesta nu mai este necesar. | ||
| + | Se va folosi un obiect de tip ''Query'' care va întoarce un singur rezultat. | ||
| + | Limbajul JPL implică folosirea denumirii clasei de tip entitate în locul denumirii tabelei. Se poate utiliza metoda ''getSimpleName()'' pentru obiectul ''persistentEntityType'' de tip ''Class''. | ||
| + | </spoiler> | ||
| + | |||
| + | **2**. Să se implementeze metoda ''getBookList()'' din clasa ''BookManager'' a pachetului ''ro.pub.cs.aipi.lab02.businesslogic'' care furnizează lista tuturor cărților din baza de date. | ||
| + | |||
| + | Pentru fiecare volum vor fi incluse următoarele informații: | ||
| + | * identificatorul; | ||
| + | * titlul; | ||
| + | * lista autorilor (în formatul ''prenume nume''): | ||
| + | * în cazul în care nu există nici un autor, se va afișa textul ''* * *''; | ||
| + | * în cazul în care există mai mulți autori, aceștia vor fi delimitați prin șirul de caractere '', '' (virgulă și spațiu); | ||
| + | * denumirea colecției; | ||
| + | * denumirea editurii; | ||
| + | * ediția; | ||
| + | * anul de apariție; | ||
| + | * țara. | ||
| + | |||
| + | Rezultatul acestei metode este o listă de obiecte de tip ''BookInformation'' care are drept proprietăți toate informațiile solicitate sub forma unor tipuri de date primitive din limbajul Java (sau wrappere ale acestora). | ||
| + | |||
| + | Este obligatoriu să se folosească Criteria API. | ||
| + | |||
| + | <spoiler|Indicații de Rezolvare> | ||
| + | Se încarcă tot conținutul entității persistente ''Book'' (folosind metoda ''getCollection()'' din clasa ''PersistentEntityManager''), parcurgându-se ulterior lista de rezultate pentru a se extrage informațiile necesare. Pentru unele proprietăți (lista de scriitori), vor fi necesare prelucrări suplimentare, care vor fi realizate direct pe obiectele Java. | ||
| + | Este necesar ca obiectul de tip ''EntityManager'' să fie menținut atâta vreme cât este necesar să se obțină obiecte de tip referință, acestea fiind încărcate leneș. Numai după ce toate informațiile au fost încărcate din baza de date, resursele ocupate de acesta pot fi eliberate. | ||
| + | </spoiler> | ||
| + | |||
| + | **3**. Să se implementeze metoda ''create()'' din clasa ''PersistentEntityManager'' a pachetului ''ro.pub.cs.aipi.lab02.businesslogic'', pentru a stoca un nou obiect într-o tabelă a bazei de date. <code java> | ||
| + | public Long create(T persistentEntity); | ||
| + | </code> | ||
| + | Metoda primește ca parametru un obiect de tip generic (derivat din ''PersistentEntity''), conținând toate proprietățile, mai puțin cheia primară (care va fi autogenerată) și întoarce identificatorul din baza de date al entității persistente respective. | ||
| + | |||
| + | <spoiler|Indicații de Rezolvare> | ||
| + | Nu uitați să folosiți o tranzacție, care asigură atomicitatea operației și un nivel de izolare corespunzător. | ||
| + | Identificatorul poate fi obținut numai după ce obiectul a fost stocat în baza de date, **în afara tranzacției** (cu alte cuvinte, după ce a fost apelată metoda ''commit()'' - sau ''flush()''). | ||
| + | </spoiler> | ||
| + | |||
| + | **4**. Să se implementeze metoda ''updateBookPresentationPriceForBooksWithMultipleFormats()'' din clasa ''BookPresentationManager'' a pachetului ''ro.pub.cs.aipi.lab02.businesslogic'' astfel încât să mărească cu un anumit procent prețul cărților care sunt disponibile într-un număr de formate (de prezentare) mai mare decât un anumit prag. <code java> | ||
| + | public List<BookPresentationInformation> updateBookPresentationPriceForBooksWithMultipleFormats(int numberOfFormats, double amount) | ||
| + | </code> | ||
| + | Metoda primește ca parametri procentul cu care este crescut prețul cărților precum și numărul de formate pe care trebuie să îl aibă și furnizează informații referitoare la prezentările cărților pentru care au fost actualizate, stocate ca proprietăți ale clasei ''BookPresentationInformation'': | ||
| + | * identificatorul din tabela ''book_presentation''; | ||
| + | * identificatorul cărții corespunzătoare; | ||
| + | * identificatorul formatului corespunzător; | ||
| + | * prețul după modificare. | ||
| + | |||
| + | Este de preferat să se folosească Criteria API, acolo unde este posibil. | ||
| + | |||
| + | <spoiler|Indicații de Rezolvare> | ||
| + | Operațiile de creare și de ștergere a unei tabele temporare vor fi realizate folosind interogări native, întrucât JPA nu oferă suport pentru astfel de operații. Întrucât actualizarea folosește informații din tabela temporară, acestea nefiind corespunzătoare unei entități, și această operație va fi realizată tot prin intermediul unor interogări native. | ||
| + | Se va utiliza Criteria API pentru a se determina lista cărților pentru care trebuie actualizat prețul precum și pentru a se determina informațiilor solicitate după operația de actualizare. | ||
| + | </spoiler> | ||
| + | |||
| + | **5**. Să se implementeze metoda ''deleteWritersWithoutBooks()'' din clasa ''WriterManager'' a pachetului ''ro.pub.cs.aipi.lab02.businesslogic''. Metoda furnizează numărul de înregistrări care au fost modificate. | ||
| + | |||
| + | Este obligatoriu să se folosească Criteria API. | ||
| + | |||
| + | <spoiler|Indicații de Rezolvare> | ||
| + | Pentru subinterogarea din clausa WHERE se va utiliza un obiect de tip ''SubQuery''. Aceasta va furniza numărul de înregistrări din entitatea ''Author'' corespunzătoare scriitorului respectiv, fiind necesar ca acesta să fie 0. | ||
| + | </spoiler> | ||
| + | |||
| + | **6**. Să se implementeze metoda ''getWritersBibliography()'' din clasa ''WritersManager'' a pachetului ''ro.pub.cs.aipi.lab02.businesslogic'' care furnizează lista scriitorilor care au un scris un anumit număr de cărți, dintre care la unele sunt unici autori iar pe altele le-au redactat în colaborare (oricare dintre aceste valori pot fi și nule). <code java> | ||
| + | public List<WriterInformation> getWritersBibliography(int numberOfBooksTotal, int numberOfBooksAlone, int numberOfBooksCollaboration) { | ||
| + | </code> | ||
| + | |||
| + | Rezultatul acestei metode este o listă de obiecte de tip ''WriterInformation'' care are drept proprietăți toate informațiile solicitate sub forma unor tipuri de date primitive din limbajul Java (sau wrappere ale acestora). | ||
| + | |||
| + | Se vor afișa prenumele și numele autorilor, lista cărților scrise (separate prin caracterul '';''), numărul total de cărți, numărul de cărți la care este unic autor, numărul de cărți redactate în colaborare cu alții. | ||
| + | |||
| + | Informațiile vor fi ordonate (crescător) în funcție de prenumele și numele scriitorilor. | ||
| + | |||
| + | <spoiler|Indicații de Rezolvare> | ||
| + | Se determină lista tuturor scriitorilor folosind metoda ''getCollection()'' din clasa ''PersistentEntityManager''. | ||
| + | Pentru fiecare scriitor în parte, se determină - prin intermediul unei interogări - lista tuturor cărților pe care aceștia le-au scris. În situația în care numărul lucărilor la care au participat corespunde pragului impus se calculează - prin intermediul altor interogări - numărul cărților la care sunt unici autori, respectiv numărul de cărți redactate în colaborare cu alții (pentru acestea este necesar să se utilizeze subinterogări care contorizează numărul de înregistrări din entitatea ''Author'' corespunzătoare unei cărți din lista celor pe care le-a redactat un scriitor). Dacă și aceste criterii respectă condițiile, informațiile sunt incluse în rezultat. | ||
| + | </spoiler> | ||
| + | |||
| + | **7**. Să se implementeze metoda ''makeSupplyOrderBasedOnStockPile()'' din clasa ''BookPresentationManager'' a pachetului ''ro.pub.cs.aipi.lab02.businesslogic'' care creează comenzi de aprovizionare pentru cărțile al căror stoc este inferior unui anumit prag, furnizat ca parametru. O comandă de aprovizionare este realizată pentru o anumită editură și conține toate cărțile furnizate de aceasta, având stocul care respectă condiția respectivă. <code java> | ||
| + | public List<SupplyOrderInformation> makeSupplyOrderBasedOnStockpile(int stockpile); | ||
| + | </code> | ||
| + | |||
| + | Rezultatul acestei metode este o listă de obiecte de tip ''SupplyOrderInformation'' care are drept proprietăți toate informațiile solicitate sub forma unor tipuri de date primitive din limbajul Java (sau wrappere ale acestora): identificatorul editurii, identificatorul pentru prezentarea cărții, respectiv cantitatea pentru care a fost realizată comanda de aprovizionare. | ||
| + | |||
| + | Este obligatoriu să se folosească Criteria API. | ||
| + | |||
| + | <spoiler|Indicații de Rezolvare> | ||
| + | Se indentifică acele formate de prezentare ale cărților pentru care stocul nu întrunește cantitatea minimă, acestea fiind ordonate în funcție de editură. Sortarea în funcție de mai multe criterii se realizează folosind o listă de obiecte de tip [[https://docs.oracle.com/javaee/7/api/javax/persistence/criteria/Order.html|javax.persistence.criteria.Order]]. Accesul la identificatorul editurii se face prin intermediul unui obiect ''Join<Collection, PublishingHouse>'' obținut pe baza operației de asociere (prin intermediul metodei ''join()'') ce pornește de la un obiect de tipul ''BookPresentation''. | ||
| + | Se parcurge această listă, creându-se o comandă de aprovizionare atunci când se întâlnește o editură nouă. O entitate corespunzătoare va fi stocată pentru fiecare volum în parte, cantitatea fiind determinată ca diferență între pragul minim și valoarea aflată în stoc. Pentru stocarea unei valori în baza de date se va utiliza metoda ''create()'' din clasele specifice, derivate din ''PersistentEntityManager'', pentru tipurile de date corespunzătoare (''SupplyOrderHeader'', respectiv ''SupplyOrderLine''). | ||
| + | Pentru generarea unui număr de identificare se poate utiliza metoda statică ''generateIdentificationNumber()'' din clasa ''Utilities'' pentru care se specifică stuctura: numărul de caractere de tip literă, respectiv numărul de caractere de tip cifră. | ||
| + | Lista înregistrărilor stocate se poate determina pe baza datei la care acestea au fost emise (data curentă). | ||
| + | |||
| + | <note important>Este necesar să se elibereze resursele alocate pentru obiectul de tip ''EntityManager'' între operațiile de scriere, respectiv de citire a informațiilor în baza de date, pentru a se asigura faptul că interogările furnizează înregistrări actualizate.</note> | ||
| + | </spoiler> | ||
| + | |||
| + | **8**. Să se implementeze metoda ''getBookListsWithStockpile()'' din clasa ''BookManager'' a pachetului ''ro.pub.cs.aipi.lab02.businesslogic'' care furnizează lista cărților pentru care suma stocurilor (determinate din toate formatele de prezentare posibile) depășește un anumit prag, furnizat ca parametru. <code java> | ||
| + | public List<BookInformationDetailed> getBooksListWithStockpile(int stockpile) | ||
| + | </code> | ||
| + | |||
| + | Pentru fiecare volum vor putea fi consultate următoarele informații: | ||
| + | * identificatorul; | ||
| + | * titlul și subtitlul; | ||
| + | * lista autorilor; | ||
| + | * lista categoriilor; | ||
| + | * lista formatelor; | ||
| + | * lista limbilor. | ||
| + | |||
| + | Rezultatul acestei metode este o listă de obiecte de tip ''BookInformationDetailed'' care are drept proprietăți toate informațiile solicitate sub forma unor tipuri de date primitive din limbajul Java (sau wrappere ale acestora | ||
| + | |||
| + | În cazul în care o listă este vidă, se va afișa valoarea ''null''. În cazul în care o listă conține mai multe elemente, acestea vor fi delimitate prin caracterul virgulă. | ||
| + | |||
| + | Este obligatoriu să se folosească Criteria API. | ||
| + | |||
| + | <spoiler|Indicații de Rezolvare> | ||
| + | Se determină cărțile pentru care suma stocurilor corespunzătoare diferitelor tipuri de prezentări întrunește condiția specificată. | ||
| + | Pentru fiecare carte în parte se determină informațiile solicitate. Datele precum formatul și limba vor fi obținute unei interogări adiționale prin care se realizează asocierea dintre entitățile ''Book'' și ''BookPresentation''. | ||
| + | </spoiler> | ||
| ===== Resurse ====== | ===== Resurse ====== | ||
| Line 1122: | Line 1284: | ||
| ===== Soluții ===== | ===== Soluții ===== | ||
| - | TODO | + | [[https://github.com/aipi2015/Laborator02/tree/master/solutions/eclipse/02-BookStore-JPA|Proiect Eclipse]]\\ |
| + | [[https://github.com/aipi2015/Laborator02/tree/master/solutions/netbeans/02-BookStore-JPA|Proiect NetBeans]] | ||
