0. 현재 상황
미뤄왔던 QueryDSL을 도입해보려 한다.
도입해야할 시기라는 것을 가장 크게 느낀 것은 아래 쿼리메소드를 작성했을 때이다.
메소드의 이름만으로도 쿼리문을 자동으로 작성해주는 Spring Data JPA 의 기능이지만
단점으로는 저렇게 너무 길어지기도 한다.
알아보기가 어렵다.
QueryDSL는 동적쿼리를 생성하는 데에 있어서도 장점이 있지만,
한눈에 쿼리의 내용이 잘 파악이 되기도 하니 이를 기대해보며 개선해보려 한다.
1. QueryDsl 세팅
이전에 관련해서 설정을 마쳤기에 세팅관련한 자료는 아래 이전에 작성해뒀던 포스팅을 참고했다.
이전 포스팅 링크로 방법은 갈무리한다.
https://thiswooin.tistory.com/68
https://thiswooin.tistory.com/69
2. 리팩토링
기존코드
Page<Quiz> findByQuizUserDatas_UserAndQuizUserDatas_IsShowHintTrueAndQuizUserDatas_IsSolvedFalse(User user, Pageable pageable);
QueryDsl 적용 코드
public Page<Quiz> selectMyCheckedHintQuizzes(User user, Pageable pageable) {
QQuiz quiz = QQuiz.quiz;
QQuizUserData quizUserData = QQuizUserData.quizUserData;
List<Quiz> results = jpaQueryFactory
.select(quiz) // refactor select() 안에 Projection 객체를 넣어줄 수 있다
.from(quiz)
.join(quizUserData).on(quizUserData.quiz.eq(quiz))
.where(quizUserData.user.eq(user)
.and(quizUserData.isShowHint.isTrue())
.and(quizUserData.isSolved.isFalse())
)
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
Long count = jpaQueryFactory
.select(quiz.count())
.from(quiz)
.join(quizUserData).on(quizUserData.quiz.eq(quiz))
.where(quizUserData.user.eq(user)
.and(quizUserData.isShowHint.isTrue())
.and(quizUserData.isSolved.isFalse())
)
.fetchOne();
assert count != null;
return new PageImpl<>(results, pageable, count);
}
개선이라고 봐야할 지 헷갈릴 정도로 코드양이 늘었다.
Page객체를 반환해주기 위해 Count를 구하는 쿼리를 추가로 날려줬다.
fetchResult()를 통해 getTotal()하는 방식은 성능저하의 우려가 있다고 한다.
3. 느낀 점
쿼리를 파악하기 쉽다.
위의 장점을 기대한 것이기도 하다. 확실히 어떤 쿼리인지 파악하기도 쉽고,
처음 쿼리를 만들 때 오류를 발견하기도 쉽다는 것도 동의한다.
도전해볼 것
이번에는 다양한 조건으로 검색기능을 추가하며 이를 통한 동적쿼리 생성에 도전해볼까한다.
(진행중)
참고링크
'Projects > 푸하하 - 개인 프로젝트' 카테고리의 다른 글
Refactoring : 좋아요테이블을 기존 퀴즈-유저 정보 테이블에 합치기 (0) | 2024.01.03 |
---|---|
[트러블 슈팅] QueryDsl 도입후 테스트시 빈생성 문제 (0) | 2023.12.04 |
[리팩토링] 작은 깨달음 : 리팩토링을 하기엔 데이터 수가 너무도 적었다 (0) | 2023.11.28 |
[리팩토링] 레디스 캐싱을 통한 인증과정 유저정보 조회 속도 개선하기 (0) | 2023.11.28 |
[리팩토링] Redis 캐싱을 통한 조회 성능 개선 도전기 (0) | 2023.11.28 |