티스토리 뷰

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;
    }

 

 

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함