Como usar OrderBy com findAll no Spring Data

288

Estou usando dados da primavera e meu DAO parece

public interface StudentDAO extends JpaRepository<StudentEntity, Integer> {
    public findAllOrderByIdAsc();   // I want to use some thing like this
}

No código acima, a linha comentada mostra minha intenção. O Spring Data fornece funcionalidade embutida para usar esse método para localizar todos os pedidos de registros por alguma coluna com ASC / DESC?

Prashant Shilimkar
fonte

Respostas:

657
public interface StudentDAO extends JpaRepository<StudentEntity, Integer> {
    public List<StudentEntity> findAllByOrderByIdAsc();
}

O código acima deve funcionar. Estou usando algo parecido:

public List<Pilot> findTop10ByOrderByLevelDesc();

Retorna 10 linhas com o nível mais alto.

IMPORTANTE: Como me disseram que é fácil perder o ponto principal desta resposta, aqui está um pequeno esclarecimento:

findAllByOrderByIdAsc(); // don't miss "by"
       ^
Sikor
fonte
4
Para a sua assinatura do método funcione como pretendido com a Primavera de dados JPA, você deve incluir o "tudo" palavra-chave, assim: List<StudentEntity> findAllByOrderByIdAsc();. Adicionando um tipo de retorno e remover o modificador público redundante também é uma boa idéia;)
Håvard Geithus
1
Concordo que o público é redundante, mas mantém as coisas claras caso alguém precise trabalhar no seu código. Você nunca sabe quem será: o PI não mudou nada além do nome do método no código dos autores porque não é onde estava o problema e se alguém não sabe o que deve estar lá, esperamos aprender algo novo. Além disso, está no meu exemplo abaixo, para que eles não precisem procurar, Deus sabe onde, mas se você insistir, que seja assim :) Adicionado a palavra-chave "all" Obrigado.
Sikor 21/04/2015
73
Observe que o pouco Byantes da OrderBypalavra - chave faz toda a diferença.
Stefan Haberl
5
Ainda não entendo por que é necessário adicionar um extra Byna frente OrderBy. A documentação não fala sobre isso .
Xtreme Biker
3
@XtremeBiker No link da documentação que você forneceu: "No entanto, o primeiro By atua como delimitador para indicar o início dos critérios reais". Além disso, se você rolar para a seção "3.4.5. Limitando os resultados da consulta", na verdade há um exemplo como este, mas isso não é explicado.
Sikor 02/02
54

AFAIK, acho que isso não é possível com uma consulta de nomenclatura direta de método. No entanto, você pode usar o mecanismo de classificação incorporado, usando a Sortclasse O repositório possui um findAll(Sort)método para o qual você pode passar uma instância Sort. Por exemplo:

import org.springframework.data.domain.Sort;

@Repository
public class StudentServiceImpl implements StudentService {
    @Autowired
    private StudentDAO studentDao;

    @Override
    public List<Student> findAll() {
        return studentDao.findAll(sortByIdAsc());
    }

    private Sort sortByIdAsc() {
        return new Sort(Sort.Direction.ASC, "id");
    }
} 
Paul Samsotha
fonte
Isso é realmente possível utilizando findAllByOrderByIdAsc () conforme mencionado na resposta de Sikor abaixo ... @Prashant que realmente deve ser a resposta correta
Samuel Parsonage
Maneira alternativa de fazer a classificação na camada de serviço, se você quiser manter seus repositórios menos confusos. Tenha em mente o tamanho do resultado!
dkanejs
2
O método findAll()do tipo CrudRepository<>não é aplicável para os argumentos (Ordenar)
Thiago Pereira
5
@ThiagoPereira você deve estender JpaRepository<>se desejar usar o exemplo acima.
Waleed Abdalmajeed
15

Consulte a JPA de dados da primavera - documentação de referência, seção 5.3. Métodos de consulta , especialmente na seção 5.3.2. Criação de consulta , na " Tabela 3. Palavras- chave suportadas nos nomes dos métodos " (links a partir de 2019-05-03).

Eu acho que tem exatamente o que você precisa e a mesma consulta que você declarou que deve funcionar ...

shlomi33
fonte
1
Seu link não funciona -> Suponho que você queira apontar para este link: docs.spring.io/spring-data/jpa/docs/current/reference/html/…
Jørgen Skår Fischer
5

