본문 바로가기
혼자서 개발새발

JPA ) QueryDsl , Pageble 을 이용해 페이징을 하다!

by 휴일이 2023. 1. 4.

 

나중에 나중에 하면서 미루던 작업이 있었드....

그것은 바로 페이징 ㅠ,ㅠ

드디어 오늘......!! 바로 이 시간....!!

나머지 파트 페이징도 끝낼 수 있었다 ㅠㅠ

(어드민용은 또 새로 만들어야하긴 하지마는...)

 

 

 

오쨌든 ^0^ /

페이징을 구현했던 과정을 써보쟈

(간단하게 본인 

 

 

 

 

1) 첫페이지를 1페이지로 만들기, 페이지 사이즈 지정

Pageble의 페이지 인덱스는 0부터 시작해서, 0 == 1페이지로 지정해주고

페이지 기본 사이즈를 정해쥰다

 

@Bean
public PageableHandlerMethodArgumentResolverCustomizer customize() {
    return p -> {
        p.setOneIndexedParameters(true);   // 1부터 시작
        p.setMaxPageSize(10);           // size=10
    };
}

 

 

 

2) 엔티티에서 보여주고 싶은 필드만 따로 떼서 Dto 클래스를 만든다

엔티티 내부도 숨길 수 있고 + 엔티티에 직접 의존하지 않아도 돼서 변경에 유리하다! ^0^

 

@Data
public class MarketDto {

    private Long marketId;
    private String title;
    private String content;
    private MarketStatus status;
    private String nickname;
    private String name;
    private Integer price;
    private Integer quantity;
    
}

 

 

3) Dto를 참조(?)해서 select 하기 위해 select 할 필드들을 생성자로 주입받고,

이 생성자를 이용해 dto로 값을 받겠다는 뜻을 가진

@QueryProjection 애노테이션을 붙여준다

- !!반드시!! select할 필드들을 전부 생성자로 넣어줘야 한다ㅎㅎ(이름은 달라도 되긴 하지만 되도록 같게!)

 

    @QueryProjection
    public MarketDto(Long marketId, String title, String content, MarketStatus status, String nickname, String name, Integer price, Integer quantity) {
        this.marketId = marketId;
        this.title = title;
        this.content = content;
        this.status = status;
        this.nickname = nickname;
        this.name = name;
        this.price = price;
        this.quantity = quantity;
    }

 

 

 

4) 리포지토리를 만든다

 

 

나는 페이징 하는 쿼리가 있는 코드가 중복 코드여서 메소드를 따로 떼어놨다

페이징에 필요한 Pageble과 조건을 가져오는 BooleanBulider를 매개변수로 받았다~

 

private Page<MarketDto> getOrderList(Pageable pageable, BooleanBuilder builder) {

    Long total = query.select(market.count())
            .from(market)
            .fetchOne();

    List<MarketDto> resultList = query.select(Projections.constructor(MarketDto.class,
                    market.id, market.title, market.content, market.status,
                    market.member.nickname, market.md.name, market.md.price, market.md.quantity))
            .from(market)
            .where(builder)
            .offset(pageable.getOffset())
            .limit(pageable.getPageSize())
            .fetch();

    return new PageImpl<>(resultList, pageable, total);
}

 

1- 불러올 엔티티의 토탈카운트를 구함

2- 불러올 필드들을 디티오로 받고, where에 조건 넣고 최소페이지와 페이지사이즈를 넣음

3- fetch()로 닫음(페치조인 메소드 따로 안 불러와도 됨)

4- PageImple 객체를 생성하고 *리스트, 페이저블, 토탈카운트* 순으로 넣는다~

 

public Page<MarketDto> findAllForUser(Pageable pageable) {
    BooleanBuilder builder = new BooleanBuilder();
    builder.and(market.marketRemover.isNull());

    return getOrderList(pageable, builder);
}

 

핵심 메소드~

만든 getOrderList 메소드에 페이저블과 빌더를 넣어서 리턴했다

 

 

 

5) 서비스

 

@Override
public Page<MarketDto> readList(Pageable pageable) {
    return marketRepository.findAllForUser(pageable);
}

 

 

 

6) 컨트롤러

기본 리스트를 반환하는 거라면, 페이저블 객체만 매개변수로 받는다

 

@GetMapping 
public Page<MarketDto> list(Pageable pageable) {
    return marketService.readList(pageable);
}

 

 

 

 

결과

 

 

기본 page를 안 주면 기본 1페이지 부터 시작한다

 

 

 

 

쿼리스트링으로 page=2 를 주면

2페이지로 슝슝

728x90