Skip to content

Commit fb0aeb0

Browse files
committed
paging examples
1 parent b3532e2 commit fb0aeb0

File tree

8 files changed

+153
-26
lines changed

8 files changed

+153
-26
lines changed

spring-boot/pagination/src/main/java/io/reflectoring/pagination/MovieCharacter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
import javax.persistence.Entity;
66
import javax.persistence.GeneratedValue;
77
import javax.persistence.Id;
8+
import javax.persistence.Table;
89

910
@Entity
1011
@Data
12+
@Table(name = "character")
1113
class MovieCharacter {
1214

1315
@Id

spring-boot/pagination/src/main/java/io/reflectoring/pagination/MovieCharacterRepository.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,29 @@
66
import org.springframework.data.domain.Pageable;
77
import org.springframework.data.domain.Slice;
88
import org.springframework.data.domain.Sort;
9+
import org.springframework.data.jpa.repository.Query;
910
import org.springframework.data.repository.CrudRepository;
11+
import org.springframework.data.repository.query.Param;
1012

11-
interface MovieCharacterRepository extends CrudRepository<MovieCharacter, Long> {
13+
interface MovieCharacterRepository
14+
extends CrudRepository<MovieCharacter, Long> {
1215

16+
@Query("select c from MovieCharacter c")
1317
Page<MovieCharacter> findAllPage(Pageable pageable);
1418

19+
@Query("select c from MovieCharacter c")
1520
Slice<MovieCharacter> findAllSlice(Pageable pageable);
1621

22+
@Query("select c from MovieCharacter c")
1723
List<MovieCharacter> findAllSorted(Sort sort);
1824

25+
Page<MovieCharacter> findByMovie(String movieName, Pageable pageable);
26+
27+
@Query("select c from MovieCharacter c where c.movie = :movie")
28+
Slice<MovieCharacter> findByMovieCustom(
29+
@Param("movie") String movieName, Pageable pageable);
30+
31+
@Query("select c from MovieCharacter c where c.movie = :movie")
32+
List<MovieCharacter> findByMovieSorted(
33+
@Param("movie") String movieName, Sort sort);
1934
}

spring-boot/pagination/src/main/java/io/reflectoring/pagination/PaginatedController.java

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,45 @@
33
import java.util.List;
44

55
import lombok.RequiredArgsConstructor;
6+
import org.springframework.beans.factory.annotation.Qualifier;
67
import org.springframework.data.domain.Page;
78
import org.springframework.data.domain.Pageable;
89
import org.springframework.data.domain.Slice;
910
import org.springframework.data.domain.Sort;
11+
import org.springframework.data.web.PageableDefault;
12+
import org.springframework.data.web.SortDefault;
1013
import org.springframework.web.bind.annotation.GetMapping;
1114
import org.springframework.web.bind.annotation.RestController;
1215

1316
@RestController
1417
@RequiredArgsConstructor
1518
class PaginatedController {
1619

17-
private final MovieCharacterRepository characterRepository;
20+
private final MovieCharacterRepository characterRepository;
1821

19-
@GetMapping(path = "/characters/page")
20-
Page<MovieCharacter> loadCharactersPage(Pageable pageable) {
21-
return characterRepository.findAllPage(pageable);
22-
}
22+
@GetMapping(path = "/characters/page")
23+
Page<MovieCharacter> loadCharactersPage(
24+
@PageableDefault(page = 0, size = 20)
25+
@SortDefault.SortDefaults({
26+
@SortDefault(sort = "name", direction = Sort.Direction.DESC),
27+
@SortDefault(sort = "id", direction = Sort.Direction.ASC)
28+
}) Pageable pageable) {
29+
return characterRepository.findAllPage(pageable);
30+
}
2331

24-
@GetMapping(path = "/characters/sorted")
25-
List<MovieCharacter> loadCharactersSorted(Sort sort) {
26-
return characterRepository.findAllSorted(sort);
27-
}
32+
@GetMapping(path = "/characters/qualifier")
33+
Page<MovieCharacter> loadCharactersPageWithQualifier(
34+
@Qualifier("my") Pageable pageable) {
35+
return characterRepository.findAllPage(pageable);
36+
}
2837

29-
@GetMapping(path = "/characters/slice")
30-
Slice<MovieCharacter> loadCharactersSlice(Pageable pageable) {
31-
return characterRepository.findAllSlice(pageable);
32-
}
38+
@GetMapping(path = "/characters/sorted")
39+
List<MovieCharacter> loadCharactersSorted(Sort sort) {
40+
return characterRepository.findAllSorted(sort);
41+
}
42+
43+
@GetMapping(path = "/characters/slice")
44+
Slice<MovieCharacter> loadCharactersSlice(Pageable pageable) {
45+
return characterRepository.findAllSlice(pageable);
46+
}
3347
}

spring-boot/pagination/src/main/java/io/reflectoring/pagination/PaginationApplication.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package io.reflectoring.pagination;
22

33
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
45
import org.springframework.boot.autoconfigure.SpringBootApplication;
6+
import org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration;
57

68
@SpringBootApplication
79
public class PaginationApplication {

spring-boot/pagination/src/main/java/io/reflectoring/pagination/PaginationConfiguration.java

Lines changed: 0 additions & 9 deletions
This file was deleted.

spring-boot/pagination/src/main/resources/application.properties

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,5 @@ spring.data.web.pageable.size-parameter=size
22
spring.data.web.pageable.page-parameter=page
33
spring.data.web.pageable.default-page-size=10
44
spring.data.web.pageable.one-indexed-parameters=false
5-
spring.data.web.pageable.max-page-size=10000
6-
spring.data.web.pageable.prefix=
5+
spring.data.web.pageable.prefix=2000
76
spring.data.web.pageable.qualifier-delimiter=_

spring-boot/pagination/src/test/java/io/reflectoring/pagination/PaginatedControllerTest.java

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ void evaluatesPageableParameter() throws Exception {
3636
mockMvc.perform(get("/characters/page")
3737
.param("page", "5")
3838
.param("size", "10")
39-
.param("sort", "id, desc") // <-- no space after comma!!!
39+
.param("sort", "id,desc") // <-- no space after comma!!!
4040
.param("sort", "name,asc")) // <-- no space after comma!!!
4141
.andExpect(status().isOk());
4242

@@ -50,6 +50,56 @@ void evaluatesPageableParameter() throws Exception {
5050
assertThat(pageable).hasSort("id", Sort.Direction.DESC);
5151
}
5252

53+
@Test
54+
void evaluatesQualifier() throws Exception {
55+
56+
mockMvc.perform(get("/characters/qualifier")
57+
.param("my_page", "5")
58+
.param("my_size", "10")
59+
.param("my_sort", "id,desc") // <-- no space after comma!!!
60+
.param("my_sort", "name,asc")) // <-- no space after comma!!!
61+
.andExpect(status().isOk());
62+
63+
ArgumentCaptor<Pageable> pageableCaptor = ArgumentCaptor.forClass(Pageable.class);
64+
verify(characterRepository).findAllPage(pageableCaptor.capture());
65+
PageRequest pageable = (PageRequest) pageableCaptor.getValue();
66+
67+
assertThat(pageable).hasPageNumber(5);
68+
assertThat(pageable).hasPageSize(10);
69+
assertThat(pageable).hasSort("name", Sort.Direction.ASC);
70+
assertThat(pageable).hasSort("id", Sort.Direction.DESC);
71+
}
72+
73+
@Test
74+
void setsUpperPageLimit() throws Exception {
75+
76+
mockMvc.perform(get("/characters/page")
77+
.param("size", "10000"))
78+
.andExpect(status().isOk());
79+
80+
ArgumentCaptor<Pageable> pageableCaptor = ArgumentCaptor.forClass(Pageable.class);
81+
verify(characterRepository).findAllPage(pageableCaptor.capture());
82+
PageRequest pageable = (PageRequest) pageableCaptor.getValue();
83+
84+
assertThat(pageable).hasPageSize(2000);
85+
}
86+
87+
@Test
88+
void evaluatesPageableDefault() throws Exception {
89+
90+
mockMvc.perform(get("/characters/page"))
91+
.andExpect(status().isOk());
92+
93+
ArgumentCaptor<Pageable> pageableCaptor = ArgumentCaptor.forClass(Pageable.class);
94+
verify(characterRepository).findAllPage(pageableCaptor.capture());
95+
PageRequest pageable = (PageRequest) pageableCaptor.getValue();
96+
97+
assertThat(pageable).hasPageNumber(0);
98+
assertThat(pageable).hasPageSize(20);
99+
assertThat(pageable).hasSort("name", Sort.Direction.DESC);
100+
assertThat(pageable).hasSort("id", Sort.Direction.ASC);
101+
}
102+
53103
@Test
54104
void returnsSlice() throws Exception {
55105

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package io.reflectoring.pagination;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.mockito.ArgumentCaptor;
5+
import org.springframework.beans.factory.annotation.Autowired;
6+
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
7+
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
8+
import org.springframework.boot.test.context.SpringBootTest;
9+
import org.springframework.boot.test.mock.mockito.MockBean;
10+
import org.springframework.data.domain.PageRequest;
11+
import org.springframework.data.domain.Pageable;
12+
import org.springframework.data.domain.Sort;
13+
import org.springframework.test.context.TestPropertySource;
14+
import org.springframework.test.web.servlet.MockMvc;
15+
import static io.reflectoring.pagination.PageableAssert.*;
16+
import static org.mockito.Mockito.*;
17+
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
18+
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
19+
20+
@WebMvcTest(controllers = PaginatedController.class)
21+
@TestPropertySource(properties = {
22+
"spring.data.web.pageable.prefix=prefix_",
23+
"spring.data.web.pageable.size-parameter=my-size",
24+
"spring.data.web.pageable.page-parameter=my-page"
25+
})
26+
class PaginatedControllerWithCustomPagingPropertiesTest {
27+
28+
@MockBean
29+
private MovieCharacterRepository characterRepository;
30+
31+
@Autowired
32+
private MockMvc mockMvc;
33+
34+
@Test
35+
void evaluatesPageableParameter() throws Exception {
36+
37+
mockMvc.perform(get("/characters/page")
38+
.param("prefix_my-page", "5")
39+
.param("prefix_my-size", "10")
40+
.param("sort", "id,desc") // <-- no space after comma!!!
41+
.param("sort", "name,asc")) // <-- no space after comma!!!
42+
.andExpect(status().isOk());
43+
44+
ArgumentCaptor<Pageable> pageableCaptor = ArgumentCaptor.forClass(Pageable.class);
45+
verify(characterRepository).findAllPage(pageableCaptor.capture());
46+
PageRequest pageable = (PageRequest) pageableCaptor.getValue();
47+
48+
assertThat(pageable).hasPageNumber(5);
49+
assertThat(pageable).hasPageSize(10);
50+
assertThat(pageable).hasSort("name", Sort.Direction.ASC);
51+
assertThat(pageable).hasSort("id", Sort.Direction.DESC);
52+
}
53+
54+
}

0 commit comments

Comments
 (0)