Maneira simples:

repository.findAll(Sort.by(Sort.Direction.DESC, "colName"));

Fonte: https://www.baeldung.com/spring-data-sorting

TizonDife Villiard
fonte
Existem 2 as mesmas respostas. E sua resposta teve a forma incorreta #
222 Dred
3

Sim, você pode classificar usando o método de consulta no Spring Data.

Ex: ordem crescente ou decrescente usando o valor do campo id.

Código:

  public interface StudentDAO extends JpaRepository<StudentEntity, Integer> {
    public findAllByOrderByIdAsc();   
}

solução alternativa:

    @Repository
public class StudentServiceImpl implements StudentService {
    @Autowired
    private StudentDAO studentDao;

    @Override
    public List<Student> findAll() {
        return studentDao.findAll(orderByIdAsc());
    }
private Sort orderByIdAsc() {
    return new Sort(Sort.Direction.ASC, "id")
                .and(new Sort(Sort.Direction.ASC, "name"));
}
}

Classificação de dados do Spring: Classificação

Narayan Yerrabachu
fonte
3

Eu tento neste exemplo mostrar um exemplo completo para personalizar as suas classificações OrderBy

 import java.util.List;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Sort;
 import org.springframework.data.jpa.repository.*;
 import org.springframework.data.repository.query.Param;
 import org.springframework.stereotype.Repository;
 import org.springframework.data.domain.Sort;
 /**
 * Spring Data  repository for the User entity.
 */
 @SuppressWarnings("unused")
 @Repository
 public interface UserRepository extends JpaRepository<User, Long> {
 List <User> findAllWithCustomOrderBy(Sort sort);
 }

você usará este exemplo: Um método para criar dinamicamente um objeto nessa instância de Sort:

import org.springframework.data.domain.Sort;
public class SampleOrderBySpring{
 Sort dynamicOrderBySort = createSort();
     public static void main( String[] args )
     {
       System.out.println("default sort \"firstName\",\"name\",\"age\",\"size\" ");
       Sort defaultSort = createStaticSort();
       System.out.println(userRepository.findAllWithCustomOrderBy(defaultSort ));


       String[] orderBySortedArray = {"name", "firstName"};
       System.out.println("default sort ,\"name\",\"firstName\" ");
       Sort dynamicSort = createDynamicSort(orderBySortedArray );
       System.out.println(userRepository.findAllWithCustomOrderBy(dynamicSort ));
      }
      public Sort createDynamicSort(String[] arrayOrdre) {
        return  Sort.by(arrayOrdre);
        }

   public Sort createStaticSort() {
        String[] arrayOrdre  ={"firstName","name","age","size");
        return  Sort.by(arrayOrdre);
        }
}
S. FRAJ
fonte
0

Combinando todas as respostas acima, você pode escrever código reutilizável com BaseEntity:

@Data
@NoArgsConstructor
@MappedSuperclass
public abstract class BaseEntity {

  @Transient
  public static final Sort SORT_BY_CREATED_AT_DESC = 
                        Sort.by(Sort.Direction.DESC, "createdAt");

  @Id
  private Long id;
  private LocalDateTime createdAt;
  private LocalDateTime updatedAt;

  @PrePersist
  void prePersist() {
    this.createdAt = LocalDateTime.now();
  }

  @PreUpdate
  void preUpdate() {
    this.updatedAt = LocalDateTime.now();
  }
}

O objeto DAO sobrecarrega o método findAll - basicamente, ainda usa findAll()

public interface StudentDAO extends CrudRepository<StudentEntity, Long> {

  Iterable<StudentEntity> findAll(Sort sort);

}

StudentEntityestende BaseEntityque contém campos repetíveis (talvez você também queira classificar por ID)

@Getter
@Setter
@FieldDefaults(level = AccessLevel.PRIVATE)
@Entity
class StudentEntity extends BaseEntity {

  String firstName;
  String surname;

}

Finalmente, o serviço e uso dos SORT_BY_CREATED_AT_DESCquais provavelmente serão usados ​​não apenas no StudentService.

@Service
class StudentService {

  @Autowired
  StudentDAO studentDao;

  Iterable<StudentEntity> findStudents() {
    return this.studentDao.findAll(SORT_BY_CREATED_AT_DESC);
  }
}
J.Wincewicz
fonte