QueryDsl 개념 정리와 예시 코드

choko's avatar
Jun 29, 2024
QueryDsl 개념 정리와 예시 코드
 

1. 설치

  • build.gradle
... dependencies { ... //Querydsl 추가 implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' annotationProcessor "com.querydsl:querydsl-apt:${dependencyManagement.importedProperties['querydsl.version']}:jakarta" annotationProcessor "jakarta.annotation:jakarta.annotation-api" annotationProcessor "jakarta.persistence:jakarta.persistence-api" } def generated = 'src/main/generated' // querydsl QClass 파일 생성 위치를 지정 tasks.withType(JavaCompile) { options.getGeneratedSourceOutputDirectory().set(file(generated)) } // java source set 에 querydsl QClass 위치 추가 sourceSets { main.java.srcDirs += [ generated ] } // gradle clean 시에 QClass 디렉토리 삭제 clean { delete file(generated) }
 
  • Gradle/build/build 실행
  • 위에 설정한src/main/generated/sources 밑에 Q{Entity} 클래스들 생성 확인
notion image
 

2. Repository 구조

 
notion image
(→ Academy 라는 Repo example)
 
  • 기본적으로 3가지 Repo 파일을 생성한다.
notion image
 
  1. CustomRepositoryImpl : QueryDsl를 사용할 custom repo 구현체, CustomRepository 상속
    1. @RequiredArgsConstructor public class CustomReservationRepositoryImpl implements CustomReservationRepository { private final JPAQueryFactory queryFactory; public List<Reservation> findReservations() { QReservation r = QReservation.reservation; return queryFactory.selectFrom(r).where(r.customerId.eq("tom")).fetch(); } }
      • QReservation r = QReservation.reservation; → src/main/generated/sources에 확인
       
  1. CustomRepository
    1. public interface CustomReservationRepository { public List<Reservation> findReservations(); }
       
  1. Repository: JpaRepository<Entity, PK_TYPE>, CustomRepository 상속
    1. public interface ReservationRepository extends JpaRepository<Reservation, Long>, CustomReservationRepository { List<Reservation> findByCustomerId(String customerId); Reservation findByReservationPaymentFilm(String reservationPaymentFilm); List<Reservation> findFirst2ByCustomerId(String customerId); }
       
       
       

3. JPAQuery Config 빈 등록

  • Querydsl를 사용하려면 JPAQueryFactory가 필요
    • 일일히 주입받기 귀찮으므로 bean으로 등록하여 생성자 주입을 받는다.
  • @PersistenceContext : DataSourceConfiguration에서 생성한 EntityManager를 주입.
@Configuration public class QueryDslConfig { private static JPAQueryFactory jpaQueryFactory; @PersistenceContext private EntityManager entityManager; @Bean public JPAQueryFactory jpaQueryFactory() { return new JPAQueryFactory(entityManager); } }
 
 

4. 테스트

@SpringBootTest @Slf4j @RequiredArgsConstructor public class QueryDslTest { @Autowired ReservationRepository reservationRepository; @Test void QueryDSLTest() { List<Reservation> reservations = reservationRepository.findReservations(); for(Reservation r: reservations) { log.info("{}, {}, {}, {}",r.getReservationPaymentId(), r.getCustomerId(), r.getReservationPaymentScheduleId(), r.getReservationPaymentFilm()); } } }
 
 

5. 문법

  1. 결과 조회
fetch() : 리스트 조회, 데이터 없으면 빈 리스트 반환(null 아니다) fetchOne() : 단 건 조회, 결과가 없으면 null, 결과가 둘 이상이면 예외 발생 fetchFirst() : limit(1).fetchOne() 과 같다.
 
  1. 정렬
desc() : 내림차순 asc() : 올림차순 nullsLast() : null 데이터 순서 부여(마지막) nullsFirst() : null 데이터 순서 부여(처음)
 
  1. 페이징
offset(long offset) : 쿼리 결과에 대한 오프셋을 정의, 0부터 시작 limit(long limit) : 쿼리 결과에 대한 제한/최대 결과를 정의
 
  1. 집합
count() : 카운트 sum()   : 합 avg()    : 평균 max()   : 최대 min()    : 최소
 
  1. 그룹화
groupby() : 그룹화/집계 having() : 그룹화/집계용 필터
 
  1. 조인
join(), innerJoin()  : 내부 조인(inner join) leftJoin()            : left 외부 조인(left outer join) rightJoin()          : right 외부 조인(right outer join)
 
  • 조인 예제 - Customer(customerName), Reservation(customId)
public List<Reservation> CustomsReservation(String customName) { QReservation r = QReservation.reservation; QCustomer c = QCustomer.customer; return queryFactory.selectFrom(r). join(c).on(r.customerId.eq(c.customerName)). where(c.customerName.eq(customName)). fetch(); }
 
 
  1. 서브 쿼리
    1. com.querydsl.jpa.JPAExpressions
    2. int()
    3. select()
    4.  
Share article

Tom의 TIL 정리방