3.1 Bevezetés
Egy másik hasznos dolog, amiről szeretnék beszélni, a NativeQuery . Mint már tudja, a NativeQuery használatával natív SQL-ben írhat lekérdezéseket. Azonban ami még érdekesebb, hogy nem kell osztályleképezést használnia a lekérdezés eredményének lekérésekor.
Inkább mutatok egy példát:
List<Object[]> persons = session.createNativeQuery("SELECT * FROM Person").list();
Ebben a példában nem adunk át olyan osztályt, amely megfelel a lekérdezés eredménysorainak, ehelyett csak egy Object objektumok tömbjét használjuk.
Ez akkor lehet hasznos, ha csak néhány oszlopot szeretne kijelölni egy táblázatban. Példa:
List<Object[]> persons = session.createNativeQuery("SELECT id, name FROM Person").list();
for(Object[] person : persons) {
Number id = (Number) person[0];
String name = (String) person[1];
}
Ez némileg hasonlít a JDBC megközelítéshez, amikor egy ResultSet objektumot kap, és adatokat olvas ki a soraiból.
A Hibernate azonban különféle módokat kínál ennek megbízhatóbbá tételére. Például megadhatja a kivonni kívánt oszlopok típusát. Példa:
Query<Object[]> query = session.createNativeQuery("SELECT id, name FROM Person");
query.addScalar("id", StandardBasicTypes.LONG);
query.addScalar("name", StandardBasicTypes.STRING);
List<Object[]> persons = query.list();
for(Object[] person : persons) {
Long id = (Long) person[0];
String name = (String) person[1];
}
3.2 Entitásleképezés
Explicit módon megadhatja azt az osztályt is, amelyet a Hibernate használjon a NativeQuery eredményének elemzésekor . Ezt különböző módon lehet megtenni.
Query<Person> query = session.createNativeQuery("SELECT * FROM Person")
.addEntity(Person.class);
.list();
És persze a régi jó formátum, amit ismersz:
Query<Person> query = session.createNativeQuery("SELECT * FROM Person", Person.class).list();
Az első megközelítés a natív hibernált megközelítés, a második pedig a JPA megközelítés. A JPA megközelítés kényelmesebb és tömörebb, mivel ezt a szabványt azután találták fel, hogy a Hibernate sok éven át létezett. A Hibernate pedig fejlődött, és kénytelen volt támogatni a régi megközelítéseket, hogy fenntartsa a kompatibilitást a régi verzióival.
A Hibernate egyébként megközelítésének köszönhetően nem egy osztályt, hanem több osztályt is lehetővé tesz a lekérdezési eredményleképezéshez. Példa:
List<Phone> results = session.createNativeQuery(
"SELECT {ph.*}, {pr.*}" +
"FROM Phone ph" +
"JOIN Person pr ON ph.person_id = pr.id")
.addEntity("ph", Phone.class)
.addJoin("pr", "ph.person")
.list();
for (Phone. phone : results) {
assertNotNull( phone.getPerson().getName() );
}
Ez a NativeQuery-t használó megközelítés felgyorsíthatja az adatok kiválasztását az adatbázisból. Ha tudja, hogy nincs szüksége néhány oszlopra, elhagyhatja őket a kérésben.
Az összes gyermek entitást egyszerre is betöltheti, még akkor is, ha a Hibernate a gyorsítótárat vagy a LazyLoading mechanizmust szeretné használni . Ezenkívül az alárendelt entitások sok oszlopot tartalmazhatnak az adatbázisban, és ezek közül csak néhányat választhat ki.
3.3 DTO leképezés
A hibernálás lehetővé teszi nem Entity osztályok használatát is az eredmény leképezéséhez. Osztályok, amelyek nem rendelkeznek megjegyzésekkel, és nincsenek hozzárendelve egyetlen táblázathoz sem.
Példa:
public class PersonSummaryDTO {
private Number id;
private String name;
public Number getId() {
return id;
}
public void setId(Number id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
List<PersonSummaryDTO> dtos = session.createNativeQuery(
"SELECT p.id as \"id\", p.name as \"name\" FROM Person p")
.setResultTransformer(Transformers.aliasToBean(PersonSummaryDTO.class) )
.list();
Mivel a PersonSummaryDTO osztályban nincsenek megjegyzések, az SQL lekérdezés oszlopainak nevének pontosan meg kell egyeznie a PersonSummaryDTO osztály mezőinek nevével.
Ez nagyon hasznos lehet, ha olyan külső adatbázisból olvas adatokat, amelyhez az alkalmazás csak olvasható módban csatlakozik. Vagyis olyan táblákhoz kaptál hozzáférést, amelyek 50+ oszlopot tartalmaznak, denormalizált formában tárolják az adatokat, hogy felgyorsítsák a kijelölést.
Vagy tegyük fel, hogy valaki úgy döntött, hogy egy táblázatban tárolja az osztályhierarchiát, és öt év alatt ez a táblázat annyira megnőtt, hogy az ördög eltöri a lábát. Ebből a táblázatból ki kell választani néhány oszlopot (Id és username), és át kell adni az ügyfélnek.
Szerintem érted, de ha szeretnél mélyebbre merülni ebben a témában, akkor a linken olvashatsz bővebben:
GO TO FULL VERSION