Querydsl 공부하기

AeZan·2021년 9월 28일
0

전공 시간에는 SQL문만 작성하다가 실습에서 Querydsl를 사용하게 되었다
Querydsl이란 내가 이해한 바로는 String, XML 형태의 SQL문을 코드 형태로 나타낼 수 있도록 해주는 아이?

일단 레퍼런스 문서 사이트 부터 찾아가 보았다.

👉 https://querydsl.com/static/querydsl/4.0.1/reference/ko-KR/html_single/

모르겠다. 기본 사용법부터 공부해야 겠다.

👉 https://dev-gorany.tistory.com/32 👈
많이 배웠습니다. 정리 감사합니다 ㅜㅜ

📌 사용하기 위한 준비 - dependency 추가

 <dependency>
      <groupId>com.querydsl</groupId>
      <artifactId>querydsl-jpa</artifactId>
    </dependency>
    <dependency>
      <groupId>com.querydsl</groupId>
      <artifactId>querydsl-apt</artifactId>
      <scope>provided</scope>
    </dependency>

🧷 쿼리클래스 생성

이게 제일 신기했다. 쿼리를 위한 클래스가 따로 생성되다니..

 <plugin>
        <groupId>com.mysema.maven</groupId>
        <artifactId>apt-maven-plugin</artifactId>
        <version>1.1.3</version>
        <executions>
          <execution>
            <goals>
              <goal>process</goal>
            </goals>
            <configuration>
              <outputDirectory>target/generated-sources/java</outputDirectory>
              <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
            </configuration>
          </execution>
        </executions>
      </plugin>

그리고 이제 maven 탭에서 Lifecycle > compile 해주면 자동으로 Q 로 시작되는 클래스가 생성될 것이다.

가끔 이를 인식을 못할 때가 있는데 그럴 땐 소스 경로에 target/generated-sources를 추가하면 된다고 한다.

intelliJ) Modules 탭에서 target/generated-sources/java 폴더 클릭한 뒤 상단 Mark as의 Sources 클릭하여 소스폴더로 인식하도록 설정



📌 본격적으로 사용하기 위해 문법 알아보기

들어가기 앞서 JPQL이 뭔지 알아보고 가야겠다.

🧷 JPQL

JPA가 SQL을 추상화한 JPQL이라는 객체지향 쿼리 언어를 제공함
JPQL은 엔티티 객체를 대상으로 쿼리를 질의
SQL은 데이터베이스 테이블을 대상으로 쿼리 질의
JPQL은 결국 SQL로 변환

-JPQL

String jpql= "select m From Member m where m.name like '%hello%'";
List<Member> result = em.createQuery(jpql, Member.class).getResultList();

-SQL

select
  m.id as id,
  m.age as age,
  m.USERNAME as USERNAME,
  m.TEAM_ID as TEAM_ID
from
  Member m
where
  m.age>18

출처: https://ict-nroo.tistory.com/116 [개발자의 기록습관]

JPQL도 SQL과 비슷하게 SELECT, UPDATE, DELETE 문을 사용 가능
(저장시, EntityManager.persist() 메소드를 사용하므로 INSERT는 존재하지 않음)


출처: https://cornswrold.tistory.com/334 [평범한개발자노트]


🧷 Querydsl 사용하기

JPQLquery, BooleanBuilder 사용

JPQLquery?
BooleanBuilder? 동적 쿼리를 쉽게 생성할 수 있음 (SQL에서 where 절)

BooleanExpression 도 사용하는듯. 메소드 형식이라서 다른 쿼리에서도 사용할 수 있어서 재사용성이 좋은거 같음, 이거를 추천하는 사람들이 더 많았음
메소드에서 null return 되면 해당 조건을 무시할 수 있어 동적쿼리가 가능

  • BooleanBuilder 사용 -> and.(조건식)
@Override
public List<Member> findDynamicQuery(String name, String age, String phoneNumber) {
    BooleanBuilder builder = new BooleanBuilder();
    
    if (!StringUtils.isEmpty(name))
        builder.and(member.name.eq(name));
    if (!StringUtils.isEmpty(age))
        builder.and(member.age.eq(age));
    if (!StringUtils.isEmpty(phoneNumber))
        builder.and(member.phoneNumber.eq(phoneNumbeR));
 
    return queryFactory
            .selectFrom(member)
            .where(builder)
            .fetch();
}
  • BooleanExpression
@Override
public List<Member> findDynamicQuery(String name, String age, String phoneNumber) {
    return queryFactory
            .selectFrom(member)
            .where(eqName(name),
                    eqAge(age),
                    eqPhoneNumber(phoneNumber))
            .fetch();
}
 
private BooleanExpression eqName(String name) {
    if (StringUtils.isEmpty(name)) return null;
    else return member.name.eq(name);
}
 
private BooleanExpression eqAge(String age) {
    if (StringUtils.isEmpty(age)) return null;
    else return member.age.eq(age);
}

코드 참고 https://www.kua.kr/44

🧷 repository 를 확장하여 작성하기

구현 클래스는 (인테페이스 이름 + Impl) 으로 작성

public class ActivityRepositoryImpl extends QuerydslRepositorySupport implements
    CustomActivityRepository {

  QLatestActivity latestActivity = QLatestActivity.latestActivity;

  public ActivityRepositoryImpl() {
    super(Activity.class);
  }

QuerydslRepositorySupport 를 상속받아야 Querydsl을 사용하여 쿼리를 작성할 수 있다고 한다.
그리고 도메인 엔티티 클래스를 슈퍼타입인 QuerydslRepositorySupport 생성자의 인자로 넘겨주어야 한다고 한다. (생성자가 존재하므로)

 @Override
  public List<latestActivityListDTO> findListWithActivity() {
    BooleanBuilder builder = new BooleanBuilder();

    builder.and(latestActivity.value.lt(10));

    return from(latestActivity)
        .where(builder)
        .select(new QlatestActivityListDTO(
            latestActivity.activityDate, latestActivity.cow, latestActivity.type,
            latestActivity.value))
        .fetch();
  }

JPQLQuery 문법

  • from : 쿼리 소스 추가
  • innerJoin, leftJoin, fullJoin, on: 조인 추가
  • where: 쿼리 필터 추가, 가변인자나 AND/OR 메서드 이용하여 필터 추가
  • groupBy: 가변인자 형식의 인자를 기준으로 그룹 추가
  • having: groupBy 의 필터 추가
  • orderBy: 정렬 순서 지정, asc() or desc()
  • limit, offset, restrict: 페이징 설정, limit은 최대 결과 개수, offset은 결과의 시작 행, restrict는 limit과 offset 함께 정의


작성하다 보니 의문이 생겼다. 그래서 JPQLQuery랑 Querydsl이랑 뭐가 다른 거지?
결국엔 JPQLQuery 문법을 사용해서 코드를 작성하는건데? 라는 의문.

그래서 찾아보았다

📋 Querydsl 라이브러리 내에 JPQLQuery 라는 인터페이스를 활용하는 것이라고 한다.

0개의 댓글