NativeQuery

Tilgjengelig

3.1 Introduksjon

En annen nyttig ting jeg ønsker å snakke om er NativeQuery . Som du allerede vet, ved å bruke NativeQuery, kan du skrive spørringer i naturlig SQL. Det som imidlertid er enda mer interessant er at du ikke trenger å bruke klassekartlegging når du får søkeresultatet.

Jeg vil heller vise deg et eksempel:

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

I dette eksemplet sender vi ikke en klasse som samsvarer med søkeresultatradene, i stedet bruker vi bare en rekke Object-objekter.

Dette kan være nyttig hvis du bare vil velge et par kolonner i en tabell. Eksempel:

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

Dette ligner litt på JDBC-tilnærmingen når du får et ResultSet-objekt og leser data fra radene.

Hibernate tilbyr imidlertid forskjellige måter å gjøre dette mer pålitelig på. Du kan for eksempel spesifisere typen kolonner du vil trekke fra. Eksempel:

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 Entitetskartlegging

Du kan også spesifisere klassen som Hibernate skal bruke når du analyserer resultatet av NativeQuery . Dette kan gjøres på forskjellige måter.

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

Og selvfølgelig det gode gamle formatet du vet:

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

Den første tilnærmingen er den native Hibernate-tilnærmingen og den andre er JPA-tilnærmingen. JPA-tilnærmingen er mer praktisk og konsis, siden denne standarden ble oppfunnet etter at Hibernate eksisterte i mange år. Og Hibernate utviklet seg og ble tvunget til å støtte gamle tilnærminger for å opprettholde kompatibilitet med de gamle versjonene.

Forresten, takket være tilnærmingen, lar Hibernate deg ikke koble til én klasse til kartleggingen av søkeresultater, men flere klasser. Eksempel:

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

Denne tilnærmingen som bruker NativeQuery kan brukes til å øke hastigheten på utvalget av data fra databasen. Hvis du vet at du ikke trenger noen kolonner, kan du utelate dem i forespørselen.

Du kan også laste inn alle underordnede enheter samtidig, selv om Hibernate ønsker å bruke Cache eller LazyLoading -mekanismen . I tillegg kan de underordnede enhetene dine ha mange kolonner i databasen, og du kan bare velge noen av dem.

3.3 DTO-kartlegging

Hibernate lar deg også bruke ikke-Entity-klasser for å kartlegge resultatet. Klasser som ikke har noen merknader og som ikke er tilordnet noen tabeller.

Eksempel:

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

Siden det ikke er merknader i PersonSummaryDTO-klassen, må navnene på kolonnene i SQL-spørringen samsvare nøyaktig med navnene på feltene i PersonSummaryDTO-klassen.

Dette kan være svært nyttig hvis du leser data fra en ekstern database som applikasjonen din er koblet til kun i skrivebeskyttet modus. Det vil si at du fikk tilgang til tabeller som har 50+ kolonner, de lagrer data i en denormalisert form for å fremskynde utvalget.

Eller la oss si at noen bestemte seg for å lagre klassehierarkiet i én tabell, og på fem år har dette bordet vokst så mye at djevelen vil brekke beinet. Du må velge et par kolonner fra denne tabellen (Id og brukernavn) og gi dem til klienten.

Jeg tror du forstår, men hvis du vil dykke dypere inn i dette temaet kan du lese mer på lenken:

Innebygde SQL-spørringer

Kommentarer
  • Populær
  • Ny
  • Gammel
Du må være pålogget for å legge igjen en kommentar
Denne siden har ingen kommentarer ennå