스프링데이터 + JPA/QueryDSL

35. 스프링 데이터 JPA가 제동하는 QueryDSL 기능

sdafdq 2023. 12. 4. 07:49

사실 지금부터 이야기 하는 기능들은, 제약이 커서 실무에서는 잘 활용 안함. 테이블 하나일 땐 괜찮은 데 join 하면서 여러 개 하면 잘 동작을 안한다고 함.

 

우선 첫번째로는, 

QuerydslPredicateExecutor라고, 

스프링 데이터 JPA에서 Querydsl과 함께 쓸 수 있도록 해주는 것 이다.

 

그러니까, 마치 우리가 스프링 데이터 JPA 만들었을 때 처럼, findAll 같은 것을 지원해 주는 것이다.

그런데, 거기 안에 술어를 쓸 수 있다.

 

public interface MemberRepository extends JpaRepository<Member, Long>, MemberRepositoryCustom, QuerydslPredicateExecutor<Member> {
    List<Member> findByUsername(String username);
}

저렇게 QuerydslPredicateExecutor<엔티티> 인터페이스를 추가한다.

 

public interface QuerydslPredicateExecutor<T> {

    Optional<T> findOne(Predicate predicate);

    Iterable<T> findAll(Predicate predicate);

    Iterable<T> findAll(Predicate predicate, Sort sort);

    Iterable<T> findAll(Predicate predicate, OrderSpecifier<?>... orders);

    Iterable<T> findAll(OrderSpecifier<?>... orders);

    Page<T> findAll(Predicate predicate, Pageable pageable);

    long count(Predicate predicate);

    boolean exists(Predicate predicate);

    <S extends T, R> R findBy(Predicate predicate, Function<FluentQuery.FetchableFluentQuery<S>, R> queryFunction);
}

실제 인터페이스 내부이다.

 

이제 저걸 사용할 때는,

@Test
public void querydslPredicateExecutorTest(){
	......

    QMember m = QMember.member;
    Iterable<Member> members = memberRepository.findAll(m.age.between(20, 40).and(m.username.eq("member3")));
    for (Member member : members) {
        System.out.println("member = " + member);
    }
}

마치 Spring Data JPA 쓰듯이 쓰면 되는데, 인자로 저렇게 표현식을 넣어주면 된다. 저 곳에 where가 들어간다.

 

/* select
    member1 
from
    Member member1 
where
    member1.age between ?1 and ?2 
    and member1.username = ?3 */ select
        m1_0.member_id,
        m1_0.age,
        m1_0.team_id,
        m1_0.username 
    from
        member m1_0 
    where
        m1_0.age between ? and ? 
        and m1_0.username=?

쿼리도 술어대로 들어갔다.

 

술어와 표현식의 차이는 술어는 참거짓의 조건이고, 표현식은 넓은 범위. 

 

간단해 보이지만 한계가 있다.

 

조인이 안된다. (묵시적 조인은 가능하나 left join이 안됨.)

저거는 서비스나 그런 곳에서 호출하게 될 텐데, 그렇게 된다면 저 Q에 대한 표현식을 알기 위해 QueryDSL 기술을 import 하게 된다. 

 

묵시적 조인이란 연관관계를 참조할 때 알아서 조인해오는 거. 

 

 

그리고 이거 Pageable, Sort 되긴 됨.