NativeQuery

Tillgängliga

3.1 Inledning

En annan användbar sak jag skulle vilja prata om är NativeQuery . Som du redan vet kan du med NativeQuery skriva frågor i inbyggd SQL. Vad som är ännu mer intressant är att du inte behöver använda klassmappning när du får frågeresultatet.

Jag skulle hellre visa dig ett exempel:

List<Object[]> persons = session.createNativeQuery("SELECT * FROM Person").list();

I det här exemplet skickar vi inte en klass som matchar frågeresultatraderna, istället använder vi bara en array av objektobjekt.

Detta kan vara användbart om du bara vill välja ett par kolumner i en tabell. Exempel:

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];
}

Detta liknar något JDBC-metoden när du får ett ResultSet-objekt och läser data från dess rader.

Hibernate erbjuder dock olika sätt att göra detta mer tillförlitligt. Du kan till exempel ange vilken typ av kolumner du vill subtrahera. Exempel:

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 Entitetskartläggning

Du kan också uttryckligen ange den klass som Hibernate ska använda när resultatet av NativeQuery tolkas . Detta kan göras på olika sätt.

Query<Person> query = session.createNativeQuery("SELECT * FROM Person")
    .addEntity(Person.class);
    .list();

Och naturligtvis, det gamla goda formatet du vet:

Query<Person> query = session.createNativeQuery("SELECT * FROM Person", Person.class).list();

Den första metoden är den ursprungliga Hibernate-metoden och den andra är JPA-metoden. JPA:s tillvägagångssätt är bekvämare och mer kortfattat, eftersom denna standard uppfanns efter att Hibernate funnits i många år. Och Hibernate utvecklades och tvingades stödja gamla tillvägagångssätt för att bibehålla kompatibiliteten med sina gamla versioner.

Förresten, tack vare dess tillvägagångssätt låter Hibernate dig ansluta inte en klass till frågeresultatmappningen, utan flera klasser. Exempel:

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() );
}

Detta tillvägagångssätt med NativeQuery kan användas för att påskynda valet av data från databasen. Om du vet att du inte behöver några kolumner kan du utelämna dem i förfrågan.

Du kan också ladda alla underordnade enheter på en gång, även om Hibernate vill använda Cache eller LazyLoading -mekanismen . Dessutom kan dina underordnade enheter ha många kolumner i databasen, och du kan bara välja några av dem.

3.3 DTO-mappning

Hibernate låter dig också använda icke-Entity-klasser för att kartlägga resultatet. Klasser som inte har några anteckningar och som inte är mappade till några tabeller.

Exempel:

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();

Eftersom det inte finns några anteckningar i klassen PersonSummaryDTO måste namnen på kolumnerna i SQL-frågan exakt matcha namnen på fälten i klassen PersonSummaryDTO.

Detta kan vara mycket användbart om du läser data från en extern databas som din applikation är ansluten till endast i skrivskyddat läge. Det vill säga att du fick tillgång till tabeller som har 50+ kolumner, de lagrar data i en denormaliserad form för att påskynda urvalet.

Eller låt oss säga att någon bestämde sig för att lagra klasshierarkin i en tabell, och på fem år har det här bordet vuxit så mycket att djävulen kommer att bryta benet. Du måste välja ett par kolumner från denna tabell (Id och användarnamn) och ge dem till klienten.

Jag tror att du förstår, men om du vill dyka djupare in i detta ämne kan du läsa mer på länken:

Inbyggda SQL-frågor

Kommentarer
  • Populär
  • Ny
  • Gammal
Du måste vara inloggad för att lämna en kommentar
Den här sidan har inga kommentarer än