Upload
rigel-cervantes
View
24
Download
3
Embed Size (px)
DESCRIPTION
VÝVOJ PODNIKOVÝCH APLIKACÍ NA PLATFORMĚ JAVA - PŘEDNÁŠKA. Zbyněk Šlajchrt http://java.vse.cz/4it447/HomePage. Část 8. Dědičnost entit. Základní vlastnost OOP Sdílení stavu a chování mezi třídami uspořádanými do hierarchií - PowerPoint PPT Presentation
Citation preview
VÝVOJ PODNIKOVÝCH APLIKACÍ NA PLATFORMĚ JAVA - PŘEDNÁŠKAZbyněk Šlajchrt http://java.vse.cz/4it447/HomePageČást 8.
Dědičnost entit
Základní vlastnost OOP Sdílení stavu a chování mezi třídami
uspořádanými do hierarchií Na rozdíl od relací nemají relační databáze
koncept pro dědičnost mezi tabulkami Lze zařídit dodatečně - 3 strategie
Single-table-per-hierarchy Joined-subclass Table-per-concrete-class
2
Příklad dědičnosti3
Příklad dědičnosti - Java4
Single-table-per-hierarchy
Tato strategie mapuje celou hierarchii tříd entit do jedné tabulky Jedna tabulka ITEM a v ní atributy pro Item,
Book a CD Default strategie Tabulka obsahuje speciální sloupec pro
rozlišení entit – tzv. discriminator column Lze konfigurovat pomocí @DiscriminatorColumn Hodnotu, kterou je identifikována entita ve
sloupci, lze určit pomocí @DiscriminatorValue umístěné na třídu
5
Single-table-per-hierarchy6
ID
DTYPE
TITLE PRICE
DESCRIPTION
MUSICCOMPANY
ISBN ...
1 Item Pen 1,20 Nice pen
2 CD ABBA 20,00 Remake EMI
3 Book Bible 1,00 God's book 1
4 CD Beatles
30,00 best of ... EMI
ITEMIDDTYPETITLEPRICEDESCRIPTIONMUSICCOMPANYISBNNUMBEROFPAGES...
ITEMIDDTYPETITLEPRICEDESCRIPTIONMUSICCOMPANYISBNNUMBEROFPAGES...
Single-table-per-hierarchy
Výhody Nejjednodušší – snadná správa Nejvýkonnější strategie – žádné joiny,
subselecty atd. Nevýhody
Sloupce potomků musí být NULLABLE – big problem!
Model není normalizovaný, jelikož sloupce patřící potomkům nemusí být používané
7
Joined-strategy
Tato strategie mapuje entity do samostatných tabulek
Tabulka entity obsahuje pouze sloupce pro atributy deklarované ve třídě entity
Zděděný stav se mapuje do tabulky předka Tabulka kořenové entity (Item) znovu
obsahuje discriminator column pro rozlišení řádek entit
Kořenovou entitu (Item) je třeba anotovat @Inheritance(strategy=Inheritance.JOINED)
8
Joined-strategy9
ITEMIDDTYPETITLEPRICEDESCRIPTION
ITEMIDDTYPETITLEPRICEDESCRIPTION
CDIDMUSICCOMPANYNUMBEROFCDSTOTALDURATIONGENDER
CDIDMUSICCOMPANYNUMBEROFCDSTOTALDURATIONGENDER
BOOKIDILLUSTRATIONSISBNNUMBEROFPAGESPUBLISHER
BOOKIDILLUSTRATIONSISBNNUMBEROFPAGESPUBLISHER
Joined-strategy
Výhody Vlastnosti potomků mohou být NOT NULL Model je normalizovaný
Nevýhody Není tak výkonná jako Single-table-per-
hierarchy
10
Single-per-concrete-class
Každá entita je mapovaná do vlastní tabulky včetně zděděných vlastností
Schéma není normalizované Sloupce z kořenové tabulky se opakují v
tabulkách potomků Není zde žádný discrimator column Primární klíč je sdílený – nesmí se vyskytovat
dvakrát napříč tabulkami v jedné hierarchii Nepovinná strategie ve specifikaci JPA 2.0
přenositelné aplikace by jej neměly používat
11
Single-per-concrete-class12
ITEMIDTITLEPRICEDESCRIPTION
ITEMIDTITLEPRICEDESCRIPTION
CDIDTITLEPRICEDESCRIPTIONMUSICCOMPANYNUMBEROFCDSTOTALDURATIONGENDER
CDIDTITLEPRICEDESCRIPTIONMUSICCOMPANYNUMBEROFCDSTOTALDURATIONGENDER
BOOKIDTITLEPRICEDESCRIPTIONILLUSTRATIONSISBNNUMBEROFPAGESPUBLISHER
BOOKIDTITLEPRICEDESCRIPTIONILLUSTRATIONSISBNNUMBEROFPAGESPUBLISHER
Single-per-concrete-class
Výhody Vlastnosti mohou být NOT NULL Může být jednodušší mapování na legacy schéma
Nevýhody Model není normalizovaný, opakování sloupců
předka Náročné na implementaci polymorfních dotazů
Buď více selectů do všech tabulek hierarchie – POMALÉ! Nebo pomocí SQL UNION – podporují pouze některé DB
Lépe se této strategii vyhýbat
13
Typy předků Entita
standardní entita Abstraktní entita
z hlediska JPA totéž jako entita Ne-entita
také se někdy označují jako tranzientní třídy vlastnosti zděděné z tohoto předka se nemapují do DB
Mapovaný předek Ne-entita, její vlastnosti se však mapují do tabulky
potomka – anotuje se @MappedSuperclass Podobnost s embedded entity
14
Dotazovací aparát
Doposud jsme probírali pouze vyhledávání podle primárního klíče EntityManager::find a
EntityManager::getReference JPA 2.0 obsahuje specifikaci jazyka JPQL Objektově-orientovaný dotazovací jazyk
inspirovaný SQL Vývojář při sestavování dotazu pracuje s
objekty nikoliv s prostými hodnotami Tečková notace pro přístup k vlastnostem entit Client.address.street
15
Query API
Dotaz se vytváří voláním metody createQuery na objektu EntityManager
Parametrem je výraz v syntaxi jazyka JPQL
Vrací objekt s rozhraním javax.persistence.Query
Metoda getSingleResult() vrací jediný objekt pokud není objekt právě jeden
Metoda getResults() vrací seznam – i prázdný
16
Parametrizovaný dotaz
Podobně jako v JDBC, i v JPQL lze dotazy parametrizovat
Parametry lze definovat jménem nebo pořadím Definice pojmenovaného parametru
na místo hodnoty ve výrazu se zapíše název parametru s prefixem :
na místo hodnoty ve výrazu se zapíše pořadové číslo parametru s prefixem ? indexováno od 1
Hodnota parametru se nastavuje setParameter()
17
Parametrizovaný dotaz18
Nastavení parametrů podle jejich pořadí:
Nastavení parametrů podle jejich názvu:
Časové parametry
Pro zadávání hodnot časových parametrů se používá jiných metod setParameter(name/position, Date, TemporalType) setParameter(name/position, Calendar,
TemporalType) TemporalType je výčtový typ, který specifikuje
databázový časový typ, do kterého se konvertuje typ java.util.Date nebo java.util.Calendar DATE TIME TIMESTAMP
19
Stránkování výsledků
V případě velkého počtu výsledků lze omezit jejich počet
Query::setFirstResult(index) Oznamuje dotazu, od kterého indexu má
vrátit první výsledek Query::setMaxResult(max)
Oznamuje dotazu maximální počet výsledků v seznamu
20
Hints
Někteří dodavatelé JPA poskytují extra funkcionalitu, kterou lze použít při dotazování Např. JBoss EJB 3.0 (obsahuje Hibernate)
umožňuje specifikovat timeout dotazu Pro nastavení extra funkcionality se volá
setHint(hintName, hintValue) query.setHint("org.hibernate.timeout",
1000);
21
FlushMode dotazu
Ovlivňuje způsob synchronizace stavu entit s databází
Někdy se hodí, aby během zpracování dotazu platil jiný flush mod např. chceme zabránit, aby EntityManager
provedl automatický flush před dotazem – mod AUTO mu to umožňuje
Dočasný flush mod se nastavuje Query::setFlushMode(flushMode) query.setFlushMode(FlushModeType);
22
JPQL SELECT
Klauzule SELECT slouží k definici výběru dat z databáze
Výsledkem může být entita atribut entity nově zkonstruovaný objekt hodnota agregační funkce sekvence výše uvedených výsledků
Pro odkazování na atributy entit se používá tečková konvence
23
SELECT - Syntaxe24
SELECT <select expression>FROM <from clause>[WHERE <conditional expression>][ORDER BY <order by clause>][GROUP BY <group by clause>[HAVING <having clause>]]
SELECT – Příklady
SELECT c FROM Customer c Vrací seznam všech zákazníků List<Customer>
SELECT c.firstName FROM Customer c Vrací seznam křestních jmen všech zákazníků List<String>
SELECT c.firstName, c.lastName FROM Customer c
Vrací seznam křestních jmen a příjmení (pole velikosti 2) List<Object[2]>
SELECT c.address FROM Customer c Vrací seznam adres všech zákazníků List<Address>
25
SELECT – Příklady
SELECT c.address.country.code FROM Customer c
Ukázka tečkové notace. Vrací seznam kódů zemí v adresách zákazníků.
List<String>
SELECT NEW cz.vse.javaee.prednaska8.CustomerDTO (c.firstName, c.lastName, c.address.city) FROM Customer c
Vrací seznam objektů CustomerDTO vytvořených pro každého zákazníka. Do konstruktoru se předávají údaje zákazníka.
List<CustomerDTO>
26
SELECT – Příklady
SELECT DISTINCT c.firstName FROM Customer c Vrací seznam křestních jmen všech zákazníků bez duplicit. List<String>
SELECT count(c) FROM Customer c Vrací skalární hodnotu rovnu počtu všech zákazníků. List<Long>, velikost 1, volat Query::getSingleResult()
Agregační funkce AVG - průměr COUNT - počet MAX - maximum MIN - minimum SUM - součet
27
Klauzule FROM
Definuje entity v dotazu Alias entity může být použit v dalších
klauzulích SELECT, WHERE, ...
Příklady: FROM Customer c FROM Customer AS c FROM Customer c, Account a FROM Customer c, IN(c.accounts) a
28
Klauzule WHERE
Definuje podmínkový výraz pro omezení výsledků používá se v SELECT, UPDATE, DELETE
Příklady: WHERE c.firstName='Josef' WHERE c.firstName='Josef' AND c.lastName='Novák' WHERE a.deposit NOT BETWEEN 1000 AND 100000 WHERE c.address.country IN ('CZ', 'SK') WHERE c.email LIKE '%vse.cz'
% - více-znakový wildcard _ - jednoznakový wildcard
29
Operátory ve WHERE
=, >, <, >=, <=, <>, [NOT] BETWEEN [NOT] LIKE [NOT] IN IS [NOT] NULL IS [NOT] EMPTY [NOT] MEMBER OF AND, OR
V Javě se druhý operand nevyhodnocuje, pokud hodnota prvního určuje výsledek
V JPQL se na toto nedá spolehnout
30
Subqueries
Vnořené dotazy se používají v klauzulích WHERE a HAVING
Příklady SELECT acc FROM Account acc WHERE acc.deposit=
(SELECT MAX(a.deposit) FROM Account a) Vybere účet s největším vkladem V podstatě dva nezávislé dotazy
SELECT c FROM Customer c WHERE 1000 > (SELECT SUM(a.deposit) FROM c.accounts AS a) Vybere klienty, kteří mají na svých účtech méně než
1000 Kč Vnořený dotaz je svázaný s hlavním dotazem
31
Subqueries – ALL, ANY, SOME Tyto operátory se používají pro vnořené
dotazy, které vracejí více řádek ALL – logická operace musí platit pro všechny
výsledky vnořeného dotazu ANY (SOME), - Operace musí platit aspoň pro
jeden výsledek vnořeného dotazu Příklad:
... FROM Client c WHERE 100 < ALL (SELECT a.deposit FROM c.accounts AS a) Vybere klienty, kteří mají na svých všech účtech více
než 100
32
Subqueries - EXISTS
Operátor EXISTS vrací true výsledek obsahuje jeden nebo více výsledků
Příklad: FROM Client c WHERE EXISTS (SELECT a
FROM c.accounts AS a WHERE a.deposit > 100) Vrací pouze ty klienty, kteří mají aspoň na
jednom účtu uloženo více jak 100 Kč
33
Klauzule ORDER BY
ORDER BY se používá k seřazení výsledků dotazu
Výsledky jsou seřazeny podle atributů entity uvedených v klauzuli
Uvádí se i směr seřazení – vzestupně ASC, sestupně DESC
Příklady: SELECT c FROM Customer c ORDER BY c.lastName,
c.firstName SELECT a FROM Account a ORDER BY a.deposit
DESC, a.client.lastName ASC, a.client.firstName ASC
34
Klauzule GROUP BY
GROUP BY se používá k seskupení entit Skupina je tvořena entitami, které mají stejnou
hodnotu atributů uvedených v GROUP BY Výsledek může obsahovat pouze skupinové
atributy (z GROUP BY) a hodnoty agregačních funkcí aplikovaných na ne-skupinové atributy entit.
Příklad: SELECT a.client, sum(a.deposit) FROM Account a
GROUP BY a.client Výsledek v seznamu je klient a součet vkladů na jeho
účtech
35
Klauzule HAVING
Používá se pro filtrování dotazů sestavených pomocí GROUP BY
Podmínku může obsahovat pouze agregační funkce nad atributy, které se vyskytují v klauzuli SELECT
Příklad: SELECT a.client, sum(a.deposit) FROM Account
a GROUP BY a.client HAVING sum(a.deposit) > 1000 Vybere klienty, kteří mají na svých účtech v
souhrnu vyšší částku než 1000 Kč
36
Příkaz DELETE
Určeno pro dávkové odstraňování entit Syntaxe:
DELETE FROM <entity_name> [[AS] <alias>] [WHERE <condition>]
Příklad: DELETE FROM Client AS c WHERE
c.firstName='Karel' Smaže všechny Karly
37
Příkaz UPDATE
Určeno pro dávkovou aktualizaci entit Syntaxe:
UPDATE <entity_name> [[AS] <alias>] SET <update_statement> {, <update_statement>}* [WHERE <condition>]
Příklad: UPDATE Account AS a SET
a.deposit=a.deposit*1.01 where a.client.firstName='Josef' Připíše 1% ze zůstatku všem Josefům
38
INNER JOIN
V klauzulích není možné používat atributy-kolekce
Často je ale zapotřebí s nimi pracovat Operátor IN přiřazuje vybrané kolekci
alias lze pak s tímto alias pracovat, jako by to
byla entita Příklad:
SELECT a FROM Client c, IN(c.accounts) a Vrátí všechny účty patřící nějakým klientům
Alternativní zápis: SELECT a FROM Client c INNER JOIN
c.accounts a
39
LEFT JOIN
LEFT JOIN umožňuje vybírat také entity, které nemají nastavenu požadovanou vazbu
Atributy protější entity mají ve výsledku hodnotu NULL
Příklad: SELECT c.firstName, c.lastName, p.number
FROM Client c LEFT JOIN c.phoneNumbers p
40
Josef Novák 656787377Josef Novák 746888333Karel Vodička 535288223Jan Malý NULL
Fetch Joins
Umožňuje nahrát asociované entity, i když má vazba nastaven FetchType jako LAZY
Příklad: MailBox – Messages (1:N)
SELECT mbox FROM MailBox mbox INNER JOIN FETCH mbox.messages
Bez FETCH bychom museli nahrát entity zpráv v Javě pomocí cyklu – problém s výkonností
41
Dodatek: JPQL Funkce
LOWER(String), UPPER(String) TRIM([[LEADING|TRAILING|BOTH]
[trimchar] FROM] String) CONCAT(String1, String2) LENGTH(String) LOCATE(String1, String2 [, start]) – hledá
řetězec SUBSTRING(String, start, length) ABS(number), SQRT(double), MOD(int, int)
42
Dodatek: JPQL Funkce
CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP
Agregační funkce: COUNT, MAX, MIN, AVG, SUM DISTINCT – eliminuje duplicity hodnoty null jsou automaticky eliminovány
43
Zdroje
Burke, Bill – Monson-Haefel, Richard; Enterprise Java Beans 3.0; O'Reilly
Goncalves, Antonio; Beginning Java EE 6 Platform With GlassFish 3; APRESS
44