Pagination, tri et projections
Renvoyez des résultats paginés avec Pageable, triez dynamiquement et utilisez des projections d’interface pour limiter les colonnes récupérées.
Pagination, tri et projections est une leçon Java Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Java Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Java Academy comprend 4 leçons au total.
Pourquoi utiliser la pagination ?
Renvoyer des milliers de lignes en une seule requête gaspille de la mémoire et de la bande passante. La pagination charge une page à la fois. Spring Data intègre la pagination grâce à l’abstraction Pageable.
Pageable et PageRequest
Créez un Pageable avec PageRequest.of(page, size). Transmettez-le à toute méthode de dépôt qui renvoie Page<T>.
Pageable pageable = PageRequest.of(0, 20); // page 0, 20 per page
Page<User> page = userRepo.findAll(pageable);
System.out.println("Total: " + page.getTotalElements());
System.out.println("Pages: " + page.getTotalPages());
System.out.println("Content: " + page.getContent().size());Trier avec PageRequest
Ajoutez un tri à PageRequest avec un objet Sort. Chaînez plusieurs champs avec Sort.by().and().
Pageable sorted = PageRequest.of(0, 20,
Sort.by(Sort.Direction.DESC, "createdAt")
.and(Sort.by("name")));
Page<User> page = userRepo.findAll(sorted);Slice contre Page
Page<T> déclenche une requête COUNT pour calculer le nombre total de pages. Slice<T> ne le fait pas : il sait seulement s’il existe une page suivante. Utilisez Slice pour le défilement infini lorsque le nombre total n’est pas nécessaire.
public interface UserRepository extends JpaRepository<User, Long> {
Slice<User> findByStatus(UserStatus status, Pageable pageable);
}Intégration avec Spring MVC
Spring MVC résout automatiquement Pageable à partir des paramètres de requête : ?page=0&size=20&sort=name,asc. Aucun analyse manuelle n’est nécessaire.
@GetMapping("/users")
public Page<UserDto> list(Pageable pageable) {
return userRepo.findAll(pageable).map(UserDto::from);
}
// GET /users?page=0&size=10&sort=name,ascProjections par interface
Définissez une interface dont les méthodes d’accès correspondent aux noms des champs de l’entité. Spring Data ne renvoie que ces colonnes, ce qui réduit le transfert de données et masque les détails internes.
public interface UserSummary {
Long getId();
String getName();
String getEmail();
}
List<UserSummary> findByStatus(UserStatus status);Projections basées sur une classe (DTO)
Utilisez un enregistrement DTO ou une classe dotée d’un constructeur. Spring Data génère une expression de constructeur JPQL pour les colonnes sélectionnées.
public record UserDto(Long id, String name, String email) {}
@Query("SELECT new com.example.UserDto(u.id, u.name, u.email) FROM User u WHERE u.status = :s")
List<UserDto> findSummaries(@Param("s") UserStatus status);Projections dynamiques
Transmettez le type de projection comme paramètre générique à la méthode du dépôt afin de choisir la projection au point d’appel.
public interface UserRepository extends JpaRepository<User, Long> {
<T> List<T> findByStatus(UserStatus status, Class<T> type);
}
// Usage:
List<UserSummary> summaries = repo.findByStatus(ACTIVE, UserSummary.class);
List<User> full = repo.findByStatus(ACTIVE, User.class);Pagination par clé (offset contre clé)
La pagination par offset (OFFSET N) devient moins performante lorsque les offsets sont élevés. La pagination par clé (avec WHERE id > lastSeenId) est en O(1), quelle que soit la profondeur de la page, et convient mieux aux paginations profondes.
// Keyset pagination:
@Query("SELECT u FROM User u WHERE u.id > :lastId ORDER BY u.id LIMIT :size")
List<User> findPage(@Param("lastId") Long lastId, @Param("size") int size);Optimisation du nombre total
Utilisez countQuery dans @Query pour fournir une requête de comptage optimisée qui évite les JOIN coûteux de la requête principale.
@Query(value = "SELECT u FROM User u JOIN FETCH u.orders WHERE u.status = :s",
countQuery = "SELECT COUNT(u) FROM User u WHERE u.status = :s")
Page<User> findActiveWithOrders(@Param("s") UserStatus s, Pageable p);Renvoyer ResponseEntity avec les métadonnées de page
Incluez les métadonnées de page (totalElements, totalPages, numéro, taille) dans la réponse REST afin que les clients sachent comment naviguer.
@GetMapping("/users")
public ResponseEntity<Map<String, Object>> list(Pageable p) {
Page<UserDto> page = repo.findAll(p).map(UserDto::from);
return ResponseEntity.ok(Map.of(
"content", page.getContent(),
"totalElements", page.getTotalElements(),
"totalPages", page.getTotalPages()
));
}Vérification rapide
Quelle est la différence essentielle entre Page et Slice ?
Récapitulatif
Utilisez Pageable+PageRequest.of() pour la pagination par offset. Spring MVC résout Pageable à partir des paramètres de requête. Utilisez Slice pour éviter COUNT. Utilisez des projections par interface ou DTO pour limiter les colonnes chargées. Utilisez la pagination par clé pour les offsets élevés.
Questions Fréquemment Posées
La leçon « Pagination, tri et projections » est-elle gratuite ?
Oui — le texte complet de « Pagination, tri et projections » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Java Academy, passe à CoddyKit PRO. Le cours Java Academy comprend 4 leçons au total.
Qu'est-ce que j'apprendrai dans « Pagination, tri et projections » ?
Renvoyez des résultats paginés avec Pageable, triez dynamiquement et utilisez des projections d’interface pour limiter les colonnes récupérées. Tu pratiques Java Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.
Dois-je avoir de l'expérience pour commencer Java Academy ?
Aucune expérience préalable n'est requise. Java Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.
Combien de temps prend la leçon « Pagination, tri et projections » ?
La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.
Peux-tu écrire et exécuter du code dans cette leçon Java Academy ?
Oui. Chaque leçon Java Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.
Toutes les leçons de ce cours
- Mappage des entités avec les annotations JPA
- Référentiels Spring Data et méthodes de requête
- Relations One-to-Many et Many-to-Many
- Pagination, tri et projections