Java / / 2023. 1. 18. 15:55

QuerydslPredicateExecutor - querydsl 조건 조회 간단히 사용하기

반응형

해당 글은 김영한 님의 querydsl을 수강하며 정리하려고 적는 포스팅입니다.

 

지금 소개하는 기능은 제약이 커서 복잡한 실무 환경에 사용하기에는 많이 부족하다.

그래도 spring data에서 제공하는 기능이므로 간단히 소개하고, 왜 부족한지 설명한다.

 

💡 인터페이스 지원 - QuerydslPredicateExecutor

 

Spring Data JPA - Reference Documentation

Example 108. Using @Transactional at query methods @Transactional(readOnly = true) public interface UserRepository extends JpaRepository { List findByLastname(String lastname); @Modifying @Transactional @Query("delete from User u where u.active = false") v

docs.spring.io

 

QuerydslPredicateExecutor 인터페이스

public interface QuerydslPredicateExecutor<T> {
    Optional<T> findById(Predicate predicate); 
    Iterable<T> findAll(Predicate predicate); 
    long count(Predicate predicate); 
    boolean exists(Predicate predicate); 
    // … more functionality omitted.
}

 

리포지토리에 적용

  • 앞서 포스팅한 MemberRepository에 QuerydslPredicateExecutor <T>를 추가해 주었다.
public interface MemberRepository extends JpaRepository<Member, Long>, MemberRepositoryCustom, QuerydslPredicateExecutor<Member> {
    List<Member> findByUsername(String username);
}

 

테스트

package study.querydsl.repository;

import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.transaction.Transactional;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import study.querydsl.dto.MemberSearchCondition;
import study.querydsl.dto.MemberTeamDto;
import study.querydsl.entity.Member;
import study.querydsl.entity.QMember;
import study.querydsl.entity.Team;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

@SpringBootTest
@Transactional
class MemberRepositoryTest {

    @PersistenceContext
    EntityManager em;

    @Autowired
    MemberRepository memberRepository;
    
    @Test
    public void querydslPredicateExecutorTest() {
        Team teamA = new Team("teamA");
        Team teamB = new Team("teamB");
        em.persist(teamA);
        em.persist(teamB);

        Member member1 = new Member("member1", 10, teamA);
        Member member2 = new Member("member2", 20, teamA);
        Member member3 = new Member("member3", 30, teamB);
        Member member4 = new Member("member4", 40, teamB);
        em.persist(member1);
        em.persist(member2);
        em.persist(member3);
        em.persist(member4);

        QMember member = QMember.member;
        Iterable<Member> result = memberRepository.findAll(member.age.between(10, 40).and(member.username.eq("member1")));
        for (Member findMember : result) {
            System.out.println("findMember = " + findMember);
        }
    }
}
---------------------------------------------------------------------------------------
2023-01-18T15:23:48.108+09:00 DEBUG 14500 --- [           main] org.hibernate.SQL                        : 
    /* 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=?
findMember = Member(id=1, username=member1, age=10)

 

한계점

  • 간단한 곳에서 사용하는 것은 가능하다.
  • 조인이 불가능 하다. (묵시적 조인은 가능하지만 left join이 불가능하다.)
  • 클라이언트가 Querydsl에 의존해야 한다.
    • service와 controller 등이 Querydsl이라는 구현 기술에 의존해야 하므로 좋지 않다.
    • repository를 만드는 이유는 하부에 querydsl과 같은 구체화된 기술을 숨기는 목적이다.
      • 만약에 querydsl이나 다른 기술을 변경하려고 할 때, repository만 변경하면 되는데 service와 controller가 의존하게 되면 모든 게 변경되어야 하기 때문에 좋지 않은 것이다.
      • 순수한 DTO 같은 class를 넘기는 것이 아니라 querydsl과 연관된 객체를 만들어 넘겨야 한다는 것이다.
  • 복잡한 실무환경에서 사용하기에는 한계가 명확하다.
참고: QuerydslPredicateExecutor 는 Pagable, Sort를 모두 지원하고 정상 동작한다

 


💡 참고 : Query Web 지원

 

한계점

  • 단순한 조건만 가능
  • 조건을 커스텀하는 기능이 복잡하고 명시적이지 않다.
  • 컨트롤러가 Querydsl에 의존한다.
  • 복잡한 실무환경에서 사용하기에 한계가 명확하다.
반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유