QueryDSL 개념 정리

devlsn96·2024년 10월 31일
0

JPQL은 검색에 대한 null 처리가 너무 복잡하기 때문에 검색 쿼리에 대한 더 좋은 유지관리를 위해 QueryDSL을 사용한다.

QueryDSL 설정하기

  • 먼저, QueryDSL에 대한 라이브러리를 추가한다. (gradle방식)
    implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" annotationProcessor "jakarta.annotation:jakarta.annotation-api" annotationProcessor "jakarta.persistence:jakarta.persistence-api"
  • Q클래스를 저장할 공간 지정을 위한 설정을 추가 한다.
def querydslDir = "$buildDir/generated/querydsl"
sourceSets {
	main.java.srcDirs += [ querydslDir ]
}
tasks.withType(JavaCompile) {
	options.generatedSourceOutputDirectory = file(querydslDir)
}
clean.doLast {
	file(querydslDir).deleteDir()
}
  • Qclass생성을 위해 Gradle task에서 해당 프로젝트의 build파일을 실행해준다.
  • 다음과 같은 build폴더가 생기면 QueryDSL을 작성할 준비가 된거다!!

QueryDSL 사용하기

01. queryDSL 객체를 선언

JPAQueryFactory queryFactory = new JPAQueryFactory(em);

02. Q엔티티객체 생성과 별칭명을 부여한다.

  • 예를 들어, QMember 가 있다고 한다면, QMember객체의 이름은 'm'이다.
    QMember m = new QMember("m");
    QMember m = QMember.m;
  • 상단에 import static 구문으로 변수를 직접 지정할 수도 있다.
    import static com.codingbox.querydsl.entity.QMember.*;

03. 쿼리 작성

select m from Member m where m.username = :username
과 같은 쿼리는 아래와 같이 표현할 수 있다.

queryFactory.select(member)
			.from(member)
            .where(member.username.eq("member1"))
			.fetchOne();
  • .select(member)하는 대상과 .from(member)하는 대상이 동일하면, .selectFrom(member)이 가능하다.

SQL 예약어와 QueryDSL 내장함수 비교

SQLQueryDSL
AND절.and() (또는, and()를 콤마(,)로 구분가능하다)
order by asc, order by desc절.orderBy(필드값.desc()나 .asc())
null은 마지막에 위치.nullsLast()
group by절.groupBy()
having 조건절.having()
left outer join절.leftJoin("조인객체","객체이름").on("조인되는필드값")
inner join절.join().on()
IN절.in()
concat절.concat("")

쿼리 조회

  • fetch() : 리스트로 조회
  • fetchOne() : 단 건으로 조회

페이징 처리

  • .offset() : JPQL의 setFirstResult(), 해당 인덱스부터 조회
  • .limit() : JPQL의 setMaxResults(), 해당 건까지 조회

집합 함수 처리

jpql의 count(*), sum(m.age), avg(m.age), max(m.age), min(m.age)등 집계함수에 대한 처리는 queryDSL에서도 Tuple이라는 라이브러리를 사용하면 가능하다.
select count(m), sum(m.age), avg(m.age), max(m.age), min(m.age) from Member m

서브 쿼리

  • Q엔티티 객체를 하나 더 생성해서 JPAExpressions로 서브 쿼리문으로 활용
queryFactory.selectFrom(member)
			.where(member.age.eq(
				JPAExpressions.select(memberSub.age.max())
							.from(memberSub)
			))

case 구문

| when ~ then문 | .when(조건).then("값").otherwise("기타 값") |

  • 좀 더 복잡한 case문은 new CaseBuilder() 객체를 통해 생성할 수 있다.

DTO 객체를 조회할 때,

  • Projections객체를 활용하여 bean, fields, 생성자를 조회할 수 있다.
  • bean
.select(Projections.bean(MemberDTO.class, member.username, member.age))
  • fields (만약, fields값이 다르면, .as()를 붙혀 이름을 동일하게 변경한다.)
.select(Projections.fields(MemberDTO.class, member.username, member.age))
.select(Projections.fields(UserDTO.class, member.username.as("name"), member.age))
  • 생성자
.select(Projections.constructor(MemberDTO.class, member.username, member.age))
profile
Quantum Jump to class for java….

0개의 댓글