JPA / Hibernate Projections

1. Áttekintés

Ebben az oktatóanyagban megtanuljuk hogyan lehet az entitás tulajdonságait kivetíteni a JPA és a Hibernate használatával.

2. Az entitás

Először nézzük meg azt az entitást, amelyet a cikkben használni fogunk:

@Entity public class Product {@Id private long id; privát karakterlánc neve; privát karakterlánc leírása; privát húr kategória; privát BigDecimal unitPrice; // beállítók és szerelők}

Ez egy egyszerű entitásosztály, amely különféle tulajdonságokkal rendelkező terméket képvisel.

3. A KPK előrejelzései

Noha a JPA specifikációja nem említi kifejezetten az előrejelzéseket, sok esetben elképzelhetőnek találjuk őket.

Jellemzően egy JPQL lekérdezésnek van egy entitásjelöltje. A lekérdezés végrehajtáskor létrehozza a jelölt osztály objektumait - az összes tulajdonságukat feltölti a lekérdezett adatok felhasználásával.

De lehetséges beolvassa az entitás tulajdonságainak egy részhalmazát, vagy vagyis a kivetítés oszlopadatok.

Az oszlopadatokon kívül vetíthetjük a csoportosítási funkciók eredményeit is.

3.1. Egyoszlopos vetületek

Tegyük fel, hogy fel akarjuk sorolni az összes termék nevét. A JPQL-ben ezt úgy tehetjük meg, hogy csak a név ban,-ben válassza kikötés:

Lekérdezés = entitásManager.createQuery ("válasszon nevet a termékből"); List resultList = lekérdezés.getResultList ();

Vagy megtehetjük ugyanezt CriteriaBuilder:

CriteriaBuilder builder = entitásManager.getCriteriaBuilder (); CriteriaQuery lekérdezés = builder.createQuery (String.osztály); Gyökértermék = query.from (Product.class); query.select (product.get ("név")); List resultList = entitásManager.createQuery (lekérdezés) .getResultList ();

Mivel egyetlen oszlopot vetítünk, amely véletlenül típusú Húr, azt várjuk, hogy kapunk egy listát Húrs az eredményben. Ezért megadtuk a jelölt osztályt Húr ban,-ben createQuery () módszer.

Mivel egyetlen ingatlanra akarunk vetíteni, használtuk a Query.select () módszer. Itt az történik, hogy melyik ingatlant akarjuk, ezért esetünkben a név ingatlan a miénktől Termék entitás.

Most nézzük meg a fenti két lekérdezés által létrehozott mintakimenetet:

Termék neve 1 Termék neve 2 Termék neve 3 Termék neve 4

Vegye figyelembe, hogy ha használnánk a id tulajdonság a vetületben név, a lekérdezés a (z) listáját adta volna vissza Hosszú tárgyakat.

3.2. Többoszlopos vetületek

Több oszlopra vetítéshez JPQL használatával csak az összes szükséges oszlopot hozzá kell adnunk a válassza kikötés:

Lekérdezés = session.createQuery ("válasszon azonosítót, nevet, egységárat a termékből"); List resultList = lekérdezés.getResultList ();

De, ha a CriteriaBuilder, kicsit másképp kell csinálnunk a dolgokat:

CriteriaBuilder builder = session.getCriteriaBuilder (); CriteriaQuery lekérdezés = builder.createQuery (Object []. Class); Gyökértermék = query.from (Product.class); query.multiselect (product.get ("id"), product.get ("név"), product.get ("unitPrice")); List resultList = entitásManager.createQuery (lekérdezés) .getResultList ();

Itt, használtuk a módszert többszörös választás() ahelyett válassza (). Ezzel a módszerrel több elemet is meghatározhatunk.

Egy másik jelentős változás a Tárgy[]. Amikor több elemet választunk ki, a lekérdezés egy objektum tömböt ad vissza az egyes vetített tételek értékével. Ez a helyzet a JPQL esetében is.

Nézzük meg, hogy néznek ki az adatok, amikor kinyomtatjuk őket:

[1, 1. terméknév, 1.40] [2, 2. terméknév, 4.30] [3, 3. terméknév, 14.00] [4, 4. terméknév, 3.90]

Mint láthatjuk, a visszaküldött adatok feldolgozása kissé nehézkes. De szerencsére elérhetjük a JPA-t, hogy ezeket az adatokat egyéni osztályba töltse fel.

Továbbá használhatjuk CriteriaBuilder.tuple () vagy CriteriaBuilder.construct () hogy az eredményeket felsorolja Tuple objektumok vagy egyedi osztály objektumai.

3.3. Összesített függvények kivetítése

Az oszlopadatokon kívül néha érdemes lehet az adatokat csoportosítani és összesítő függvényeket használni, mint a számol és átlagos.

Tegyük fel, hogy meg akarjuk találni az egyes kategóriákba tartozó termékek számát. Ezt megtehetjük a számol() összesítő függvény JPQL-ben:

Lekérdezés = entitásManager.createQuery ("válasszon p.kategóriát, számolja meg (p) a termék p csoportból p.kategória szerint");

Vagy használhatjuk CriteriaBuilder:

CriteriaBuilder builder = entitásManager.getCriteriaBuilder (); CriteriaQuery lekérdezés = builder.createQuery (Object []. Class); Gyökértermék = query.from (Product.class); query.multiselect (termék.get ("kategória"), építő.szám (termék)); query.groupBy (product.get ("kategória"));

Itt használtuk CriteriaBuilder’S számol() módszer.

A fentiek bármelyikének felhasználásával létrehozza az objektumtömbök listáját:

[kategória1, 2] [kategória2, 1] [kategória3, 1]

Attól eltekintve számol(), CriteriaBuilder különféle egyéb összesítő funkciókat biztosít:

