0Pricing
Java Academy · Lezione

Paginazione, ordinamento e proiezioni

Restituisca risultati paginati con Pageable, applichi ordinamenti dinamici e utilizzi proiezioni tramite interfacce per limitare le colonne recuperate.

Paginazione, ordinamento e proiezioni è una lezione Java Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Java Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Java Academy include 4 lezioni in totale.

Perché utilizzare la paginazione?

Restituire migliaia di righe con una sola query spreca memoria e larghezza di banda. La paginazione carica una pagina alla volta. Spring Data integra la paginazione tramite l'astrazione Pageable.

Pageable e PageRequest

Crei un Pageable utilizzando PageRequest.of(page, size). Lo passi a qualsiasi metodo del repository che restituisca 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());

Ordinamento con PageRequest

Aggiunga l'ordinamento a PageRequest con un oggetto Sort. Combini più campi con 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 vs Page

Page<T> esegue una query COUNT per calcolare il numero totale di pagine. Slice<T> non lo fa: sa solo se esiste una pagina successiva. Utilizzi Slice per lo scorrimento infinito quando il conteggio totale non è necessario.

public interface UserRepository extends JpaRepository<User, Long> {
    Slice<User> findByStatus(UserStatus status, Pageable pageable);
}

Integrazione con Spring MVC

Spring MVC risolve automaticamente Pageable dai parametri della query: ?page=0&size=20&sort=name,asc. Non è necessario analizzarli manualmente.

@GetMapping("/users")
public Page<UserDto> list(Pageable pageable) {
    return userRepo.findAll(pageable).map(UserDto::from);
}
// GET /users?page=0&size=10&sort=name,asc

Proiezioni basate su interfacce

Definisca un'interfaccia con metodi getter che corrispondano ai nomi dei campi dell'entità. Spring Data restituisce solo quelle colonne, riducendo il trasferimento dei dati e nascondendo i dettagli interni.

public interface UserSummary {
    Long getId();
    String getName();
    String getEmail();
}
List<UserSummary> findByStatus(UserStatus status);

Proiezioni basate su classi (DTO)

Utilizzi un record o una classe DTO con un costruttore. Spring Data genera un'espressione costruttore JPQL per le colonne selezionate.

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

Proiezioni dinamiche

Passi il tipo della proiezione come parametro generico al metodo del repository, per scegliere la proiezione nel punto della chiamata.

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

Paginazione keyset (offset vs keyset)

La paginazione tramite offset (OFFSET N) peggiora con offset elevati. La paginazione keyset (utilizzando WHERE id > lastSeenId) è O(1) indipendentemente dalla profondità della pagina: è più adatta alla paginazione profonda.

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

Ottimizzazione del conteggio totale

Utilizzi countQuery in @Query per fornire una query di conteggio ottimizzata che eviti i JOIN costosi della query 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);

Restituzione di ResponseEntity con i metadati della pagina

Includa i metadati della pagina (totalElements, totalPages, number, size) nella risposta REST, così i client sapranno come spostarsi tra le pagine.

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

Verifica rapida

Qual è la differenza principale tra Page e Slice?

Riepilogo

Utilizzi Pageable+PageRequest.of() per la paginazione tramite offset. Spring MVC risolve Pageable dai parametri della query. Utilizzi Slice per evitare COUNT. Utilizzi proiezioni basate su interfacce o DTO per limitare le colonne recuperate. Scelga la paginazione keyset per offset elevati.

Domande Frequenti

La lezione «Paginazione, ordinamento e proiezioni» è gratuita?

Sì — il testo completo di «Paginazione, ordinamento e proiezioni» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Java Academy, passa a CoddyKit PRO. Il corso Java Academy include 4 lezioni in totale.

Cosa imparerò in «Paginazione, ordinamento e proiezioni»?

Restituisca risultati paginati con Pageable, applichi ordinamenti dinamici e utilizzi proiezioni tramite interfacce per limitare le colonne recuperate. Eserciti Java Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.

Ho bisogno di esperienza per iniziare Java Academy?

Non è richiesta alcuna esperienza precedente. Java Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.

Quanto tempo richiede la lezione «Paginazione, ordinamento e proiezioni»?

La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.

Posso scrivere ed eseguire codice in questa lezione Java Academy?

Sì. Ogni lezione Java Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.

Tutte le lezioni di questo corso

  1. Mappatura delle entità con le annotazioni JPA
  2. Repository Spring Data e metodi di query
  3. Relazioni uno-a-molti e molti-a-molti
  4. Paginazione, ordinamento e proiezioni
← Torna a Java Academy