Kermek_NWTiS_20_EE_JPA.pdf

Full Transcript

Napredne Web tehnologije i servisi Prof.dr.sc. Dragutin Kermek Sveučilište u Zagrebu Fakultet organizacije i informatike Pavlinska 2, Varaždin 42000 [email protected] Jakarta Persistence API - JPA...

Napredne Web tehnologije i servisi Prof.dr.sc. Dragutin Kermek Sveučilište u Zagrebu Fakultet organizacije i informatike Pavlinska 2, Varaždin 42000 [email protected] Jakarta Persistence API - JPA Napredne Web tehnologije i servisi 2 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Spremanje u OODBMS Napredne Web tehnologije i servisi 3 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Spremanje u RDBMS Napredne Web tehnologije i servisi 4 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Neslaganje koncepta (impendancije) Objektni model Relacijski model Objekti Tablice Nasljeđivanje Ključevi Veze Procedure Napredne Web tehnologije i servisi 5 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Preslikavanje objekti/relacije Preslikavanje objekti/relacije je automatsko i transparentno pohranjivanje objekata iz aplikacije u tablice relacijske baze podataka, koristeći metapodatke koji definiraju način preslikavanja između objekata i baze podataka. Bauer, King; Hibernate in action Napredne Web tehnologije i servisi 6 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Preslikavanje objekti/relacije Napredne Web tehnologije i servisi 7 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Java Persistence Java Persistence pruža mogućnosti za objektno/relacijsko povezivanje/preslikavanje kako bi Java razvojni inženjeri mogli upravljati relacijskim podacima u Java aplikacijama primjenjujući objektno orijentiranu paradigmu. Java perzistencija/upornost sastoji se od 4 područja: Java Persistence API (JPA) upitni jezik Java Persistence Criteria API metapodaci objektno/relacijskog preslikavanja Napredne Web tehnologije i servisi 8 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Entity bean (EB) Entity bean je trajan objekt koji predstavlja podatke koje se održavaju u spremištu podataka: njegov fokus je usmjeren na podatke. Entity bean može upravljati vlastitim trajanjem ili može delegirati tu funkciju svojem kontejneru (? EJB < 3.0). Entity bean je identificiran primarnim ključem. Ako padne kontejner u kojem se nalazi entity bean tada entity bean, primarni ključ i bilo koja udaljena referenca prežive pad. U EJB v.3 dolazi do redefiniranja EJB s obzirom na uvođenje perzistencije (JPA – Java Persistence API) POJO – Plain Old Java Object Napredne Web tehnologije i servisi 9 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Korištenje EB u klijentima Klijent EB može dobaviti referencu instance EB putem: dependency injection – koristeći anotacije Java programskog jezika JNDI pogleda – koristeći JNDI sintaksu za traženje instance EB. Postoje tri prostora naziva: java:global, java:module, and java:app Napredne Web tehnologije i servisi 10 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Upiti  JPQL – Jakarta Persistence Query Language  Objektno orijentirani upitni jezik  Projekcije, sortiranje, grupiranje, agregatne funkcije, straničenje  Criteria API  Programsko kreiranje upita  Rad bez poznavanja SQL  SQL  Korištenje RDBMS specifičnih funkcija  Optimizacija upita Napredne Web tehnologije i servisi 11 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Mogući nedostaci  Strma krivulja učenja (kasnije se vide rezultati)  Performanse (važno je dobro podesiti konfiguraciju)  Nije svemoguće Napredne Web tehnologije i servisi 12 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Pružatelji perzistentncije  Hibernate - https://hibernate.org/  EclipseLink - https://www.eclipse.org/eclipselink/  OpenJPA - http://openjpa.apache.org/  ObjectDB – https://www.objectdb.com/  DataNucleus - https://www.datanucleus.org/ Usporedba brzine JPA uz korištenje određene baze podataka http://www.jpab.org/All/All/All.html Napredne Web tehnologije i servisi 13 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Primjer sheme segmenta baze podataka POLAZNICI_ POLAZNICI GRUPE GRUPE Napredne Web tehnologije i servisi 14 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Tablice CREATE TABLE polaznici ( kor_ime varchar(10) NOT NULL DEFAULT '', ime varchar(25) NOT NULL DEFAULT '', prezime varchar(25) NOT NULL DEFAULT '', lozinka varchar(20) NOT NULL DEFAULT '', email_adresa varchar(40) NOT NULL DEFAULT '', vrsta int NOT NULL DEFAULT 1, datum_kreiranja timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, datum_promjene timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', PRIMARY KEY (kor_ime)); CREATE TABLE grupe ( gr_ime varchar(10) NOT NULL DEFAULT '', naziv varchar(25) NOT NULL DEFAULT '', PRIMARY KEY (gr_ime)); CREATE TABLE polaznici_grupe ( kor_ime varchar(10) NOT NULL DEFAULT '', gr_ime varchar(10) NOT NULL DEFAULT '', PRIMARY KEY (kor_ime,gr_ime), CONSTRAINT polaznici_grupe_FK1 FOREIGN KEY (kor_ime) REFERENCES polaznici (kor_ime), CONSTRAINT polaznici_grupe_FK2 FOREIGN KEY (gr_ime) REFERENCES grupe (gr_ime)); Napredne Web tehnologije i servisi 15 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Entitet - Polaznici @Entity @Table(name = "POLAZNICI") @NamedQueries({... }) public class Polaznici implements Serializable { private static final long serialVersionUID = 1L; @Id @Basic(optional = false) @Column(name = "KOR_IME") private String korIme; @Basic(optional = false) @Column(name = "IME") private String ime; @Basic(optional = false) @Column(name = "PREZIME") private String prezime; @Basic(optional = false) @Column(name = "LOZINKA") private String lozinka; @Basic(optional = false) @Column(name = "EMAIL_ADRESA") private String emailAdresa; @Basic(optional = false) Napredne Web tehnologije i servisi 16 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Entitet – Polaznici / 2 @Column(name = "VRSTA") private int vrsta; @Column(name = "DATUM_KREIRANJA") @Temporal(TemporalType.TIMESTAMP) private Date datumKreiranja; @Column(name = "DATUM_PROMJENE") @Temporal(TemporalType.TIMESTAMP) private Date datumPromjene; @ManyToMany(mappedBy = "polazniciList") private List grupeList; Napredne Web tehnologije i servisi 17 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Entitet – Polaznici / 3 public Polaznici() { } public Polaznici(String korIme) { this.korIme = korIme; } public Polaznici(String korIme, String ime, String prezime, String lozinka, String emailAdresa, int vrsta) { this.korIme = korIme; this.ime = ime; this.prezime = prezime; this.lozinka = lozinka; this.emailAdresa = emailAdresa; this.vrsta = vrsta; } Napredne Web tehnologije i servisi 18 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Entitet – Polaznici / 4 public String getKorIme() { return korIme; } public void setKorIme(String korIme) { this.korIme = korIme; }... public List getGrupeList() { return grupeList; } public void setGrupeList(List grupeList) { this.grupeList = grupeList; } @Override public int hashCode() { int hash = 0; hash += (korIme != null ? korIme.hashCode() : 0); return hash; } Napredne Web tehnologije i servisi 19 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Entitet – Polaznici / 5 @Override public boolean equals(Object object) { if (!(object instanceof Polaznici)) { return false; } Polaznici other = (Polaznici) object; if ((this.korIme == null && other.korIme != null) || (this.korIme != null && !this.korIme.equals(other.korIme))) { return false; } return true; } @Override public String toString() { return "org.foi.nwtis.dkermek.ejb.eb.Polaznici[korIme=" + korIme + "]"; } } Napredne Web tehnologije i servisi 20 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Entitet – Grupe @Entity @Table(name = "GRUPE") @NamedQueries({...}) public class Grupe implements Serializable { private static final long serialVersionUID = 1L; @Id @Basic(optional = false) @Column(name = "GR_IME") private String grIme; @Basic(optional = false) @Column(name = "NAZIV") private String naziv; @JoinTable(name = "POLAZNICI_GRUPE", joinColumns = { @JoinColumn(name = "GR_IME", referencedColumnName = "GR_IME")}, inverseJoinColumns = { @JoinColumn(name = "KOR_IME", referencedColumnName = "KOR_IME")}) @ManyToMany private List polazniciList; Napredne Web tehnologije i servisi 21 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Entitet – Grupe/ 2 public Grupe() { } public Grupe(String grIme) { this.grIme = grIme; } public Grupe(String grIme, String naziv) { this.grIme = grIme; this.naziv = naziv; }... @Override public String toString() { return "org.foi.nwtis.dkermek.ejb.eb.Grupe[grIme=" + grIme + "]"; } } Napredne Web tehnologije i servisi 22 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Entiteti Entitet je lagano perzistentni objekt iz domene. Tipično jedan entitet predstavlja tablicu u relacijskoj bazi podataka, a svaka instanca entiteta odgovara retku u toj tablici. Primarni programski artefakt jednog entiteta je klasa entiteta premda entiteti mogu koristiti pomoćne klase (tzv. helper). Napredne Web tehnologije i servisi 23 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Zahtjevi za klasom entiteta Klasa entiteta mora ispuniti sljedeće zahtjeve: klasa mora biti anotirana s anotacijom @Entity klasa mora imati javnog ili zaštićenog konstruktora bez argumenata. Može imati i druge konstruktore klasa ne smije biti deklarirana s final. Metode ni perzistentne varijable ne smiju biti deklarirane s final ako se instanca entiteta prenosi po vrijednosti kao prikačeni objekt, preko udaljenog poslovnog sučelja session bean-a, klasa mora implementirati sučelje Serializable entiteti mogu proširivati klase entiteta i klase neentiteta, i klase neentiteta mogu proširivati klase entiteta varijable perzistentnih instanci moraju biti deklarirane kao privatne, zaštićene ili privatne za pakete, i mogu biti pristupane samo direktno od metoda klase entiteta. Klijenti moraju pristupati stanju entiteta putem metoda za pristup ili poslovnim metoda (kao JavaBean komponenta) Napredne Web tehnologije i servisi 24 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Perzistentne osobine Ako klasa entiteta koristi perzistentne osobine, entiteti moraju slijediti konvenciju metoda JavaBean komponenti (getter-i i setter-i). Anotacije objektno relacijskog preslikavanja moraju biti primjenjene na get metode. Anotacije preslikavanja ne mogu biti primijenjene na polja (atribute, osobine) koje su anotirane s @Transient ili označena s Java transient. Napredne Web tehnologije i servisi 25 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Korištenje kolekcija u poljima i osobine entiteta Polja (atributi, osobine) s kolekcijskim vrijednostima moraju podržavati sučelja Java kolekcija: java.util.Collection java.util.Set java.util.List java.util.Map Mogu se koristiti generičke varijante. Ako polje (atribut, osobina) entiteta sadrži kolekciju osobnih tipova ili ugrađene klase, koristi se anotacija @ElementCollection. Ta anotacija ima dva atributa: targetClass i fetch. Prvi atribut je opcionalan i određuje naziv klase. Opcionalnim atributom fetch određuje se način dobavljanja kolekcije: LAZY – lijeno, što kasnije, osnovno EAGER – revno, žurno, što prije Napredne Web tehnologije i servisi 26 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Entiteti Perzistentnom stanju entiteta može se pristupati preko varijabli instance eniteta ili putem osobina Java Beans stila. Polja (atributi ili osobine) mogu biti: Java primitivni tipovi java.lang.String drugi serijalizirani tipovi: omotači Java primitivnih tipova java.math.BigInteger, java.math.BigDecimal, java.util.Date, java.utl.Calendar, java.sql.Date, java.sql.Time, java.sql.TimeStamp korisničko definirani serijalizirani tipovi byte[], Byte[], char[], Character[] enumerirani tipovi drugi entiteti i/ili kolekcije entiteta ugrađene klase Napredne Web tehnologije i servisi 27 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Entiteti Svaki entitet ima jednoznačan identifikator objekta, primarni ključ. Jednostavni primarni ključ koristi anotaciju @Id kako bi odredio polje (atribut, osobinu) primarnog ključa. Složeni primarni ključ sastoji se od više od jednog atributa koji odgovaraju skupu pojedinačnih perzistentnih polja (atributa, osobina). Složeni primarni ključ mora biti definiran u klasi primarnog ključa i označava se korištenjem anotacija @EmbeddedId i @IdClass. Napredne Web tehnologije i servisi 28 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Primarni ključ entiteta Perzistentna polja (atributi, osobine) složenog primarnog ključa mogu biti: Java primitivni tipovi omotači Java primitivnih tipova java.lang.String java.util.Date (privremeni tip treba biti DATE) java.sql.Date, java.math.BigInteger, java.math.BigDecimal Napredne Web tehnologije i servisi 29 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Klase primarnog ključa Klasa primarnog ključa mora ispuniti zahtjeve: klasa mora biti public Osobine (atributi) klase primarnog ključa moraju biti public ili protected ako se koristi pristup na temelju osobina klasa mora imati osnovni konstruktor klasa mora implementirati metode hashCode() i equals(Object other) klasa mora biti serializirana složeni primarni ključ mora biti reprezentiran i preslikan na više polja (atributa, osobina) klase entiteta ili mora biti reprezentiran i preslikan na ugrađenu klasu ako je klasa preslikana na više polja (atributa, osobina) klase entiteta, nazivi i tipovi polja primarnog ključa ili osobina u primarnom ključu moraju odgovarati toj klasi entiteta Napredne Web tehnologije i servisi 30 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Veze entiteta Postoje 4 vrste odnosa: jedan-na-jedan – anotacija @OneToOne jedan-na-više - anotacija @OneToMany više-na-jedan - anotacija @ManyToOne više-na-više - anotacija @ManyToMany Napredne Web tehnologije i servisi 31 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Smjer u vezama entiteta Postoje 2 vrste smjerova: dvosmjerna veza (Bidirectional Relationship) – svaki entitet ima polje veze ili osobinu koje se referencira na drugi entitet. Putem polja veze ili osobine, programski kod klase entiteta može pristupiti njegovim povezanim objektima jednosmjerna veza (Unidirectional Relationship) – samo jedan entitet ima polje veze ili osobinu koja se referencira na drugi. Napredne Web tehnologije i servisi 32 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Kaskadne operacije Entiteti koji koriste veze često ovise o postojanju drugog entiteta u vezi. Enumetirani tip jakarta.persistence.CascadeType definira kaskadne operacije koje se primjenjuju na kaskadni element u anotacijama veza. Kaskadne operacije mogu biti : ALL – sve kaskadne operacije bit će primijenjene na entitet koji je povezan na roditeljev entitet. Isto kao {DETACH, MERGE, PERSIST, REFRESH, REMOVE} DETACH – ako je entitet roditelja odvojen od perzistentnog konteksta, tada će i povezani entitet biti odvojen MERGE - ako je entitet roditelja udružen u perzistentni kontekst, tada će i povezani entitet biti udružen PERSIST - ako je entitet roditelja perzistentan u perzistentnom kontekstu, tada će i povezani entitet biti perzistentan REFRESH - ako je entitet roditelja osvježen u perzistentnom kontekstu, tada će i povezani entitet biti osvježen REMOVE - ako je entitet roditelja obrisan iz perzistentnog konteksta, tada će i povezani entitet biti obrisan Napredne Web tehnologije i servisi 33 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Brisanje siročića u vezama Kada je ciljni entitet u vezi 1-na-1 ili 1-na-n obrisan iz veze, može biti poželjno da se kaskadno provede operacija brisanja za ciljni entitet. Takvi entiteti smatraju se “siročićima” te se atribut orphanRemoval može koristiti da se odredi da takvi entiteti budu obrisani. Napredne Web tehnologije i servisi 34 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Ugrađene klase u entitetima Ugrađene klase koriste se za predstavljanje stanja entiteta ali ne trebaju imati vlastiti perzistentni identitet. Instance ugrađene klase dijele identitet entiteta koji im je vlasnik. Ugrađene klase postoje samo dok postoji stanje drugog entiteta. Entitet može imati atribute ugrađene klase kao pojedinačnu vrijednost ili kolekciju vrijednosti. Ugrađene klase mogu imati ista pravila kao klase entiteta osim što su anotirane s @Embeddable umjesto @Entity Napredne Web tehnologije i servisi 35 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Nasljeđivanje entiteta Entiteti podržavaju nasljeđivanje, polimorfne asocijacije i polimorfne upite. Oni mogu proširiti klase koje nisu entiteti kao što i klase koje nisu entiteti mogu nasljeđivati klase entiteta. Klase entiteta mogu biti apstraktne i konkretne. Astraktni entiteti ne mogu biti instancirani. Entiteti mogu nasljeđivati od superklasa koje sadrže perzistentno stanje i informacije preslikavanja, ali nisu entiteti (i anotirani s @Entity). Takve superklase često se koriste kada postoji stanje i informacije preslikavanja koje su zajedničke za više klasa entiteta. Takva superklasa se anotira s @MappedSuperClass Napredne Web tehnologije i servisi 36 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Upravljanje entitetima Entitetima upravlja upravljač entiteta, koji se predstavlja instancama jakarta.persistence.EntityManager. Svaka instanca EntityManager-a pridružena je perzistentnom kontekstu, koji definira vidljivost pod kojom je pojedinačna instanca entiteta kreirana, perzistentna i obrisana. Perzistenti kontekst je skup upravljanih instanci entiteta koje postoje u pojedinačnom spremištu podataka. Sučelje EntityManager određuje metode koje se mogu koristiti za interakciju s perzistentnim konteksom. EntityManager API kreira i briše instance perzistentnog entiteta, traži entitet po primarnom ključu entiteta i dopušta upitima da se izvršavaju nad entitetima. Napredne Web tehnologije i servisi 37 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin EntityManager upravljan kontejnerom Perzistentni kontekst instance EntityManager-a se automatski propagira od kontejnera za sve komponente aplikacije koje koriste instancu EntityManager-a unutar pojedinačne Jakarta Transaction Architecture (JTA) transakcije. JTA transakcija obično uključuje pozive nad komponentama aplikacije, a za dovršenje transakcije te komponente obično trebaju pristup do pojedinačnog perzistentnog konteksta. To se događa kada je EntityManager stavljen u aplikacijsku komponentu putem anotacije @PersistanceContext. Automatskim propagiranjem perzistentnim kontekstom aplikacijske komponente ne trebaju jedna drugoj prenositi reference za instancu EntityManager-a kako bi se obavile promjene u pojedinačnoj transakciji. Jakarta EE kontejner upravlja životnim ciklusom EntityManager-a koji su upravljani kontejnerom. Napredne Web tehnologije i servisi 38 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin EntityManager upravljan aplikacijom Perzistentni kontekst instance EntityManager-a NE propagira se za komponente aplikacije, nego aplikacija upravlja životnim ciklusom instance EntityManager –a. EntityManager upravljan aplikacijom koristi se kada aplikacije trebaju pristup do perzistentnog konteksta koji nije propagiran s JTA transakcijom kroz instancu EntityManager –a u pojedinačnu perzistentnu jedinicu. U ovom slučaju svaki EntityManager kreira novi, izolirani perzistentni kontekst. EntityManager i njemu pridruženi perzistentni kontekst, kreiran je i brisan ekspicitno od aplikacije. Ova vrsta također se koristi kada se želi postići sigurnost budući da instance EntityManager nisu sigurne kod dretvi (thread-safe). U tom slučaju aplikacije kreiraju instance EntityManager-a korištenjem metode createEntityManager() iz jakarta.persistence.EntityManagerFactory. Prije toga potrebno je pribaviti instancu gornje klase dodavanjem anotacije jakarta.persistence.PersistanceUnit. Napredne Web tehnologije i servisi 39 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin EntityManager upravljan aplikacijom EntityManager upravljan aplikacijom ne propagira automatski JTA transakcijski kontekst pa aplikacije trebaju ručno pristupiti JTA transkacijskom upravljaču i dodati transakcijsku demarkacijsku informaciju kada obavlja operacije s entitetom. Sučelje jakarta.transaction.UserTransaction određuje metode za početak, potvrdu i vraćanje transakcija. Instanca UserTransaction dodaje se tako da se kreira instanca varijable koja je anotirana s @Resource. Napredne Web tehnologije i servisi 40 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Perzistentne jedinice Perzistentna jedinica definira skup svih klasa entiteta koje su upravljane od instance EntityManager-a u aplikaciji. Taj skup klasa entiteta predstavlja podatke koji su sadržani u pojedinačnom spremištu podataka. Perzistentne jedinice definirane su u konfiguracijskoj datoteci persistence.xml. JAR datoteka ili direktorij čiji META-INF direktorij sadrži spomenutu datoteku naziva se korijen perzistentne jedinice. Vidljivost perzistentne jedinice određena je korijenom perzistentne jedinice. Svaka perzistentna jedinica mora biti identificirana s nazivom koji je jednoznačan za vidljivost perzistentne jedinice. Perzistentne jedinice mogu biti pakirane kao dio WAR ili EJB jar datoteke, ili kao JAR datoteka koja je tada uključena u WAR ili EAR datoteku. Napredne Web tehnologije i servisi 41 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin persistence.xml org.eclipse.persistence.jpa.PersistenceProvider jdbc/nwtis false Napredne Web tehnologije i servisi 42 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Osnovne operacije s entitetima Osnovne operacije s entitetima su: kreiranje, pretraživanje ažuriranje brisanje. Često se objedinjuju pod akronimom CRUD. Postoji više načina provođenja operacija s entitetima. Jedan od njih je putem instanci posebnih pomoćnih klasa tzv. Facade. To su klase koje implementiraju razne metode za rad s entitetima, a obično uz naziv klase entiteta imaju sufiks Facade, npr. za klasu entiteta Polaznici to je klasa PolazniciFacade. Te klase u Jakarta EE web profilu su anotirane kao @RequestScoped, a u Jakarta EE platform profilu kao @Stateless Napredne Web tehnologije i servisi 43 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin CRUD entiteta public abstract class AbstractFacade { private Class entityClass; public AbstractFacade(Class entityClass) { this.entityClass = entityClass; } protected abstract EntityManager getEntityManager(); public void create(T entity) { getEntityManager().persist(entity); } public void edit(T entity) { getEntityManager().merge(entity); } public void remove(T entity) { getEntityManager().remove(getEntityManager().merge(entity)); } public T find(Object id) { return getEntityManager().find(entityClass, id); }... Napredne Web tehnologije i servisi 44 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin CRUD entiteta @RequestScoped public class PolazniciFacade extends AbstractFacade { @PersistenceContext(unitName = "nwtis_pu") private EntityManager em; protected EntityManager getEntityManager() { return em; } public PolazniciFacade() { super(Polaznici.class); } } Napredne Web tehnologije i servisi 45 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin CRUD entiteta Kreiranje novog objekta: PolazniciFacade pf = new PolazniciFacade(); Polaznici polaznik = new Polaznici(“pero”, “Pero”, “Kos”, “123456”, “[email protected]”, 0); pf.create(polaznik); Pretraživanje objekta: PolazniciFacade pf = new PolazniciFacade(); Polaznici polaznik = pf.find(“pero”); Napredne Web tehnologije i servisi 46 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Java Persistence Query Language JP upitni jezik (JPQL) određuje upite za entitete i njihova perzistentna stanja. Upitni jezik dopušta pisanje prenosivih upita koji rade bez obzira na temeljno spremište podataka. Upitni jezik koristi apstraktne sheme perzistencije entiteta (uključujući njihove veze) za svoj model podataka, i definira operatore i izraze koji se temelje na tom modelu podataka. Upitni jezik koristi sintaksu koja sliči SQL-u za selekciju objekata ili vrijednosti na temelju apstraktne sheme podataka entiteta i veza između njih. Napredne Web tehnologije i servisi 47 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Terminologija upitnog jezika Apstraktna shema – perzistentna shema asptrakcije (perzistentni entiteti, njihova stanja i veze) nad kojima djeluju upiti. Upitni jezik prevodi upite nad tom shemom u upite koji se izvršavaju nad shemom baze podataka na koju se entiteti preslikavaju Apstraktni tip sheme – svi izrazi se evaluiraju u tip. Apstraktni tip sheme nekog entiteta se izvodi iz klase entiteta i informacija iz metapodatka koje pružaju anotacije Java jezika Backus-Naur Form (BNF) – notacija koja opisuje sintaksu viših jezika. Navigacija – putovanje veza u izrazu upitnog jezika. Operator navigacije je točka (.) Izraz putanje – izraz koji navigira do stanja polja entiteta ili veze. Stanje polja – perzistentno polje (atribut) entiteta Polje veze – perzistentno polje (atribut) veze nekog entiteta čiji tip je apstraktni tip sheme povezanog entiteta. Napredne Web tehnologije i servisi 48 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Kreiranje JPQL upita Metoda EntiteManager.createQuery koriste se za dinamičke upite nad spremištem podataka korištenjem upita JPQL Metoda EntiteManager.createNamedQuery koriste se za statičke upite nad spremištem podataka korištenjem upita JPQL Prefiksom : ispred parametra određuje se imenovani parametar u upitu. Prefiksom ? ispred broja određuje se pozicionirani parametar u upitu. Napredne Web tehnologije i servisi 49 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Kreiranje JPQL upita @RequestScoped public class PolazniciFacade { @PersistenceContext(unitName = "nwtis_pu") private EntityManager em; public List findAll(String prezime, String ime) { return em.creatQeuery( "SELECT p FROM Polaznici p WHERE p.prezime " + "like :prezime and p.ime like :ime ").setParameter("prezime", prezime).setParameter("ime", ime).getResultList(); } Napredne Web tehnologije i servisi 50 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Kreiranje JPQL upita @RequestScoped public class PolazniciFacade { @PersistenceContext(unitName = „nwtis_pu") private EntityManager em; private CriteriaBuilder cb; @PostConstruct private void init() { cb = em.getCriteriaBuilder(); } public List findAll(String prezime, String ime) { return em.creatQeuery( "SELECT p FROM Polaznici p WHERE p.prezime " + "like ?1 and p.ime like ?2 ").setParameter(1, prezime).setParameter(2, ime).getResultList(); } Napredne Web tehnologije i servisi 51 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Kreiranje JPQL upita Za statičke upite koristi se anotacija @NamedQuery @Entity @Table(name = "POLAZNICI") @NamedQueries({ @NamedQuery( name = "Polaznici.findByPrezimeIme", query = "SELECT p FROM Polaznici p WHERE p.prezime “ + “like :prezime and p.ime like :ime“),... public class Polaznici implements Serializable {... } Napredne Web tehnologije i servisi 52 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Criteria API Criteria API se koristi za definiranje upita za entitete i njihovo perzistentno stanje kreiranjem upitnih objekata. Criteria API temelji se na apstraktnoj shemi perzistentne entiteta, njihovim vezama i ugrađenim objektima. Criteria API djeluje nad apstraktnom shemom tako da dopušta razvojnim inženjerima da pronalaze, mijenjaju i brišu entitete putem poziva operacija za entitete iz JP API. Criteria API i JPQL blisko su povezani i dizajnirani su da dopuste slične operacije u njihovim upitima. Razvojni inženjeri koji su upoznati sa sinteksom JPQL pronaći će ekvivalentne operacije na razini objekta u Criteria API. Napredne Web tehnologije i servisi 53 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Kreiranje Criteria API upita Instanca EntityManeger kreira objekt Primjer za upit SELECT p FROM Polaznici p: CriteriaBuilder Kreiranje upitnog objekta za kreiranje public List findAll() { instance sučelja CriteriaQuery, 1. CriteriaBuilder cb = em.getCriteriaBuilder(); čiji će objekti biti podešeni s detaljima 2. CriteriaQuery cq = cb.createQuery(); objekta 3. Root polaznici = cq.from(Polaznici.class); 4. cq.select(polaznici); Postavljanje korijena upita pozivom metode 5. TypedQuery q = em.createQuery(cq); from na objektu CriteriaQuery 6. List allPolaznici = em.getResultList(); return allPolaznici } Izvršavanje upita pozivom metode Priprema upita za getResultList na izvršavanje objektu kreiranjem instance TypedQuery, Određivanje kojeg će TypedQuery, budući da upit vraća tipa biti rezultat upita određivanjem tipa kolekciju entiteta pozivom metode spremljenih u objekt select na objektu rezultata upita List. CriteriaQuery Napredne Web tehnologije i servisi 54 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Kreiranje Criteria API upita 1. Instanca EntityManeger kreira objekt CriteriaBuilder 2. Kreiranje upitnog objekta za kreiranje instance sučelja CriteriaQuery, čiji će objekti biti podešeni s detaljima objekta 3. Postavljanje korijena upita pozivom metode from na objektu CriteriaQuery 4. Određivanje kojeg će tipa biti rezultat upita pozivom metode select na objektu CriteriaQuery 5. Priprema upita za izvršavanje kreiranjem instance TypedQuery, određivanjem tipa rezultata upita 6. Izvršavanje upita pozivom metode getResultList na objektu TypedQuery, budući da upit vraća kolekciju entiteta spremljenih u objekt List. Napredne Web tehnologije i servisi 55 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Kreiranje Criteria API upita Skraćeni postupak za upit SELECT p FROM Polaznici p: public List findAll() { CriteriaQuery cq = cb.createQuery(Polaznici.class); cq.select(cq.from(Polaznici.class)); return em.createQuery(cq).getResultList(); } Napredne Web tehnologije i servisi 56 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Kreiranje Criteria API upita Osnovna sementika Criteria upita sastoji se od klauzula SELECT i FROM, te opcionalno WHERE, što je slično JPQL. Criteria upiti postavljaju klauzule korištenjem objekata Java programskog jezika tako da se upiti mogu kreirati na siguran način s obzirom na tip. Sučelje jakarta.persistence.criteria.CriteriaBuilder koristi se za konstrukciju: Criteria upita selekcije izraze predikate sređivanje Napredne Web tehnologije i servisi 57 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Kreiranje Criteria API upita Upit se obično postavlja za objekt klase entiteta (tablica) CriteriaQuery cq = cb.createQuery(Polaznici.class); Upit se može postaviti za objekt osvnovne klase kao što je Long, String, i sl. CriteriaQuery cq = cb.createQuery(Long.class); Napredne Web tehnologije i servisi 58 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Vrste Criteria API upita Postoje dvije vrste/načina kreiranje Criteria API upita: pomoću Metamodela API pomoću stringova. Napredne Web tehnologije i servisi 59 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Criteria API upiti s Metamodel API Da bi se mogao koristiti Metamodel potrebno je dodati ovisnosti (primjer na EclipseLink) koja će obaviti generiranje potrebnih klasa metamodela (nakon naziva klase imaju nastavak _, npr. za klasu Polaznici geneira se Polaznici_. Generirane datoteke izvornog koda nalaze se unutar target direktorija projekta org.eclipse.persistence org.eclipse.persistence.jpa.modelgen.processor 4.0.2 provided Napredne Web tehnologije i servisi 60 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Criteria API upiti s Metamodel API @Generated(value="org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProcessor", date="2024-05-20T06:23:27", comments="EclipseLink-4.0.2.v20230616- r3bfa6ac6ddf76d7909adc5ea7ecaa47c02c007ed") @StaticMetamodel(Polaznici.class) @SuppressWarnings({"rawtypes", "deprecation"}) public class Polaznici_ { public static volatile SingularAttribute ime; public static volatile SingularAttribute prezime; public static volatile SingularAttribute lozinka; public static volatile SingularAttribute datumPromjene; public static volatile ListAttribute grupeList; public static volatile SingularAttribute datumKreiranja; public static volatile SingularAttribute maticniBroj; public static volatile SingularAttribute emailAdresa; } Napredne Web tehnologije i servisi 61 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Criteria API upiti s Metamodel API Polazi se od preuzimanja Metamodela te se na bazi njega dohvaćaja tip entiteta putem kojem se dohvaćaju određeni podaci (npr. naziv stupca tj. varijable i sl). To je sigurnija varijanta od one sa stringom jer kompilator provjerava ispravnost koda. CriteriaQuery cq = cb.createQuery(Polaznici.class); Metamodel m = em.getMetamodel(); EntityType Polaznici_ = m.entity(Polaznici.class); Root polaznici = cq.from(Polaznici.class); Join grupe = polaznici.join(Polaznici_.grupa); Napredne Web tehnologije i servisi 62 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Criteria API upiti sa stringom Polazi se od dohvaćanja korijenskog podatka (klase/tablice) na bazi CriteriaQuery te se pojedini stupci/atributi dohvaćaju svojim nazivom. u obliku stringa: CriteriaQuery cq = cb.createQuery(Polaznici.class); Root polaznici = cq.from(Polaznici.class); Expression zaPrezime = polaznici.get("prezime"); Expression zaIme = polaznici.get("ime”); cq.where(cb.and(cb.like(zaPrezime, prezime), cb.like(zaIme, ime))); TypedQuery q = em.createQuery(cq); return q.getResultList(); Napredne Web tehnologije i servisi 63 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Kreiranje upita korištenjem JOIN Za upite koji povezuju klase entiteta potrebno je definirati spoj na povezani entitet pozivom jedne od From.join metoda na korijenskom objektu upita ili drugom spojenom objektu. Metode join slične su JOIN ključnoj riječi u JPQL. Cilj spajanje koristi klasu Metamodel tipa EntityType za određivanje perzistentnog polja ili osobine spojenog entiteta. Metode join vraćaju objekt tip Join, pri čemu je X izvorni entitet a Y cilj spajanja. CriteriaQuery cq = cb.createQuery(Polaznici.class); Metamodel m = em.getMetamodel(); EntityType Polaznici_ = m.entity(Polaznici.class); Root polaznici = cq.from(Polaznici.class); Join grupe = polaznici.join(Polaznici_.grupa); Napredne Web tehnologije i servisi 64 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Navigacija putanje u Criteria upitima Objekti putanje koriste se u SELECT i WHERE u Criteria upitima i mogu biti korijenski entiteti upita, spojeni entiteti ili ostali Path objekti. Metoda Path.get koristi se za navigaciju atributa entiteta upita. Argumenti metode get odgovaraju atributima klase Metamodela entiteta. Atributi mogu biti: s jednostavnim vrijednostima, određeno s @SingularAttribute u klasi Metomodela kolekcija vrijednosti, određeno s @CollectionAttribute, @SetAttribute, @ListAttribute ili @MapAttribute CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery cq = cb.createQuery(String.class); Metamodel m = em.getMetamodel(); EntityType Polaznici_ = m.entity(Polaznici.class); Root polaznici = cq.from(Polaznici.class); cq.select(polaznici.get(Polaznici_.prezime)); Napredne Web tehnologije i servisi 65 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Ograničavanje rezultata Criteria upita Rezultati upita mogu se ograničiti na objektu CriteriaQuery prema uvjetima koji su postavljeni pozivom CriteriaQuery.where metode, koja je analogna postavljenju WHERE u JPQL. Metoda where ispituje instance sučelja Expression kako bi ograničila rezultate prema uvjetima u izrazima. Instance Expression kreiraju se korištenjem metoda koje su definirane u sučeljima Expression i CriteriaBuilder. Uvjetne metode u sučelju Expression: isNull isNotNull in. Napredne Web tehnologije i servisi 66 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Ograničavanje rezultata Criteria upita CriteriaQuery cq = cb.createQuery(String.class); Metamodel m = em.getMetamodel(); EntityType Polaznici_ = m.entity(Polaznici.class); Root polaznici = cq.from(Polaznici.class); cq.where(polaznici.get(Polaznici_.vrsta).in(0, 1, 2); Napredne Web tehnologije i servisi 67 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Ograničavanje rezultata Criteria upita Uvjetne metode u sučelju CriteriaBuilder : equal notEqual gt ge lt le between like. Složene predikatne metode u sučelju CriteriaBuilder : and or not Napredne Web tehnologije i servisi 68 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Ograničavanje rezultata Criteria upita CriteriaQuery cq = cb.createQuery(Polaznici.class); Metamodel m = em.getMetamodel(); EntityType Polaznici_ = m.entity(Polaznici.class); Root polaznici = cq.from(Polaznici.class); cq.where(cb.between(polaznici.get(Polaznici_.vrsta)), 0, 2); CriteriaQuery cq = cb.createQuery(Polaznici.class); Metamodel m = em.getMetamodel(); EntityType Polaznici_ = m.entity(Polaznici.class); Root polaznici = cq.from(Polaznici.class); cq.where(cb.and(cb.equal(polaznici.get(Polaznici_.vrsta)), 0), cb.like(polaznici.get(Polaznici_.emailAdresa)), “%@foi.hr”))); Napredne Web tehnologije i servisi 69 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Upravljanje rezultima Criteria upita Za upite koji vraćaju više od jednog rezultata može biti potreba da se oni organiziraju. Sučelje CriteriaBuilder ima metodu orderBy za sređivanje rezultata prema atributima entiteta i metodu having za ograničenje grupa prema uvjetu. CriteriaQuery cq = cb.createQuery(Polaznici.class); Metamodel m = em.getMetamodel(); EntityType Polaznici_ = m.entity(Polaznici.class); Root polaznici = cq.from(Polaznici.class); cq.select(polaznici); cq.orderBy(cb.desc(polaznici.get(Polaznici_.datumKreiranja)); Napredne Web tehnologije i servisi 70 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Upravljanje rezultima Criteria upita Složeno sređivanje: CriteriaQuery cq = cb.createQuery(Polaznici.class); Metamodel m = em.getMetamodel(); EntityType Polaznici_ = m.entity(Polaznici.class); Root polaznici = cq.from(Polaznici.class); cq.select(polaznici); cq.orderBy(cb.asc(polaznici.get(Polaznici_.prezime), polaznici.get(Polaznici_.ime)); Napredne Web tehnologije i servisi 71 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Upravljanje rezultima Criteria upita Grupiranje se provodi putem metode CriteriaQuery.groupBy: CriteriaQuery cq = cb.createQuery(Polaznici.class); Metamodel m = em.getMetamodel(); EntityType Polaznici_ = m.entity(Polaznici.class); Root polaznici = cq.from(Polaznici.class); cq.select(polaznici); cq.groupBy(polaznici.get(Polaznici_.vrsta)); Napredne Web tehnologije i servisi 72 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Upravljanje rezultima Criteria upita Filtriranje grupiranja se provodi putem metode CriteriaQuery.having: CriteriaQuery cq = cb.createQuery(Polaznici.class); Metamodel m = em.getMetamodel(); EntityType Polaznici_ = m.entity(Polaznici.class); Root polaznici = cq.from(Polaznici.class); sq.select(polaznici); cq.groupBy(polaznici.get(Polaznici_.vrsta)); cq.having(cb.equal(polaznici.get(Polaznici_.vrsta)), 0) Napredne Web tehnologije i servisi 73 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Korištenje entiteta – Polaznici @RequestScoped public class PolazniciFacade { @PersistenceContext(unitName = „nwtis_pu") private EntityManager em; public void create(Polaznici polaznici) { em.persist(polaznici); } public void edit(Polaznici polaznici) { em.merge(polaznici); } public void remove(Polaznici polaznici) { em.remove(em.merge(polaznici)); } public Polaznici find(Object id) { return em.find(Polaznici.class, id); } Napredne Web tehnologije i servisi 74 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Korištenje entiteta – Polaznici / 2 public List findAll() { CriteriaQuery cq = cb.createQuery(Polaznici.class); cq.select(cq.from(Polaznici.class)); return em.createQuery(cq).getResultList(); } public List findRange(int[] range) { CriteriaQuery cq = cb.createQuery(Polaznici.class); cq.select(cq.from(Polaznici.class)); TypedQuery q = em.createQuery(cq); q.setMaxResults(range - range); q.setFirstResult(range); return q.getResultList(); } Napredne Web tehnologije i servisi 75 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Korištenje entiteta – Polaznici / 3 public List findAll_CS(String prezime, String ime) { CriteriaQuery cq = cb.createQuery(Polaznici.class); Root polaznici = cq.from(Polaznici.class); Expression zaPrezime = polaznici.get(Polaznici_.prezime); Expression zaIme = polaznici.get(Polaznici_.ime); cq.where(cb.and(cb.like(zaPrezime, prezime), cb.like(zaIme, ime))); TypedQuery q = em.createQuery(cq); return q.getResultList(); } public int count() { CriteriaQuery cq = cb.createQuery(Polaznici.class); Root rt = cq.from(Polaznici.class); cq.multiselect(cb.count(rt)); Query q = em.createQuery(cq); return ((Long) q.getSingleResult()).intValue(); } } Napredne Web tehnologije i servisi 76 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Korištenje entiteta – Polaznici / 4 public String dodajKorisnika() { Polaznici p = new Polaznici(pkorisnik, pime, pprezime, "123456", pkorisnik + "@foi.hr", 1); p.setDatumKreiranja(new Date()); p.setDatumPromjene(new Date()); p.setGrupeList(new ArrayList()); polaznici.create(p); return ""; } public String obrisiKorisnika() { for (String ki : odabraniKorisnici) { Polaznici p = polaznici.find(ki); polaznici.remove(p); } return ""; } Napredne Web tehnologije i servisi 77 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Korištenje entiteta – Polaznici / 5 public String postaviGrupeKorisnika() { if(odabraniKorisnici.size() == 1) { Polaznici p = polaznici.find(odabraniKorisnici.get(0)); List grupeList = p.getGrupeList(); odabraneGrupe.clear(); for(Grupe g: grupeList) { odabraneGrupe.add(g.getGrIme()); } } return ""; } Napredne Web tehnologije i servisi 78 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Korištenje entiteta – Polaznici / 6 public String dodajGrupuKorisniku() { for (String ki : odabraniKorisnici) { Polaznici p = polaznici.find(ki); List grupeList = p.getGrupeList(); boolean nema = true; for (String gs : odabraneGrupe) { nema = true; for (Grupe g : grupeList) { if (g.getGrIme().compareTo(gs) == 0) { nema = false; break; } } if (nema) { Grupe g = grupePolaznici.find(gs); grupeList.add(g); } } p.setGrupeList(grupeList); polaznici.edit(p); } return ""; } Napredne Web tehnologije i servisi 79 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin Korištenje entiteta – Polaznici / 7 public String obrisiGrupuKorisniku() { for (String ki : odabraniKorisnici) { Polaznici p = polaznici.find(ki); List grupeList = p.getGrupeList(); boolean nema = true; for (String gs : odabraneGrupe) { nema = true; for (Grupe g : grupeList) { if (g.getGrIme().compareTo(gs) == 0) { grupeList.remove(g); break; } } } p.setGrupeList(grupeList); polaznici.edit(p); } return ""; } Napredne Web tehnologije i servisi 80 Dr.sc. D.Kermek, Fakultet organizacije i informatike, Varaždin

Use Quizgecko on...
Browser
Browser