Notice
Recent Posts
Recent Comments
Link
«   2024/09   »
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
Archives
Today
Total
관리 메뉴

참새의 이야기

Querydsl 기본 세팅 본문

Spring

Querydsl 기본 세팅

참새짹짹! 2024. 2. 5. 19:59

뉴핏 프로젝트를 진행하기에 앞서 querydsl을 공부하고 있었지만 다른 팀원들이 querydsl에 대한 학습 경험이 없어서 일단은 querydsl을 사용하지 않고, Spring Data Jpa가 제공하는 쿼리 메서드와 @Query 어노테이션을 활용하여 repository 계층을 구성했다.

 

우리 서비스에서 필요한 repository의 메서드들을 어느 정도 구현하고 보니 쿼리를 자동 생성해 주는 쿼리 메서드는 괜찮았지만, @Query 어노테이션으로 직접 쿼리를 작성한 경우에는 가독성이 너무 안 좋다는 점이 아쉬웠다.

이때 querydsl을 도입하지 않을 수 없다는 생각이 들었고, 팀원들에게 querydsl 도입하자고 제안했다.

JpaQueryFactory

querydsl을 사용하여 쿼리를 만들기 위해서는 JpaQueryFactory를 사용해야 한다.

이 JpaQueryFactory는 EntityManager 를 매개변수로 받는데, 각 repository class에서 이 과정에 대한 코드를 반복하는 것을 개선하기 위해 QuerydslConfig 클래스를 사용한다.

@Configuration
public class QuerydslConfig {
    @PersistenceContext
    private EntityManager entityManager;

    @Bean
    public JPAQueryFactory jpaQueryFactory() {
        return new JPAQueryFactory(entityManager);
    }
}

흔히 이 클래스에서 JpaQueryFactory bean을 생성하고 각 클래스에서 주입받는 방식을 이용한다.

querydsl을 사용하고자 하는 repository에서는 아래와 같이 JpaQueryFactory를 주입받는다.

@RequiredArgsConstructor
public class ExampleRepository {
    private final JPAQueryFactory queryFactory;
}

migration 대상

뉴핏 프로젝트에서 querydsl migration 대상은 @Query 어노테이션으로 쿼리를 직접 작성한 메서드이었고, 그중에서도 서브 쿼리가 없는 메서드만을 대상으로 했다.

서브 쿼리는 성능 상 이점이 없으므로 쿼리를 나눠서 실행하거나 조인을 사용해 해결하는 것을 추천하는 유명한 현직자님의 블로그 글을 참고하여 서브 쿼리가 끼어 있는 메서드를 일단은 제외했다.

제외한 서브 쿼리들은 향후 더 논의를 거쳐서 적절한 방식으로 개선하는 것이 좋을 것 같다.

사용자 정의 Repository

querydsl을 도입하기 전에는 JpaRepository를 상속하는 Repository의 구조였다.

querydsl을 사용할 때 흔히 사용하는 구조는 조금 다르다.

이 기술을 도입해도 여전히 JpaRepository가 생성해 주는 쿼리를 사용하고자 하는 경우가 있기 때문에 JpaRepository를 상속하는 Repository의 구조는 유지하되, 이 Repository가 새로운 interface를 상속하게 된다.

이때 이 새로운 interface를 사용자 정의 Repository라고 한다.

사용자 정의 Repository의 활용

사용자 정의 Repository interface의 이름을 CustomRepository라고 하자.

CustomRepository에는 querydsl을 사용하고자 했던 db 접근 메서드가 있을 것이다.

이 메서드를 구현하기 위해 interface의 구현체가 있어야 할 것이고, 위에서 준비해 둔 JpaQueryFactory를 바로 이 클래스에서 사용하게 된다.

@RequiredArgsConstructor
public class CustomRepositoryImpl implements CustomRepository {
    private final JpaQueryFactory queryFactory;

    // ...
}

이 구현체 클래스에서 주의해야 할 부분이 있다.

그냥 보기에는 interface를 구현하는 평범한 class지만, spring data jpa docs에서는 repository의 확장을 위해서는 아래의 명명 규칙을 따라야 함을 명시하고 있다.

The most important part of the class name that corresponds to the fragment interface is the Impl postfix.

'Spring' 카테고리의 다른 글

Querydsl로 동적 쿼리 활용하기  (0) 2024.02.14
[Spring Security] Authentication Architecture  (0) 2023.11.05
[Spring Security] Spring security Architecture  (0) 2023.11.05
[MVC2] API 예외 처리  (2) 2023.08.15
[MVC2] MVC 예외 처리  (0) 2023.08.12