Útmutató az SqlResultSetMapping alkalmazáshoz
1. Bemutatkozás
Ebben az útmutatóban megnézzük SqlResultSetMapping, a Java Persistence API-ból (JPA).
Az alapvető funkcionalitás itt magában foglalja az eredményhalmazok leképezését adatbázis SQL utasításokból Java objektumokba.
2. Beállítás
Mielőtt megvizsgálnánk a használatát, végezzünk néhány beállítást.
2.1. Maven-függőség
Szükséges Maven-függőségeink a Hibernate és a H2 Database. A hibernálás lehetővé teszi számunkra a JPA specifikáció megvalósítását. A H2 adatbázist használjuk egy memóriában lévő adatbázishoz.
2.2. Adatbázis
Ezután létrehozunk két táblázatot, az itt látható módon:
CREATE TABLE MUNKAVÁLLALÓ (id BIGINT, név VARCHAR (10));
A MUNKAVÁLLALÓ táblázat egy eredményt tárol Entitás tárgy. SCHEDULE_DAYS fájlhoz kapcsolódó rekordokat tartalmaz MUNKAVÁLLALÓ oszlop mellett munkavállalói azonosító:
CREATE TABLE SCHEDULE_DAYS (azonosító azonosító, workerId BIGINT, dayOfWeek VARCHAR (10));
Az adat létrehozásának szkriptje megtalálható az útmutató kódjában.
2.3. Entitás objektumok
A mi Entitás az objektumoknak hasonlónak kell lenniük:
@Entity public class Employee {@Id private Long id; privát karakterlánc neve; }
Entitás lehet, hogy az objektumokat másként nevezik meg, mint az adatbázis táblákat. Megjegyezhetjük az osztályt a @ -valasztal hogy kifejezetten feltérképezzék őket:
@Entity @Table (name = "SCHEDULE_DAYS") public class ScheduledDay {@Id @GeneratedValue private Long id; magán Hosszú alkalmazottId; privát String dayOfWeek; }
3. Skaláris leképezés
Most, hogy van adatunk, megkezdhetjük a lekérdezés eredményeinek feltérképezését.
3.1. Oszlop eredménye
Míg SqlResultSetMapping és Lekérdezés az annotációk működnek Adattár osztályoknál is, az an-on használjuk a kommentárokat Entitás osztály ebben a példában.
Minden SqlResultSetMapping a megjegyzés csak egy tulajdonságot igényel, név. Az egyik tagtípus nélkül azonban semmi sem kerül feltérképezésre. A tagok típusai Oszlop eredménye, ConstructorResult, és EntityResult.
Ebben az esetben, Oszlop eredménye bármely oszlopot skaláris eredménytípushoz rendel:
@SqlResultSetMapping (név = "FridayEmployeeResult", oszlop = {@ ColumnResult (név = "workerId")})
A Oszlop eredménye ingatlan név azonosítja a lekérdezés oszlopát:
@NamedNativeQuery (név = "FridayEmployees", lekérdezés = "SELECT personalId FROM schedule_days WHERE dayOfWeek = 'FRIDAY'", resultSetMapping = "FridayEmployeeResult")
Vegye figyelembe, hogy az értéke resultSetMapping miénkben NamedNativeQuery annotáció fontos, mert megfelel a név ingatlan a miénktől ResultSetMapping nyilatkozat.
Ennek eredményeként a NamedNativeQuery az eredménykészlet a várakozásoknak megfelelően van feltérképezve. Hasonlóképpen, Tárolt eljárás Az API megköveteli ezt a társítást.
3.2. Oszlop eredménye Teszt
Szükségünk lesz néhány hibernált objektumra a kódunk futtatásához:
@BeforeAll public static void setup () {emFactory = Persistence.createEntityManagerFactory ("java-jpa-tervezett-nap"); em = emFactory.createEntityManager (); }
Végül meghívjuk a megnevezett lekérdezést a teszt futtatásához:
@Test public void whenNamedQuery_thenColumnResult () {List workerIds = em.createNamedQuery ("FridayEmployees"). GetResultList (); assertEquals (2, workerIds.size ()); }
4. Konstruktor feltérképezése
Vessünk egy pillantást arra, amikor egy teljes halmaz eredményét össze kell térképeznünk.
4.1. ConstructorResult
Hasonlóan a miénkhez Oszlop eredménye Például hozzáadjuk a SqlResultMapping annotáció a mi Entitás osztály, ScheduledDay. Ahhoz azonban, hogy egy konstruktor segítségével térképezzünk fel, létre kell hoznunk egyet:
public ScheduledDay (Hosszú id, Hosszú alkalmazottId, Egész óraInIn, Egész óra hour, Kimenet, String dayofWeek) {this.id = id; this.employeeId = alkalmazottId; this.dayOfWeek = dayofWeek; }
Ezenkívül a leképezés megadja a célosztályt és az oszlopokat (mindkettő szükséges):
@SqlResultSetMapping (név = "ScheduleResult", osztályok = {@ConstructorResult (targetClass = com.baeldung.sqlresultsetmapping.ScheduledDay.class, oszlopok = {@ColumnResult (name = "id", type = Long.class), @ColumnResult (név = "workerId", type = Long.class), @ColumnResult (név = "dayOfWeek")})}})
A. Sorrendje Oszloperedmények nagyon fontos. Ha az oszlopok rendezetlenek, akkor a konstruktort nem lehet azonosítani. Példánkban a sorrend megfelel a táblázat oszlopainak, tehát valójában nem lenne rá szükség.
@NamedNativeQuery (név = "Ütemezések", lekérdezés = "KIVÁLASZTÁS * FROM ütemezés_napok WHERE alkalmazottId = 8", resultSetMapping = "Ütemezés eredmény")
Egy másik egyedülálló különbség a ConstructorResult az, hogy az így létrejövő objektum példányosítása „új” vagy „leválasztott”. A feltérképezett Entitás leválasztott állapotban lesz, amikor egy megfelelő elsődleges kulcs létezik a EntityManager különben új lesz.
Néha futásidejű hibákkal találkozhatunk, mivel az SQL adattípusok eltérnek a Java adattípusoktól. Ezért kifejezetten kijelenthetjük a típus.
4.2. ConstructorResult Teszt
Teszteljük a ConstructorResult egység tesztben:
@Test public void whenNamedQuery_thenConstructorResult () {List scheduleDays = Collections.checkedList (em.createNamedQuery ("Schedules", ScheduledDay.class) .getResultList (), ScheduledDay.class); assertEquals (3, scheduleDays.size ()); assertTrue (scheduleDays.stream (). allMatch (c -> c.getEmployeeId (). longValue () == 3)); }
5. Entitás leképezése
Végül egy egyszerű entitás leképezéséhez kevesebb kóddal nézzük meg EntityResult.
5.1. Egyetlen entitás
EntityResult megköveteli, hogy adjuk meg az entitás osztályt, Munkavállaló. Az opcionálisat használjuk mezők tulajdonság a nagyobb ellenőrzés érdekében. Társítva valamivel FieldResult, feltérképezhetjük az álneveket és a nem megfelelő mezőket:
@SqlResultSetMapping (név = "EmployeeResult", entitások = {@EntityResult (entitásClass = com.baeldung.sqlresultsetmapping.Employee.class, mezők = {@FieldResult (név = "id", oszlop = "alkalmazotti szám"), @FieldResult (név = "név", oszlop = "név")})})
Most a lekérdezésünknek tartalmaznia kell az álneves oszlopot:
@NamedNativeQuery (név = "Alkalmazottak", lekérdezés = "KIVÁLASZTÁS azonosító mint munkavállalói szám, név FROM EMPLOYEE", resultSetMapping = "EmployeeResult")
Hasonlóan ConstructorResult, EntityResult kivitelezőt igényel. Az alapértelmezett azonban itt működik.
5.2. Több entitás
Több entitás leképezése nagyon egyszerű, ha egyetlen entitást feltérképeztünk:
@SqlResultSetMapping (név = "EmployeeScheduleResults", entitások = {@EntityResult (entitásClass = com.baeldung.sqlresultsetmapping.Employee.class), @EntityResult (entitásClass = com.baeldung.sqlresultsetmay.Scheduled
5.3. EntityResult Tesztek
Nézzük meg EntityResult működés közben:
@Test public void whenNamedQuery_thenSingleEntityResult () {List alkalmazottak = Collections.checkedList (em.createNamedQuery ("Alkalmazottak"). GetResultList (), Employee.class); assertEquals (3, alkalmazottak.méret ()); assertTrue (alkalmazottak.stream (). allMatch (c -> c.getClass () == Munkavállaló.osztály)); }
Mivel a több entitás eredménye két entitáshoz csatlakozik, a lekérdezés annotációja csak az egyik osztálynál zavaró.
Ezért meghatározzuk a lekérdezést a tesztben:
@Test public void whenNamedQuery_thenMultipleEntityResult () {Query query = em.createNativeQuery ("SELECT e.id, e.név, d.id, d.employeeId, d.dayOfWeek" + "FROM alkalmazott e, menetrend_napok d" + "HOL .id = d.employeeId "," EmployeeScheduleResults "); Eredmények felsorolása = query.getResultList (); assertEquals (4, eredmények.méret ()); assertTrue (eredmények.get (0) .hossz == 2); Employee emp = (Employee) results.get (1) [0]; ScheduledDay day = (ScheduledDay) results.get (1) [1]; assertTrue (day.getEmployeeId () == emp.getId ()); }
6. Következtetés
Ebben az útmutatóban megvizsgáltuk a SqlResultSetMapping annotáció. SqlResultSetMapping kulcsfontosságú része a Java Persistence API-nak.
A kódrészletek megtalálhatók a GitHubon.