내부에서 limit 쿼리가 작동안하는 문제(게시글 기본 조회 문제처럼메모리로 데이터를 끌고 와서 limit을 시키는) 문제 querydsl 두 번 조회로 없앰
정렬 관련된 enum에서 cursor를 가져오고, 정렬문을 만들고, 쿼리문을 만드는 로직을 각각 구분하여 사용할 수 있게 만듬
전체 과정으로 리팩토링하고 데이터 정상적으로 받아온 것을 확인
커서기반 페이지네이션 적용
-> 새롭게 적용한 방식에 대해 피드백을 받아보고 싶습니다.
24.05.22 update
기존 FolderBoardSortType 열거형에서 cursor에 따른 BooleanBuilder, 실제 쿼리문 클래스를 매핑하는 방식 적용
정렬 방식에 따라 cursor와 쿼리문이 모두 달라지는 부분에서 이렇게 작성
그러나 FolderBoardSortType의 책임 범위가 크다는 피드백을 받음
cursor에 따른 ordering 순서는 CursorGeneratorMapping에 책임을 이양, query문은 QueryGeneratorMapping에 책임을 이양
-> spring의 HandlerMapping이 api경로에 따라 컨트롤러, 메서드를 mapping 해주는 것에서 참고
CursorGeneratorMapping, QueryGeneratorMapping 이 각각 Generator 생성에 필요한 멤버 변수를 모두 가지고 생산하는 방식으로 변경
기존에는 Generator 인터페이스 메서드에 cursor, query 생성에 필요한 모든 정보를 매개변수로 넘겨 WishListRecentCursorGenerator에서만 사용하는 memberId를 모든 Generator에서 받아서 사용했어야 했다.
// 구현체 중 memberId를 사용하는 곳은 WishListRecentCursorGenerator 뿐이다
public interface CursorGenerator {
BooleanBuilder getCursor(Long cursorId, memberId);
}
CursorGenerator의 구현체에 사용되는 모든 정보를 CursorGeneratorMapping의 멤버 변수로 넣고 각각 구현체에도 그 구현체에만 필요한 변수의 경우 생성자로 넣는 방식으로 변경
//이전
@RequiredArgsConstructor
public class WishListRecentCursorGenerator implements CursorGenerator{
private static final QWishListBoard wishListBoard = QWishListBoard.wishListBoard;
private final JPAQueryFactory queryFactory;
private final Long memberId;
@Override
public BooleanBuilder getCursor(Long cursorId, Long memberId) {
BooleanBuilder cursorBuilder = new BooleanBuilder();
...
}
}
//현재
@RequiredArgsConstructor
public class WishListRecentCursorGenerator implements CursorGenerator{
private static final QWishListBoard wishListBoard = QWishListBoard.wishListBoard;
private final JPAQueryFactory queryFactory;
private final Long memberId;
@Override
public BooleanBuilder getCursor(Long cursorId) {
BooleanBuilder cursorBuilder = new BooleanBuilder();
...
}
}
- CursorGenerator의 매개변수도 그 메서드 내에서 공통적으로 꼭 사용하는 것만 받을 수 있게 변경됨
```java
public interface CursorGenerator {
BooleanBuilder getCursor(Long cursorId);
// 필수 요소인 cursorId만을 가지고 구현체에 따라 사용하기도 하고 안하기도 하는 memberId는 구현체에 따라 멤버 변수에 넣는 방식으로 변경
}
BoardResponseDao 생성 및 이용
기존 Board 를 양방향 매핑으로 정보를 가져와 BoardResponse로 바꾸는 방식 사용
불필요한 정보도 가져오고 양방향 매핑이라는 변수가 많은 기술을 사용하는 것을 변경하고자 함
태그 정보도 가공하기 쉽게 만들기 위해 TagDao를 따로 만들어 사용
public record BoardResponseDao(
Long boardId,
Long storeId,
String storeName,
String thumbnail,
String title,
Integer price,
Category category,
TagsDao tagsDao
) { }
public record TagsDao (
boolean glutenFreeTag,
boolean highProteinTag,
boolean sugarFreeTag,
boolean veganTag,
boolean ketogenicTag
){}
product를 기준으로 N:1관계인 board와 store을 join 하다 보니 하나의 board에 여러 product가 있는 경우 중복하여 조회하게 되고 board와 store 데이터에 대한 중복 제거 과정 필요
History
🚀 Major Changes & Explanations
-> 최신 담은 순, 인기순, 낮은 가격순으로 정상적으로 조회하는 것을 확인
-> 새롭게 적용한 방식에 대해 피드백을 받아보고 싶습니다.
24.05.22 update
FolderBoardSortType
열거형에서 cursor에 따른 BooleanBuilder, 실제 쿼리문 클래스를 매핑하는 방식 적용FolderBoardSortType
의 책임 범위가 크다는 피드백을 받음cursor에 따른 ordering 순서는
CursorGeneratorMapping
에 책임을 이양, query문은QueryGeneratorMapping
에 책임을 이양 -> spring의HandlerMapping
이 api경로에 따라 컨트롤러, 메서드를 mapping 해주는 것에서 참고CursorGenerator의 구현체에 사용되는 모든 정보를 CursorGeneratorMapping의 멤버 변수로 넣고 각각 구현체에도 그 구현체에만 필요한 변수의 경우 생성자로 넣는 방식으로 변경
}
//현재 @RequiredArgsConstructor public class WishListRecentCursorGenerator implements CursorGenerator{
}
📷 Test Image
💡 ETC