Verwendung von OrderBy mit findAll in Spring Data


288

Ich verwende Federdaten und mein DAO sieht aus wie

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

Im obigen Code zeigt die kommentierte Zeile meine Absicht. Kann spring Data integrierte Funktionen bereitstellen, um mit einer solchen Methode alle Datensätze in einer Spalte mit ASC / DESC zu finden?

Antworten:


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

Der obige Code sollte funktionieren. Ich benutze etwas Ähnliches:

public List<Pilot> findTop10ByOrderByLevelDesc();

Es werden 10 Zeilen mit der höchsten Ebene zurückgegeben.

WICHTIG: Da mir gesagt wurde, dass es leicht ist, den Kernpunkt dieser Antwort zu übersehen, hier eine kleine Klarstellung:

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

4
Damit Ihre Methodensignatur wie beabsichtigt mit Spring Data JPA funktioniert, sollten Sie das Schlüsselwort "all" wie folgt einfügen : List<StudentEntity> findAllByOrderByIdAsc();. Das Hinzufügen eines Rückgabetyps und das Entfernen des redundanten öffentlichen Modifikators ist ebenfalls eine gute Idee;)
Håvard Geithus

1
Ich bin damit einverstanden, dass die Öffentlichkeit überflüssig ist, aber es hält die Dinge klar, falls jemand anderes an Ihrem Code arbeiten muss. Sie wissen nie, wer es sein wird: PI hat nichts anderes als den Methodennamen im Autorencode geändert, da hier nicht das Problem aufgetreten ist und wenn jemand nicht weiß, was dort sein soll, wird er hoffentlich etwas Neues lernen. Außerdem ist es in meinem Beispiel unten, damit sie nicht nach Gott weiß wo suchen müssen, aber wenn Sie darauf bestehen, dann sei es so :) Das Schlüsselwort 'all' wurde hinzugefügt. Vielen Dank.
Sikor

73
Beachten Sie, dass das kleine Byvor dem OrderBySchlüsselwort den Unterschied ausmacht.
Stefan Haberl

5
Ich verstehe immer noch nicht, warum es notwendig ist, Byvorne ein Extra hinzuzufügen OrderBy. Die Dokumentation sagt nichts darüber aus .
Xtreme Biker

3
@XtremeBiker Über den von Ihnen angegebenen Dokumentationslink: "Das erste By fungiert jedoch als Trennzeichen, um den Beginn der tatsächlichen Kriterien anzuzeigen." Wenn Sie zum Abschnitt "3.4.5. Einschränken der Abfrageergebnisse" scrollen, gibt es tatsächlich ein Beispiel wie dieses, das jedoch nicht erläutert wird.
Sikor

54

AFAIK, ich denke nicht, dass dies mit einer direkten Methodenbenennungsabfrage möglich ist. Sie können jedoch den integrierten Sortiermechanismus mithilfe der SortKlasse verwenden. Das Repository verfügt über eine findAll(Sort)Methode, an die Sie eine Instanz übergeben können Sort. Zum Beispiel:

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

Dies ist in der Tat mit findAllByOrderByIdAsc () möglich, wie in Sikors Antwort unten erwähnt ... @Prashant, das sollte wirklich die richtige Antwort sein
Samuel Parsonage

Alternative Methode zum Sortieren in der Serviceebene, wenn Sie Ihre Repositorys übersichtlicher gestalten möchten. Beachten Sie jedoch die Ergebnisgröße!
dkanejs

2
Die Methode findAll()im Typ CrudRepository<>ist nicht anwendbar für die Argumente (Sortieren)
Thiago Pereira

5
@ThiagoPereira sollten Sie erweitern, JpaRepository<>wenn Sie das obige Beispiel verwenden möchten.
Waleed Abdalmajeed



3

Ja, Sie können mithilfe der Abfragemethode in Spring Data sortieren.

Beispiel: aufsteigende oder absteigende Reihenfolge unter Verwendung des Werts des ID-Felds.

Code:

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

alternative Lösung:

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

Spring Data Sorting: Sortieren


3

Ich versuche in diesem Beispiel, Ihnen ein vollständiges Beispiel für die Personalisierung Ihrer OrderBy-Sortierungen zu zeigen

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

Sie werden dieses Beispiel verwenden: Eine Methode zum dynamischen Erstellen eines Objekts dieser Instanz von 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

Wenn Sie alle obigen Antworten kombinieren, können Sie mit BaseEntity wiederverwendbaren Code schreiben:

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

DAO-Objekt überlädt die findAll-Methode - wird im Grunde immer noch verwendet findAll()

public interface StudentDAO extends CrudRepository<StudentEntity, Long> {

  Iterable<StudentEntity> findAll(Sort sort);

}

StudentEntityerweitert, BaseEntitydas wiederholbare Felder enthält (möglicherweise möchten Sie auch nach ID sortieren)

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

  String firstName;
  String surname;

}

Schließlich wird der Service und die Nutzung SORT_BY_CREATED_AT_DESCdavon wahrscheinlich nicht nur in der StudentService.

@Service
class StudentService {

  @Autowired
  StudentDAO studentDao;

  Iterable<StudentEntity> findStudents() {
    return this.studentDao.findAll(SORT_BY_CREATED_AT_DESC);
  }
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.