Java >> Java tutoriál >  >> Java

Vylepšení JPQL v JPA 2.1 a Java EE 7 (část 1 – JOIN ON)

Java EE 7 existuje již několik let a poskytuje několik velmi užitečných a dlouho očekávaných funkcí, jako jsou grafy entit a lepší podporu pro uložené procedury a mapování výsledků. Pro přehled se podívejte na blogový příspěvek Thorbena Janssena. Rád bych však přidal podrobnější shrnutí funkcí v dotazovacím jazyce JPA. Všechny jsou dostupné v JPQL i Criteria API:

  • ZAPNUTO klíčové slovo pro specifikaci podmínek pro JOIN
  • FUNKCE zavolat libovolnou databázovou funkci
  • LÉČBA převést entity na jejich konkrétní typ

V tomto příspěvku se zaměřím na první přídavek. Další 2 přidám do dalších příspěvků.

ZAPOJTE SE

Výrazy JOIN v JPA jsou již trochu odlišné od JOIN ve standardním SQL. JOIN je možné použít pouze tehdy, když již existuje mapování mezi entitami, a není vždy nutné kvůli línému načítání souvisejících kolekcí pomocí implicitních spojení. Buďte opatrní s JPA JOIN, pokud jste začátečník s JPA, a pečlivě si přečtěte dokumentaci.

Do JPA 2.1 bylo možné filtrovat konečné výsledky dotazu pouze pomocí podmínek v klauzuli WHERE. To je ve většině případů dostačující. Ale při použití LEFT JOIN narážíte na limit a chcete omezit to, co se má připojit od druhé entity. S LEFT JOIN vždy získáte alespoň jeden řádek z první entity, ale někdy nechcete připojit žádné instance z druhé entity, takže konečná kolekce zůstane prázdná.

Kromě klíčového slova WITH v Hibernate neexistoval v JPA žádný standardní způsob, jak to udělat. Od JPA 2.1 je možné přidat podmínku ke spojením s ZAPNUTO klíčové slovo, podobné SQL JOIN ON.

Příklad použití JOIN ON v JPA

SELECT a FROM Person p LEFT JOIN p.addresses a ON a.city = p.city

Výše uvedený úryvek načte pouze ty adresy, které mají stejné město jako osoba. Totéž lze dosáhnout přesunem podmínky do WHERE, takže potřebujeme složitější příklad s více spojeními, abychom viděli výhodu:

Příklad použití JOIN ON v JPA

SELECT c FROM Person p LEFT JOIN p.addresses a ON a.city = p.city LEFT JOIN a.country c ON c.region = 'Europe'

Ve výše uvedeném příkladu dostaneme pouze země, kde a adresa existuje a jejich osoba má stejné město. Jaký je rozdíl oproti použití WHERE? Pokud bychom obě podmínky z klauzulí ON dali do WHERE na konci, zahrnuli bychom všechny země vztahující se ke všem adresám osoby, nikoli pouze k adresám se stejným městem. Je jasné, že výsledek by mohl být větší, když podmínku aplikujeme až na konci. ZAPNUTO klíčové slovo umožňuje filtrovat výsledky po každém spojení, což vede k menšímu výsledku po každém následném spojení.

Jedno omezení však stále přetrvává i při použití JOIN s ON – entity lze stále spojovat pouze tehdy, jsou-li spolu mapovány jako související entity.

JOIN ON s více kořeny v Eclipselink

Eclipselink poskytuje další funkci ke standardnímu klíčovému slovu JPA On. Umožňuje spojit nesouvisející entity ve stavu ON, což umožňuje PŘIPOJIT nesouvisející entitu k jiným entitám, které jsou již v dotazu. Proto nevyžaduje, aby byla pole označena jako související, i když potřebujeme podmínku spojení pouze pro jednu sestavu a nechceme aktualizovat naše mapování. Také testy, které generují databázové tabulky a omezení z mapování, to z nějakého důvodu nebudou chtít (např. pokud by došlo k porušení omezení v obrovském množství testovacích dat).

Zde je příklad rozšířeného použití ON v Eclipselink (není součástí standardu JPA 2.1). Tento spojuje osoby se stejným názvem města:

JOIN ON s více kořenovými entitami

SELECT p FROM Person p LEFT JOIN Person p2 ON p2.city = p.city

Java Tag