Careeroza
Page vs Slice
Two Return Types
Page<T> | Slice<T> | List<T> + Pageable | |
|---|---|---|---|
| Extra count query | yes | no | no |
| Knows total pages/elements | yes | no | no |
| Knows if a next page exists | yes | yes (fetches size + 1 rows) | no |
| Best for | admin tables with page numbers | infinite scroll, "Load more" | just the rows |
Slice<Product> findByCategoryName(String category, Pageable pageable); // no COUNT(*)How Slice Knows There Is More
Example
A Slice asks the database for one row more than the page size. If that extra row exists, there is a next page; the extra row is dropped.
import java.util.*;
import java.util.stream.*;
public class Main {
static final List<Integer> TABLE = IntStream.rangeClosed(1, 23).boxed().toList(); // 23 product ids
static int queries = 0;
static List<Integer> select(int offset, int limit) {
queries++;
return TABLE.subList(Math.min(offset, TABLE.size()), Math.min(offset + limit, TABLE.size()));
}
public static void main(String[] args) {
int size = 10;
System.out.println("Slice (limit size+1, no count):");
for (int page = 0; ; page++) {
List<Integer> rows = select(page * size, size + 1);
boolean hasNext = rows.size() > size;
List<Integer> content = rows.subList(0, Math.min(size, rows.size()));
System.out.println(" page " + page + " " + content + " hasNext=" + hasNext);
if (!hasNext) break;
}
System.out.println(" queries: " + queries);
queries = 0;
System.out.println("Page (data + count for every page):");
for (int page = 0; page < 3; page++) {
select(page * size, size);
queries++; // select count(*) ...
}
System.out.println(" queries: " + queries + ", totalPages=" + (TABLE.size() + size - 1) / size);
}
}Output
Slice (limit size+1, no count): page 0 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] hasNext=true page 1 [11, 12, 13, 14, 15, 16, 17, 18, 19, 20] hasNext=true page 2 [21, 22, 23] hasNext=false queries: 3 Page (data + count for every page): queries: 6, totalPages=3
Count Query Cost
Tip: On big tables with complex filters, count(*) can be slower than the data query itself. Spring Data skips the count when the first page already holds fewer rows than the page size. For mobile feeds, prefer Slice.