2.1 Introdução às classes Query

A propósito, outro ponto importante é a classe auxiliar Query. Você pode ver neste exemplo:

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

Na verdade, a Consulta é uma interface e possui várias implementações para diferentes casos. Mas, para simplificar, continuarei a chamá-lo de classe. Esta é, digamos, uma classe em um sentido amplo - em termos de OOP.

Observação. Antes havia duas classes:

  • Consulta para descrever a consulta.
  • TypedQuery para descrever uma consulta com um tipo conhecido.

A primeira surgiu quando o Hibernate já existia, e ainda não existiam genéricos. Então, após o lançamento do JDK 5, outra classe foi adicionada ao Hibernate - TypedQuery, que já suportava a digitação do resultado da consulta.

Mas, pelo que me lembro, a partir da 5ª versão do Hibernate, restava apenas uma classe digitada, que agora se chama Consulta.

A maneira padrão de criar uma consulta é:


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

Você aprendeu a criar objetos Query, mas como executar essas consultas?

É ainda mais simples aqui - apenas chamamos o método list() no objeto Query:


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

O método list() tem um sinônimo JPA, um método que faz a mesma coisa, mas é chamado getResultList() . Às vezes, você pode vê-lo no código escrito por outros programadores.

A propósito, se a consulta implicar que o resultado será um único resultado, será mais fácil usar o método uniqueResult() para chamar a consulta .


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

O método uniqueResult() possui um sinônimo JPA, o método singleResult() . Foi introduzido para compatibilidade do Hibernate com o padrão JPA. Ele faz exatamente a mesma coisa.

2.2 Métodos de classe de consulta

Na verdade, a classe Query tem muitos métodos diferentes. Abaixo falarei sobre mais três deles.

O primeiro é o método stream() . E seu sinônimo JPA getResultStream() .

Ambos os métodos retornam um fluxo de dados em vez de uma lista. Essa abordagem pode ser muito eficiente quando você não precisa de todos os objetos obtidos como resultado de uma consulta de uma só vez. Ou existe a possibilidade de apenas o primeiro deles ser usado.

Exemplo:


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

O segundo método é o método executeUpdate() . Você pode escrever uma consulta que mudará algo no banco de dados. Neste caso, é necessário que o Hibernate não utilize uma transação somente leitura ao acessar o banco de dados.

Exemplo de solicitação: decidimos aumentar o nível de todos os usuários em 1.


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

O método executeUpdate() retornará o número de linhas que foram realmente modificadas.

E, finalmente, o terceiro método é scroll() . Nós vamos te contar um pouco mais sobre isso.

2.3 Métodos de classe Scroll

Esse método é um pouco semelhante ao método stream() . Somente ele permite que você percorra a lista de resultados sem retirar os resultados. Ou seja, você pode executar uma consulta, rolar até a milionésima linha do resultado e começar a ler os dados a partir daí.

Um iterador tão avançado.


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

O objeto ScrollableResults possui os seguintes métodos:

Método Descrição
R get() Retorna o elemento atual
próximo() Move o ponteiro para o próximo elemento
anterior() Move o ponteiro para o elemento anterior
scroll(tamanho int) Rolar para frente por linhas de tamanho
posição (int pos) Torna o número de posição do elemento o elemento atual
durar() O elemento atual é agora o último
primeiro() O elemento atual é agora o primeiro
getRowNumber() Retorna o número da linha atual
setRowNumber() Define o número da linha atual

Digamos que você executou uma consulta e deseja obter o último elemento. Veja como fazer:


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