PageImpl같은거 만들라하는데 잘모르겠어서 그냥 UserInsuranceSearchDto를 만들어서 검색 결과인 contents랑 검색 결과의 총 개수를 나타내는 count를 필드로 만들었다.
@Data
public class UserInsuranceSearchDto {
private List<UserInsurance> content;
private long count;
}
그리고 정렬은 어차피 보험 가입 날짜를 기준으로 내림차순 정렬하고, 보험 가입 날짜가 같은 경우에는 id를 기준으로 오름차순 정렬했다. 그래서 Controller에서는 pageNo만 @RequestParam을 통해 받았다.
@ModelAttribute InsuranceSearch insuranceSearch는 동적 쿼리를 위한 검색 조건들을 입력하기 위한 것이다.
count는 html에서 페이지 버튼 수를 계산하기 위해 사용된다.
@GetMapping("/insurance/admin/compensation/requests")
public String compensationRequests(@RequestParam(required = false, defaultValue = "0", value = "page") int pageNo,
@ModelAttribute InsuranceSearch insuranceSearch, HttpSession session, Model model) throws AccessDeniedException {
if (!checkRole(session)) {
return "error/403";
}
UserInsuranceSearchDto results = userInsuranceService.findAllUserInsurances(insuranceSearch, pageNo);
List<UserInsurance> userInsurances = results.getContent();
long count = results.getCount();
int totalPages = (int) Math.ceil((double) count / (double) 5);
model.addAttribute("userInsurances", userInsurances);
model.addAttribute("count", count);
model.addAttribute("pageNo", pageNo);
model.addAttribute("totalPages", totalPages);
return "admin/userInsuranceListForAdmin";
}
Controller가 호출한 UserInsuranceService에서는 검색 조건인 insuranceSearch, 페이징을 위한 pageNo를 받아 검색한다. insuranceSearch에 저장되어 있는 모든 검색 조건들을 꺼내서 userInsuranceRepository에 넘기며 검색한다.
검색한 이후에는 userInsuranceSearchDto에 검색 결과와 총 검색 결과 수를 가져와서 저장하고 리턴한다.
public UserInsuranceSearchDto findAllUserInsurances(InsuranceSearch insuranceSearch, int pageNo) {
Pageable pageable = PageRequest.of(pageNo, 5);
CompensationStatus compensationStatus = insuranceSearch.getCompensationStatus();
String insuranceName = insuranceSearch.getInsuranceName();
String username = insuranceSearch.getUsername();
CompensationOption option = insuranceSearch.getCompensationOption();
List<UserInsurance> contents = userInsuranceRepository.findAllUserInsurances(username, insuranceName, compensationStatus, option, pageable);
long count = userInsuranceRepository.countUserInsurances(username, insuranceName, compensationStatus, option);
UserInsuranceSearchDto userInsuranceSearchDto = new UserInsuranceSearchDto();
userInsuranceSearchDto.setContent(contents);
userInsuranceSearchDto.setCount(count);
return userInsuranceSearchDto;
}
Service가 호출한 UserInsuranceRepository에서는 Querydsl을 이용해서 동적 쿼리와 페이징을 진행한다.
각 조건은 BooleanExpression을 사용하여 조건문을 작성한다.
public List<UserInsurance> findAllUserInsurances(String usernameCond, String insuranceNameCond, CompensationStatus statusCond, CompensationOption optionCond, Pageable pageable) {
JPAQueryFactory queryFactory = new JPAQueryFactory(em);
List<UserInsurance> result = queryFactory
.selectFrom(userInsurance)
.join(userInsurance.insurance, insurance)
.join(userInsurance.user, user)
.where(
usernameEq(usernameCond),
insuranceNameEq(insuranceNameCond),
compensationOptionEq(optionCond),
compensationStatusEq(statusCond)
)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(userInsurance.registerDate.desc(), userInsurance.id.asc())
.fetch();
return result;
}
public long countUserInsurances(String usernameCond, String insuranceNameCond, CompensationStatus statusCond, CompensationOption optionCond) {
JPAQueryFactory queryFactory = new JPAQueryFactory(em);
return queryFactory
.select(userInsurance.count())
.from(userInsurance)
.where(
usernameEq(usernameCond),
insuranceNameEq(insuranceNameCond),
compensationOptionEq(optionCond),
compensationStatusEq(statusCond)
)
.fetchOne();
}
private BooleanExpression usernameEq(String usernameCond) {
if(usernameCond == null || usernameCond.isEmpty()) {
return null;
}
return user.username.eq(usernameCond);
}
private BooleanExpression insuranceNameEq(String insuranceNameCond) {
if(insuranceNameCond == null || insuranceNameCond.isEmpty()) {
return null;
}
return insurance.name.eq(insuranceNameCond);
}
private BooleanExpression compensationOptionEq(CompensationOption compensationOptionCond) {
return compensationOptionCond != null ? userInsurance.compensationOption.eq(compensationOptionCond) : null;
}
private BooleanExpression compensationStatusEq(CompensationStatus statusCond) {
return statusCond != null ? userInsurance.compensationStatus.eq(statusCond) : null;
}
실행 결과
728x90
'Spring' 카테고리의 다른 글
로딩 페이지 (ajax 이용)과 Validation 적용하기 (2) | 2024.08.29 |
---|---|
[JPA 활용 2편] API 개발 고급 - 실무 필수 최적화 (0) | 2024.07.08 |
[JPA 활용 2편] API 개발 고급 - 컬렉션 조회 최적화 (1) | 2024.07.05 |
[JPA 활용 2편] API 개발 고급 - 지연 로딩과 조회 성능 최적화 (0) | 2024.07.03 |
[JPA 활용 2편] API 개발 기본 (0) | 2024.07.02 |