백엔드/JPA&QueryDSL
QueryDsl로 페이징처리하기/QueryDsl로 동적 정렬/PageRequest 이용하기
첸첸
2023. 9. 13. 11:54
728x90
Pageable 인터페이스를 구현한 PageRequest를 사용하면 페이징 처리를 간단하게 할 수 있다.
1️⃣ 페이징 처리에 필요한 정보를 담고 있는 Class 생성
- 페이징 처리를 여러곳에서 하기 때문에 페이징 처리 정보를 담고 있는 클래스를 생성하여 해당 클래스를 상속 받아서 사용 할 수 있도록 한다.
- pageRequest의 page 인덱스, 크기, 정렬을 인자로 받는 메소드를 사용
public class Search {
private int page = 1;
private int size = 10;
private String[] sort = {};
public void setPage(int page) {
this.page = page <=0 ? 1 : page;
}
public void setSize(int size) {
int DEFAULT_SIZE = 10;
int MAX_SIZE = 50;
this.size = size > MAX_SIZE ? DEFAULT_SIZE : size;
}
public void setSort(String... sort) {
this.sort = sort;
}
public PageRequest of() {
//정렬 기준을 저장한다.
List<Sort.Order> orders = new ArrayList<>();
for (String s : this.sort) {
//조건에 따라 오름차순, 내림차순을 정해주면 된다.
orders.add(Sort.Order.desc(s));
}
return PageRequest.of(page-1, size, Sort.by(orders));
}
}
2️⃣ 검색 조건 정보를 담고 있는 class 생성
- id와 시작일, 종료일을 기준으로 검색을 하고 페이징 정보를 담고 있는 Search 클래스를 상속받았다.
@AllArgsConstructor
@Getter
public class SearchVO extends Search {
private String id;
private String startDate;
private String endDate;
}
3️⃣ QueryDsl 작성
3-1 return값을 담을 Page class 생성
@AllArgsConstructor
@Getter
public class Page<T> {
private int total; //총 갯수
private int count; //현재 페이지의 갯수
private List<T> data; //결과값
}
3-2 queryDsl 구문 작성
public Page<Response> search(SearchVO searchVO) {
//searchVO 에서 PageRequest를 가져온다.
Pageable pageable = searchVO.of();
//쿼리 작성
var query = queryFactory.select(Projections.constructor(Response.class,
entity.Id,
entity.name,
entity.actionDate,
.from(entity);
if (searchVO.getStartDate()!=null && !searchVO.getStartDate().isBlank() &&
searchVO.getEndDate()!=null && !searchVO.getEndDate().isBlank()) {
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
LocalDateTime start = LocalDateTime.parse(searchVO.getStartDate(), formatter);
LocalDateTime end = LocalDateTime.parse(searchVO.getEndDate(), formatter);
query.where(entity.actionDate.between(start,end));
}
//쿼리 실행 결과의 총 갯수를 가져온다.
int total = query.groupBy(qTbAcsClHistory.actionDate).fetch().size();
//페이징 처리의 결과값을 저장한다.
List<Response> list = query.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.orderBy(getOrderSpecifier(pageable.getSort()).stream().toArray(OrderSpecifier[]::new))
.fetch();
return new Page<>(total, list.size(), list);
}
//정렬기준 생성
public OrderSpecifier<?> getSortedColumn(Order order, Path<?> parent, String fieldName) {
Path<Object> fieldPath = Expressions.path(Object.class, parent, fieldName);
return new OrderSpecifier(order, fieldPath);
}
private static List<OrderSpecifier> getOrderSpecifier(Sort sort) {
List<OrderSpecifier> orders = new ArrayList<>();
sort.stream().forEach(order -> {
Order direction = order.isAscending() ? Order.ASC : Order.DESC;
String prop = order.getProperty();
orders.add(getSortedColumn(direction, Q타입클래스.엔티티, prop));
});
return orders;
}