  • Átl - Kiszámítja egy csoport oszlopának átlagos értékét
  • max - Kiszámítja egy csoport oszlopának maximális értékét
  • min - Kiszámítja a csoport oszlopának minimális értékét
  • legkevésbé - Megtalálja a legkevesebb oszlopértéket (például ábécé sorrendben vagy dátum szerint)
  • összeg - Kiszámítja a csoport oszlopértékeinek összegét

4. Hibernált vetületek

A JPA-tól eltérően a Hibernate biztosítja org.hibernate.criterion.Projection vetítéshez a Kritériumok lekérdezés. Osztályt is biztosít org.hibernate.criterion.Projections, gyár Kivetítés példányok.

4.1. Egyoszlopos vetületek

Először nézzük meg, hogyan vetíthetünk ki egyetlen oszlopot. A korábban látott példát használjuk:

Feltételek kritériumai = session.createCriteria (Product.class); kritériumok = szempontok.setProjection (Projekciók.tulajdonság ("név")); 

Felhasználtuk a Criteria.setProjection () metódus a lekérdezés eredményében kívánt tulajdonság megadására. Projections.property () ugyanazt a munkát végzi értünk, mint Root.get () tette a kijelölendő oszlop megjelölésekor.

4.2. Többoszlopos vetületek

Több oszlop kivetítéséhez először létre kell hoznunk a ProjectionList. ProjectionList egy különleges fajtája Kivetítés hogy beburkolja a többi vetületet lehetővé teszi több érték kiválasztását.

Hozhatunk létre a ProjectionListhasználni a Projections.projectionList () módszer, mint például a Termék’S id és név:

Feltételek kritériumai = session.createCriteria (Product.class); feltételek = kritériumok.setProjection (Projections.projectionList () .add (Projections.id ()) .add (Projections.property ("név")));

4.3. Összesített függvények kivetítése

Mint CriteriaBuilder, a Vetítések osztály az összesített függvények módszereit is biztosítja.

Lássuk, hogyan tudjuk megvalósítani a korábban látott számlálási példát:

Feltételek kritériumai = session.createCriteria (Product.class); kritériumok = kritériumok.setProjection (Projections.projectionList () .add (Projections.groupProperty ("kategória")) .add (Projections.rowCount ()));

Fontos megjegyezni nem határoztuk meg közvetlenül a GROUP BY-t a Kritériumok tárgy. Hívás groupProperty kiváltja ezt számunkra.

Eltekintve a rowCount () funkció, Vetítések a korábban látott összesített függvényeket is biztosítja.

4.4. Alias ​​használata vetítéshez

A Hibernate Criteria API érdekes tulajdonsága, hogy álnevet használnak a vetítéshez.

Ez különösen akkor hasznos, ha összesített függvényt használunk, mivel ezután az aliasra hivatkozhatunk Kritérium és Rendelés példányok:

Feltételek kritériumai = session.createCriteria (Product.class); kritériumok = szempontok.setProjection (Projections.projectionList () .add (Projections.groupProperty ("kategória")) .add (Projections.alias (Projections.rowCount (), "count"))); feltételek.addOrder (Rendelés.asc ("számlálás"));

5. Következtetés

Ebben a cikkben azt láttuk, hogyan lehet az entitástulajdonságokat kivetíteni a JPA és a Hibernate használatával.

Fontos megjegyezni, hogy A Hibernate elavult a Criteria API-tól az 5.2-es verziótól kezdve a JPA CriteriaQuery API javára. De ez csak azért van, mert a Hibernate csapatnak nincs ideje két különböző API-t tartani, amelyek nagyjából ugyanazt teszik, szinkronban.

Természetesen az ebben a cikkben használt kód megtalálható a GitHubon.