2.1 Introduktion till Query-klasserna

En annan viktig punkt är förresten Query-hjälparklassen. Du kan se det i det här exemplet:

public List<Employee> getAllEmployes() {
    try (Session session = sessionFactory.openSession()) {
            Query<Employee> query = session.createQuery("from Employee", Employee.class);
            return query.list();
    }
}

Faktum är att Query är ett gränssnitt och det har flera implementeringar för olika fall. Men för enkelhetens skull kommer jag att fortsätta kalla det en klass. Det här är, låt oss säga, en klass i vid mening – i termer av OOP.

Notera. Det brukade vara två klasser:

  • Fråga för att beskriva frågan.
  • TypedQuery för att beskriva en fråga med en känd typ.

Den första dök upp när Hibernate redan fanns, och det fanns inga generika ännu. Sedan, efter lanseringen av JDK 5, lades en annan klass till i Hibernate - TypedQuery, som redan stödde inskrivning av frågeresultatet.

Men så vitt jag minns, från och med den 5:e versionen av Hibernate, fanns bara en maskinskriven klass kvar, och den heter nu Query.

Standardsättet att skapa en fråga är:


Query<Employee> query = session.createQuery("from Employee", Employee.class);

Du lärde dig hur man skapar frågeobjekt, men hur kör man dessa frågor?

Det är ännu enklare här - vi anropar bara metoden list() på Query-objektet:


Query<Employee> query = session.createQuery("from Employee", Employee.class);
List<Employee> resultLіst = query.list();

Metoden list() har en JPA-synonym, en metod som gör samma sak men som kallas getResultList() . Du kan ibland se det i kod skriven av andra programmerare.

Förresten, om frågan antyder att resultatet kommer att finnas i ett enda resultat, är det lättare att använda metoden uniqueResult() för att anropa frågan .


Query<Employee> query = session.createQuery("from Employee where id = 1", Employee.class);
Employee result = query.uniqueResult();

Metoden uniqueResult() har en JPA-synonym, metoden singleResult() . Den introducerades för Hibernates kompatibilitet med JPA-standarden. Han gör exakt samma sak.

2.2 Frågeklassmetoder

Faktum är att Query-klassen har många olika metoder. Nedan kommer jag att prata om ytterligare tre av dem.

Den första är metoden stream() . Och dess JPA-synonym getResultStream() .

Båda dessa metoder returnerar en dataström istället för en lista. Detta tillvägagångssätt kan vara mycket effektivt när du inte behöver alla objekt som erhålls som ett resultat av en fråga på en gång. Eller så finns det en möjlighet att bara den första av dem kommer att användas.

Exempel:


Query<Employee> query = session.createQuery("from Employee where id > 100", Employee.class);
Stream<Employee> stream = query.stream();

Den andra metoden är metoden executeUpdate() . Du kan skriva en fråga som kommer att ändra något i databasen. I det här fallet är det nödvändigt att Hibernate inte använder en skrivskyddad transaktion vid åtkomst till databasen.

Exempel på begäran: vi beslutade att höja nivån på alla användare med 1.


Query<User> query = session.createQuery("update User set level=level+1", User.class);
int count = query.executeUpdate();

Metoden executeUpdate() returnerar antalet rader som faktiskt har ändrats.

Och slutligen är den tredje metoden scroll() . Vi kommer att berätta lite mer om det.

2.3 Scrollklassmetoder

Denna metod liknar till viss del stream() -metoden . Bara det låter dig gå igenom resultatlistan utan att dra ut resultaten alls. Det vill säga, du kan köra en fråga, sedan rulla den till den miljonte raden i resultatet och börja läsa data därifrån.

En sådan avancerad iterator.


Query<Employee> query = session.createQuery("from Employee where id > 100", Employee.class);
ScrollableResults<Employee> scroll = query.scroll();

ScrollableResults -objektet har följande metoder:

Metod Beskrivning
R få() Returnerar det aktuella elementet
Nästa() Flyttar pekaren till nästa element
tidigare() Flyttar pekaren till föregående element
scroll (int storlek) Rulla framåt efter storlekslinjer
position(int pos) Gör elementets posnummer till det aktuella elementet
sista() Det aktuella elementet är nu det sista
först() Det nuvarande elementet är nu det första
getRowNumber() Returnerar det aktuella radnumret
setRowNumber() Ställer in det aktuella radnumret

Låt oss säga att du körde en fråga och du vill få det sista elementet. Så här gör du:


Query<Employee> query = session.createQuery("from Employee where id > 100", Employee.class);
ScrollableResults<Employee> scroll = query.scroll();
scroll.last();
Employee lastEmployee = scroll.get();