@Service
public class UserService {
private final UserRepository userRepository;
public Page<User> findAll(Pageable pageable){
return userRepository.findAll(pageable);
}
}
2-3. 컨트롤러 (Controller) 단
2-3-1) Pageable
@PageableDefault 어노테이션 사용
size : 페이지 당 표시할 데이터 개수 (기본값 : 10)
page : 현재 페이지 (기본값 : 0)
sort : 정렬 기준
direction : 정렬 방향 (오름차순, 내림차순)
@GetMapping("")
public Page<User> findAll(@PageableDefault(size = 5, page = 1,
sort = "name", direction = Sort.Direction.DESC) {
return userService.findAll(pageable);
}
@Entity
@Getter @Setter
public class Player {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String team;
private Integer salary;
}
3-2. SearchForm (domain)
검색 폼을 위한 클래스
@Getter @Setter
public class SearchForm {
private String name; // 검색할 선수 이름
private Integer startSal; // 검색할 연봉 시작점
private Integer endSal; // 검색할 연봉 끝점
}
3-3. PlayerRepository (repository)
public interface PlayerRepository extends JpaRepository<Player, Long> {
// findPlayersBySalaryBetween : 기존의 findAll 과 동일하다고 생각 가능!
Page<Player> findPlayersBySalaryBetween(Integer startSal, Integer endSal, Pageable pageable);
// findPlayersByNameContainingAndSalaryBetween : 기존의 findByNameContaining 과 동일하다고 생각 가능!
Page<Player> findPlayersByNameContainingAndSalaryBetween(String name, Integer startSal, Integer endSal, Pageable pageable);
}
JpaRepository
find~By~Between(범위 시작점, 범위 끝점) : 범위의 시작 ~ 끝을 만족하는 데이터 반환
find~ByNameContaining(String name) : name을 "포함" 하는 데이터 반환
컨트롤러에서 연봉의 시작, 끝이 입력되지 않으면 다음과 같이 설정함
시작 : 0
끝 : 99999
따라서 연봉의 시작, 끝의 변수는 항상 값이 존재하게 됨
따라서 1) 아무것도 입력 받지 않은 경우 2) 이름만 입력 받은 경우 3) 연봉만 입력받은 경우 4) 모두 입력받은 경우가 아닌
1) 연봉만 값이 있는 경우 2) 이름과 연봉 모두 값이 있는 경우로 나눌 수 있음
1) 연봉만 값이 있는 경우 : 기존의 findAll 과 동일하게 생각
2) 이름과 연봉 모두 값이 있는 경우 : findByNameContaining 과 동일하게 생각
3-4. PlayerService (service)
@Service
@RequiredArgsConstructor
public class PlayerService {
private final PlayerRepository playerRepository;
// findAll : 모든 선수 찾기
public Page<Player> findAll(Integer startSal, Integer endSal, Pageable pageable){
return playerRepository.findPlayersBySalaryBetween(startSal, endSal, pageable);
}
// findPlayersByName : 이름으로 선수 찾기
public Page<Player> findPlayersByName(String name, Integer startSal, Integer endSal, Pageable pageable) {
return playerRepository.findPlayersByNameContainingAndSalaryBetween(name, startSal, endSal, pageable);
}
}
3-5. PlayerController (controller)
@Controller
@RequiredArgsConstructor
public class PlayerController {
private final PlayerService playerService;
@GetMapping("")
public String home(@RequestParam(required = false, defaultValue = "1") int page,
@ModelAttribute SearchForm searchForm,
Model model){
// 연봉 시작 조건이 빈 경우 : 0으로 설정
if(searchForm.getStartSal() == null) searchForm.setStartSal(0);
// 연봉 끝 조건이 빈 경우 : 99999로 설정
if(searchForm.getEndSal() == null) searchForm.setEndSal(99999);
// 연봉 시작 > 연봉 끝 (검색 조건 위반)
if(searchForm.getStartSal() > searchForm.getEndSal()){
model.addAttribute("errorMessage", "검색할 수 없는 범위 입니다.");
model.addAttribute("nextUrl", "/");
return "/error";
}
// PageRequest.of(페이지 번호, 페이지 당 5개씩 출력, 연봉 기준 내림차순)
PageRequest pageRequest = PageRequest.of(page-1, 5, Sort.by("salary").descending());
Page<Player> players;
if(searchForm.getName() == null){
// 이름이 빈 경우 : findAll 호출
players = playerService.findAll(searchForm.getStartSal(), searchForm.getEndSal(), pageRequest);
} else {
// 이름이 있는 경우 : findPlayersByName 호출
players = playerService.findPlayersByName(searchForm.getName(), searchForm.getStartSal(), searchForm.getEndSal(), pageRequest);
}
model.addAttribute("players", players);
model.addAttribute("searchForm", searchForm);
return "/home";
}
}
PlayerRepository 에서 언급한 대로 연봉 시작, 끝 변수가 항상 값이 있게끔 설정함으로써 검색 경우를 반으로 줄임