JPQL

Technology
12 hours ago
8
4
2
Avatar
Author
Albert Flores

Java Persistence Query Language (zkráceně: JPQL) je dotazovací jazyk, který se využívá v programovacím jazyce Java jako součást JPA. Je velice podobný klasickému SQL, je zde však několik podstatných rozdílů.

SQL vs JPQL

Na rozdíl od klasického SQL, kde jsou dotazy vykonávány nad tabulkami databáze, je u JPQL dotaz vykonáván nad objekty aplikace, tzv. entitami. +more Tyto objekty jsou namapovány na databázové tabulky pomocí JPA anotací či XML konfigurací (link na JPA). Podstatné také je, že JPQL respektuje nadefinované vztahy, které mají mezi sebou entity. Dalším důležitým znakem JPQL je, že odstiňuje programátora od specifik konkrétního datového úložiště. Jinými slovy, programátor se nestará o to, zda jsou v konečném důsledku dotazy převáděny nad Oracle nebo MySQL databází. Stále píše stejné dotazy. Tato vlastnost je velice pohodlná, může však mít i jistá omezení(-----).

Každý výrobce databází přináší do svého produktu jinou funkcionalitu, kterou se odlišuje od ostatních. Používáním standardních „univerzálních“ dotazů pomocí JQPL o tyto výhody přichází. +more Někdy se v této souvislosti hovoří o zákonu netěsných abstrakcí. Ten ve zkratce říká, že jakákoli abstrakce vede k zúžení funkcionality nebo k neefektivnímu využívání zdrojů. Jako příklad se často uvádí tato abstrakce SQL:.

... WHERE a=b AND b=c

... WHERE a=b AND b=c AND a=c

Matematicky jsou tyto zápisy totožné. Může však u některých databází docházet v případě použití druhého zápisu k výraznému zlepšení výkonnosti zpracování.

Vytváření a vykonávání dotazů

