main.html
<button onclick="location.href='/menu/list?page=3&sort=menuCode,desc'">
메뉴 전체 목록 보기(3페이지 부터)
</button>
Pageable 자동 바인딩컨트롤러
@GetMapping("/list")
public String findMenuList(@PageableDefault Pageable pageable, Model model)
스프링이 쿼리스트링 ?page=...&size=...&sort=...를 보고 Pageable을 만들어 넘겨준다.
기본은 0-based page index

@PageableDefault에 size/sort를 지정하지 않았으므로, 현재는 프레임워크 기본값 이 적용
@PageableDefault

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface PageableDefault {
// 기본 1페이지부터(0부터 인덱스)
@AliasFor("size")
int value() **default 10;**
@AliasFor("value")
int size() default 10;
**int page() default 0;**
String[] sort() default {};
// 기본 오름차순
**Direction direction() default Direction.ASC;**
}
반환타입 Page
**Page**<MenuDTO> menuList = menuService.findMenuList(pageable);

정렬 파라미터 형식
정렬 속성은 엔티티 필드명 기준(menuCode)
쿼리스트링을 쓰는 경우?
?sort=menuCode,desc

다중 정렬: ?sort=menuPrice,desc&sort=menuName,asc
PageRequest로 최종 Pageable 확정 public Page<MenuDTO> findMenuList(**Pageable pageable)**{
**pageable = PageRequest.of(
pageable.getPageNumber() <= 0 ? 0 : pageable.getPageNumber() - 1, // 1→0 보정
pageable.getPageSize(),
Sort.by("menuCode").descending());**
Page<Menu> menuList = menuRepository.findAll(pageable);
/* 설명. Page 자체로 stream이다. */
return menuList
.map(menu -> modelMapper.map(menu, MenuDTO.class));
}
넘어온 Pageable 객체를 커스텀마이징
page값이 넘어오면 인덱스 개념으로 바꾼다. -> 프론트에서 페이지 변화가 그대로 넘어왔다는 가정
한 페이지에 뿌릴 사이즈는 유지
정렬 기준을 내림차순으로 변경 (게시글은 최신순으로 올라와야 한다.)
반환형이 sort라 . 으로 정렬을 계속 할 수 있다.

Page 자체로 stream으로 반환
findAll(Pageable) → Page<Menu>MenuRepository 인터페이스
// 서비스에서 레포로 findAll(pageable)
Page<Menu> menuList = menuRepository.**findAll(pageable);**
// 인터페이스는 콩이 될 수 없다
// JpaRepository를 상속받음으로써 스프링이 하위구현체 객체를 만들어서 콩으로 만들어준다.
**public interface MenuRepository
extends JpaRepository<Menu, Integer>** {
// 제네릭안에 객체타입과 pk타입을 넣어준다.
}
인터페이스는 bean이 될 수 없다.
JpaRepository를 상속받아 스프링이 하위구현체 객체를 만들어 bean으로 만들어 준다.
JpaRepository**<Menu, Integer>**
JpaRepository<T, ID>의 제네릭 두 자리는
MenuInteger, Long, String또는 복합키 클래스(@Embeddable/@IdClass)스프링 데이터 JPA가 findAll메서드를 실행해 Page를 만든다.
Page는 내용 + 전체 개수/페이지 수 메타를 모두 가진 완성형 페이지 객체Page → DTO로 변환: Page#map(...)