Comment utiliser OrderBy avec findAll dans Spring Data


291

J'utilise des données de printemps et mon DAO ressemble

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

Dans le code ci-dessus, la ligne commentée montre mon intention. Spring data peut-il fournir des fonctionnalités intégrées pour utiliser une telle méthode pour trouver tous les enregistrements par ordre de colonne avec ASC / DESC?

Réponses:


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

Le code ci-dessus devrait fonctionner. J'utilise quelque chose de similaire:

public List<Pilot> findTop10ByOrderByLevelDesc();

Il renvoie 10 lignes avec le niveau le plus élevé.

IMPORTANT: Comme on m'a dit qu'il était facile de passer à côté du point clé de cette réponse, voici une petite clarification:

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

4
Pour votre signature de la méthode de travail comme prévu avec le printemps de données JPA, vous devez inclure le « tout » mot - clé, comme suit: List<StudentEntity> findAllByOrderByIdAsc();. Ajouter un type de retour et supprimer le modificateur public redondant est également une bonne idée;)
Håvard Geithus

1
Je suis d'accord que le public est redondant, mais il garde les choses claires au cas où quelqu'un d'autre devrait travailler sur votre code. Vous ne savez jamais qui ce sera: PI n'a rien changé d'autre que le nom de la méthode dans le code des auteurs parce que ce n'est pas où le problème était et si quelqu'un ne sait pas ce qui devrait être là, j'espère qu'il apprendra quelque chose de nouveau. D'ailleurs, c'est dans mon exemple ci-dessous afin qu'ils n'aient pas à chercher Dieu sait où, mais si vous insistez, alors qu'il en soit ainsi :) Ajout du mot-clé 'all'. Merci.
Sikor

74
Notez que le peu Byavant le OrderBymot - clé fait toute la différence.
Stefan Haberl

5
Je ne comprends toujours pas pourquoi il est nécessaire d'ajouter un supplément Byà l'avant OrderBy. La documentation n'en parle pas .
Xtreme Biker

3
@XtremeBiker À partir du lien de documentation que vous avez fourni: "Cependant, le premier By agit comme délimiteur pour indiquer le début des critères réels." De plus, si vous faites défiler vers le bas jusqu'à la section "3.4.5. Limitation des résultats de requête", il existe en fait un exemple comme celui-ci, mais il n'est pas expliqué.
Sikor

55

AFAIK, je ne pense pas que ce soit possible avec une requête de nommage de méthode directe. Vous pouvez cependant utiliser le mécanisme de tri intégré, en utilisant la Sortclasse. Le référentiel a une findAll(Sort)méthode dont vous pouvez passer une instance Sortà. Par exemple:

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

C'est en effet possible en utilisant findAllByOrderByIdAsc () comme mentionné dans la réponse de Sikor ci-dessous ... @Prashant qui devrait vraiment être la bonne réponse
Samuel Parsonage

Autre moyen de faire le tri dans le niveau de service si vous souhaitez garder vos référentiels moins encombrés. Gardez à l'esprit la taille du résultat!
dkanejs

2
La méthode findAll()dans le type CrudRepository<>n'est pas applicable pour les arguments (Trier)
Thiago Pereira

5
@ThiagoPereira vous devez étendre JpaRepository<>si vous souhaitez utiliser l'exemple ci-dessus.
Waleed Abdalmajeed

15

Veuillez consulter Spring Data JPA - Reference Documentation, section 5.3. Méthodes de requête , en particulier à la section 5.3.2. Création de requête , dans " Tableau 3. Mots-clés pris en charge dans les noms de méthode " (liens à partir du 2019-05-03).

Je pense qu'il a exactement ce dont vous avez besoin et la même requête que vous avez déclaré devrait fonctionner ...


1
Votre lien ne fonctionne pas -> je suppose que vous vouliez pointer vers ce lien: docs.spring.io/spring-data/jpa/docs/current/reference/html/…
Jørgen Skår Fischer


3

Oui, vous pouvez trier à l'aide de la méthode de requête dans Spring Data.

Ex: ordre croissant ou ordre décroissant en utilisant la valeur du champ id.

Code:

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

solution alternative:

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

Tri des données de printemps: tri


3

J'essaie dans cet exemple de vous montrer un exemple complet pour personnaliser vos tris 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);
 }

vous utiliserez cet exemple: Une méthode pour construire dynamiquement un objet cette instance 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);
        }
}

0

En combinant toutes les réponses ci-dessus, vous pouvez écrire du code réutilisable avec 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();
  }
}

L'objet DAO surcharge la méthode findAll - en gros, utilise toujours findAll()

public interface StudentDAO extends CrudRepository<StudentEntity, Long> {

  Iterable<StudentEntity> findAll(Sort sort);

}

StudentEntityétend BaseEntityqui contient des champs répétables (peut-être que vous souhaitez également trier par ID)

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

  String firstName;
  String surname;

}

Enfin, le service et l'utilisation de celui- SORT_BY_CREATED_AT_DESCci seront probablement utilisés non seulement dans le StudentService.

@Service
class StudentService {

  @Autowired
  StudentDAO studentDao;

  Iterable<StudentEntity> findStudents() {
    return this.studentDao.findAll(SORT_BY_CREATED_AT_DESC);
  }
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.