U dotazů se rozlišují tři typy dotazů - dynamický, pojmenovaný a nativní [url=http://java. vse. +morecz/wiki/uploads/4it447/4it447-prednaska6. ppt] Dynamický dotaz se vytváří pomocí metody createQuery na objektu EntityManager. Parametrem této metody je vytvořený dotaz v textové podobě. Metoda vrací objekt s rozhraním javax. persistence. Query(dále již pouze Query).

Např.

Query query = entityManager.createQuery("[[SELECT[/url]] c FROM Customer c ");

Vyhledaná data lze získat pomocí metod getSingleResult, která vrací jediný objekt, nebo pomocí getResults, která vrací seznam.

Pojmenovaný dotaz se vytváří pomocí metody createNamedQuery opět na objektu EntityManager. Rozdíl oproti dynamickému dotazu je ten, že se statické dotazy zapisují do souboru orm. +morexml nebo alternativně do anotace. Tím vzniká znovu použitelnost dotazu na více místech aplikace.

Nativní dotaz se vytváří pomocí metody createNativeQuery také na objektu EntityManager. Tento dotaz je na rozdíl od ostatních sestrojován v nativní syntaxi SQL.

Parametry v dotazech

Obdobně, jako je tomu v JDBC, i v JPQL lze dotazy parametrizovat. Hodnota parametru se nastavuje pomocí metody setParametr na objektu Query

Existují dva základní způsoby, jakým lze definovat parametr:(-----)

# Pomocí jména - na místo hodnoty se ve výrazu zapíše název parametru s prefixem „:“

Např.

Query query = entityManager.createQuery("SELECT c FROM Customer c WHERE c.name LIKE :custName");

query. setParameter("custName", name);

# Pomocí pořadí - na místo hodnoty se ve výrazu zapíše pořadové číslo s prefixem „?“ (indexováno od 1)

Např.

Query query = entityManager.createQuery("SELECT c FROM Customer c WHERE c.name LIKE ?1 ");

query. setParameter(1, name);

Typy dotazů

Existují tři základní typy dotazů: SELECT, UPDATE a DELETE (-----).

JPQL 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.

Syntaxe výběrového dotazu:

SELECT

FROM

[WHERE ]

[

.

Příklad využití příkazu UPDATE:.

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.

JPQL delete

Příkaz DELETE slouží k dávkovému odstraňování entit. Syntaxe:

Příklad využití příkazu DELETE

DELETE FROM User AS u WHERE u.username LIKE 'f%'

Příkaz smaže všechny uživatele, kteří začínají písmenem „f“.

Klauzule v dotazech

Každý typ dotazu má určitou strukturu (viz SELECT, UPDATE, DELETE). V této kapitole budou rozepsány jednotlivé klauzule těchto dotazů.

Klauzule FROM

Klauzule FROM definuje entity dotazu. Každá entita může mít přiřazen nějaký alias, který je možno použít i v ostatních klauzulích dotazu. +more Alias se může napsat rovnou za název entity, nebo se může alternativně použít příkaz „AS“. JPQL podporuje v klauzuli FROM použít také příkaz IN, který znázorňuje zkrácený zápis příkazu INNER JOIN (viz dále) .

Příklady:

FROM User u

FROM User AS u

FROM User u, Account a

FROM User u, IN(c.accounts) a

Klauzule WHERE

Klauzule WHERE slouží k omezení výsledků podle určitých kritérií. Používá se ve všech typech dotazů (SELECT, UPDATE, DELETE).

Příklady:

WHERE u.username='Josef'

Omezí výběr na uživatele s uživatelským jménem „Josef“

WHERE u.username ='Josef' AND u.email='josef@novak.cz'

Omezí výběr na uživatele „Josef“ s emailem „josef@novak.cz“

WHERE a.deposit NOT BETWEEN 1000 AND 100000

Omezí výběr na účty se zůstatkem mezi 1000 a 100000

WHERE u.address.country IN ('CZ', 'SK')

Omezí výběr na ty záznamy, kde adresa uživatele má kód „CZ“ nebo „SK“.

WHERE u.email LIKE '%novak.cz'

Zde je využit znak „%“, který zastupuje více libovolných znaků. V tomto případě omezí výběr na uživatele, jejichž email obsahuje doménu „novak. +morecz“. Je možné také využít znak „_“, který zastupuje právě jeden libovolný znak.

Klauzule ORDER BY

Klauzule ORDER BY slouží k seřazení výsledků výběrového dotazu. Výsledky jsou seřazeny podle atributů entity uvedené v klauzuli. +more Je možné definovat směr řazení za uvedené atributy - příkaz ASC pro vzestupné a DESC pro sestupné seřazení .

Příklady:

SELECT u FROM User u ORDER BY u.username, u.email

SELECT a FROM Account a ORDER BY a.deposit DESC, a.client.lastName ASC, a.client.firstName ASC

Klauzule GROUP BY

Příkaz GROUP BY se používá k seskupení entit. Skupina je tvořena entitami, které mají stejnou hodnotu atributů uvedených v GROUP BY.

Musí být dodrženo pravidlo, že výsledek může obsahovat pouze skupinové atributy uvedené v klauzuli GROUP BY a hodnoty agregačních funkcí (viz dále) aplikovaný na neskupinové 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.

Klauzule HAVING

Klauzule HAVING se používá pro filtrování výsledků dotazů sestavených pomocí GROUP BY. Podobá se klauzuli WHERE s tím rozdílem, že podmínka obsahuje funkční výrazy nad identifikátory (včetně agregačních funkcí), které se vyskytují v klauzuli SELECT daného dotazu .

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č

Vytváření relačních dotazů

Během vytváření dotazů je často potřeba vybírat i související záznamy dané entity. Následující příkazy slouží právě pro tyto účely.

INNER JOIN

Příkaz INNER JOIN pomáhá při výběru souvisejících entit nebo jejich atributů .

Příklad:

SELECT a FROM User u, IN(u.address) a

Vrátí všechny adresy patřící nějakým uživatelům.

Alternativní zápis:

SELECT a FROM User u INNER JOIN u.address a

LEFT JOIN

Příkaz LEFT JOIN je velmi podobný příkazu INNER JOIN. Umožňuje však vybírat také entity, které nemají nastavenou požadovanou vazbu. +more V případě, že tuto vazbu nemají, atributy mají ve výsledku hodnotu NULL .

Příklad:

SELECT u.username, u.email, a.city FROM User u LEFT JOIN u.address a

Vybere uživatelská jména, emaily všech uživatelů a název města u těch uživatelů, kteří mají vyplněnou adresu s městem.

FETCH JOIN

Příkaz FETCH JOIN vynucuje nahrání asociovaných entit a to i v případě, že je vazba nastavena pomocí FetchType jako Lazy .

Příklad:

SELECT u FROM user u INNER JOIN FETCH u.address

Stránkování výsledků

V případě, že je počet výsledků příliš velký, lze omezit jeho počet pomocí :

Query::setFirstResult(index) - určuje, od kterého indexu se má vrátit první výsledek

Query::setMaxResult(max) - určuje maximální počet výsledků v seznamu

Operátory a funkce

Operátory

Operátory se používají nejčastěji v klauzuli WHERE, která omezuje výběr entit. Jsou to :

=, >, =, , [NOT] BETWEEN

Využití u číselných hodnot.

[NOT] LIKE

Využívané u řetězcových hodnot

[NOT] IN

Používané pro výčet hodnot

IS [NOT] NULL

Ověření, zda je hodnota NULL nebo NOT NULL

IS [NOT] EMPTY

Výběr (ne) prázdných hodnot

[NOT] MEMBER OF

Zjišťuje, zda (není) je hodnota obsažena v kolekci

AND, OR

Klasické operátory pro spojování výrazů - „A“, „Nebo“

Funkce

Funkce se používají pro úpravu vybíraných dat nebo pro jejich agregaci .

LOWER(String), UPPER(String)

Převedení na malá / velká písmena

Ořezání znaků na začátku/konci řetězce

CONCAT(String1, String2)

Spojení dvou řetězců

LENGTH(String)

Zjištění délku řetězců

LOCATE(String1, String2 [, start])

Vyhledávání řetězce

SUBSTRING(String, start, length)

Výběr části řetězce

ABS(number)

Absolutní číslo

SQRT(double)

Odmocnina

MOD(int, int)

Modulo

CURRENT_DATE, CURRENT_TIME, CURRENT_TIMESTAMP

Výběr konkrétního data/času/časové známky

Agregační funkce:

COUNT

Zjišťuje počet

MAX

Maximum

MIN

Minimum

AVG

Průměr

SUM

Suma

DISTINCT

eliminuje duplicity, přičemž hodnoty null jsou automaticky eliminovány.

Novinky v JPA 2.0

JPA 2. 0 přineslo mnoho nových vylepšení, které umožňují snadnější práci s entitami propojených s databází. +more Co se týče JPQL, asi největší novinkou je tzv. Criteria API (DeMichiel, 2008).

Criteria API

Criteria API má přinést zjednodušení při vytváření dynamických dotazů. Dotaz má podobu objektu, na kterém je možné volat metody, které znázorňují jednotlivé klauzule dotazu. +more Výsledně sestavený dotaz se podobně jako u alternativního staršího způsobu předá jako parametr metody createQuery na instanci objektu EntityManager (DeMichiel, 2008).

Příklad:

EntityManager em = getEntityManager; CriteriaBuilder cb = em. getCriteriaBuilder; CriteriaQuery query = cb. +morecreateQuery(User. class); Root user = query. from(User. class); query. where(cb. equal(user. get("username"), "Pepa")); List result = em. createQuery(query). getResultList;.

Využití Criteria API má několik výhod: * Klauzule dotazů mohou být přidávány dynamicky v libovolném pořadí. * Rychlejší kompilace (odpadají některá ověření). +more * Menší riziko výskytu chyb a překlepů - dotaz není sestavován jako řetězec znaků, nýbrž pomocí objektů.

Externí odkazy

[url=http://java. vse. +morecz/wiki/uploads/4it447/4it447-prednaska8-2. ppt]Mgr. Zbyněk Šlajchrt - 8, přednáška ke předmětu 4IT447 - Vývoj podnikových aplikací na platformě Java[/url] * [url=https://web. archive. org/web/20090322190536/http://blogs. sun. com/ldemichiel/entry/java_persistence_2_0_public1]Java Persistence 2. 0 Public Draft: Criteria API. Linda DeMichiel's Blog[/url].

Kategorie:Dotazovací jazyky Kategorie:Java

5 min read
Share this post:
Like it 8

Leave a Comment

Please, enter your name.
Please, provide a valid email address.
Please, enter your comment.
Enjoy this post? Join Cesko.wiki
Don’t forget to share it
Top