Come usare OrderBy con findAll in Spring Data


290

Sto usando i dati di primavera e il mio DAO sembra

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

Nel codice sopra, la riga commentata mostra il mio intento. Spring Data può fornire funzionalità integrate per utilizzare tale metodo per trovare tutti i record in ordine di una colonna con ASC / DESC?

Risposte:


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

Il codice sopra dovrebbe funzionare. Sto usando qualcosa di simile:

public List<Pilot> findTop10ByOrderByLevelDesc();

Restituisce 10 righe con il livello più alto.

IMPORTANTE: poiché mi è stato detto che è facile perdere il punto chiave di questa risposta, ecco un piccolo chiarimento:

findAllByOrderByIdAsc(); // don't miss "by"
       ^

4
Per la vostra firma del metodo per funzionare come previsto con la Primavera dei dati JPA, è necessario includere il "tutto" parola chiave, in questo modo: List<StudentEntity> findAllByOrderByIdAsc();. Anche aggiungere un tipo restituito e rimuovere il modificatore pubblico ridondante è una buona idea;)
Håvard Geithus

1
Sono d'accordo che il pubblico è ridondante, ma mantiene le cose chiare nel caso in cui qualcun altro debba lavorare sul tuo codice. Non si sa mai chi sarà: PI non ha cambiato nient'altro che il nome del metodo nel codice degli autori perché non è dove si trovava il problema e se qualcuno non sa cosa dovrebbe essere lì, speriamo che imparino qualcosa di nuovo. Inoltre, è nel mio esempio di seguito, quindi non dovrebbero cercare dio sa dove, ma se insisti, allora sia così :) Aggiunta la parola chiave "all". Grazie.
Sikor,

73
Nota che il poco Byprima della OrderByparola chiave fa la differenza.
Stefan Haberl,

5
Ancora non capisco perché è necessario aggiungere un extra Byin primo piano OrderBy. La documentazione non ne parla .
Xtreme Biker,

3
@XtremeBiker Dal link della documentazione fornito: "Tuttavia, il primo By funge da delimitatore per indicare l'inizio dei criteri effettivi." Inoltre, se scorri verso il basso fino alla sezione "3.4.5. Limitazione dei risultati della query", in realtà esiste un esempio come questo, ma non viene spiegato.
Sikor,

54

AFAIK, non credo sia possibile con una query di denominazione del metodo diretta. È tuttavia possibile utilizzare il meccanismo di ordinamento incorporato, utilizzando la Sortclasse. Il repository ha un findAll(Sort)metodo su cui è possibile passare un'istanza Sorta. Per esempio:

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

Questo è davvero possibile usando findAllByOrderByIdAsc () come menzionato nella risposta di Sikor di seguito ... @Prashant che dovrebbe davvero essere la risposta corretta
Samuel Parsonage,

Modo alternativo di eseguire l'ordinamento nel livello di servizio se si desidera mantenere meno ingombranti i repository. Tuttavia, tieni presente la dimensione del risultato!
dkanejs,

2
Il metodo findAll()nel tipo CrudRepository<>non è applicabile per gli argomenti (Ordina)
Thiago Pereira,

5
@ThiagoPereira dovresti estendere JpaRepository<>se desideri utilizzare l'esempio sopra.
Waleed Abdalmajeed,

15

Dai un'occhiata all'APP sui dati di primavera - Documentazione di riferimento, sezione 5.3. Metodi di query , in particolare alla sezione 5.3.2. Creazione di query , in " Tabella 3. Parole chiave supportate all'interno dei nomi dei metodi " (collegamenti dal 03-05-2019).

Penso che abbia esattamente ciò di cui hai bisogno e la stessa query che hai dichiarato dovrebbe funzionare ...


1
Il tuo link non funziona -> Presumo che tu volessi puntare su questo link: docs.spring.io/spring-data/jpa/docs/current/reference/html/…
Jørgen Skår Fischer


3

Sì, puoi ordinare utilizzando il metodo di query in Spring Data.

Es: ordine crescente o decrescente utilizzando il valore del campo ID.

Codice:

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

soluzione 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"));
}
}

Ordinamento dei dati di primavera: ordinamento


3

In questo esempio provo a mostrarti un esempio completo per personalizzare i tuoi ordini

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

userete questo esempio: un metodo per costruire dinamicamente un oggetto quell'istanza di 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);
        }
}

0

Combinando tutte le risposte sopra, puoi scrivere codice riutilizzabile con 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();
  }
}

Il sovraccarico di oggetti DAO trova il metodo - in pratica, utilizza ancora findAll()

public interface StudentDAO extends CrudRepository<StudentEntity, Long> {

  Iterable<StudentEntity> findAll(Sort sort);

}

StudentEntitysi estende BaseEntityche contiene campi ripetibili (forse si desidera ordinare anche per ID)

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

  String firstName;
  String surname;

}

Infine, il servizio e l'utilizzo dei SORT_BY_CREATED_AT_DESCquali probabilmente verranno utilizzati non solo in StudentService.

@Service
class StudentService {

  @Autowired
  StudentDAO studentDao;

  Iterable<StudentEntity> findStudents() {
    return this.studentDao.findAll(SORT_BY_CREATED_AT_DESC);
  }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.