JPA
Querydsl 서브쿼리
쭈녁
2024. 3. 31. 23:10
Querydsl에서 서브쿼리 사용 시 새로운 Q타입의 객체를 생성하여 중첩되지 않도록 사용하여야 한다.
1. Where 절에 서브쿼리 사용 예 1
/**
* 나이가 가장 많은 회원
*/
@Test
public void subQuery() throws Exception {
QMember sub = new QMember("memberSub"); // 서브쿼리 Q타입 객체 생성
//when
List<Member> result = queryFactory
.selectFrom(member)
.where(member.age.eq(
JPAExpressions
.select(sub.age.max())
.from(sub))) //fetch는 하지 않는다
.fetch();
//then
assertThat(result).extracting("age").containsExactly(40);
}
2. Where 절에 서브쿼리 사용 예 2
/**
* 나이가 평균 이상 회원
*/
@Test
public void subQueryGoe() throws Exception {
QMember sub = new QMember("memberSub");
//when
List<Member> result = queryFactory
.selectFrom(member)
.where(member.age.goe(
JPAExpressions
.select(sub.age.avg())
.from(sub))) //fetch는 하지 않는다
.fetch();
//then
assertThat(result).extracting("age").containsExactly(30, 40);
}
3. Where 절에 in을 사용하여 List타입으로 필터링
/**
* 나이가 평균 이상 회원
*/
@Test
public void subQueryIn() throws Exception {
QMember sub = new QMember("memberSub");
//when
List<Member> result = queryFactory
.selectFrom(member)
.where(member.age.in(
JPAExpressions
.select(sub.age)
.from(sub)
.where(sub.age.gt(10)))) //fetch는 하지 않는다
.fetch();
//then
assertThat(result).extracting("age").containsExactly(20, 30, 40);
}
4. Select 절에 사용 예시
각기 다른 여러 타입을 조회 시 Querydsl은 Tuple이라는 객체에 여러 타입을 담아줌
@Test
public void selectSubQuery() throws Exception {
QMember sub = new QMember("memberSub");
//when
List<Tuple> result = queryFactory
.select(member.username,
JPAExpressions
.select(sub.age.avg())
.from(sub))
.from(member)
.fetch();
for (Tuple tuple : result) {
System.out.println("tuple = " + tuple);
}
}
더보기
** !! JPA의 한계 : from 절 서브쿼리가 되지 않는다. 해결방안은 아래와 같다.!! **
1. from 절의 서브쿼리를 join으로 대체 (불가능한 상황이 간혹 있다)
2. 애플리케이션에서 쿼리를 2번으로 분리하여 실행
3. nativeSQL을 사용한다.
중요!! : 쿼리는 데이터를 퍼올리는 용도로만 사용하고 애플리케이션단에서 조합한다.
쓸데없는 서브쿼리의 남용을 피해야 하며 한방 쿼리가 필요한 시점이 언제인지 고민해야 한다.
(필요 시점) ->> 전체 조회와 같은 성능이 중요한 경우에 한방
참고자료
김영한 : 실전! Querydsl
https://www.inflearn.com/course/querydsl-%EC%8B%A4%EC%A0%84/dashboard
실전! Querydsl | 김영한 - 인프런
김영한 | Querydsl의 기초부터 실무 활용까지, 한번에 해결해보세요!, 복잡한 쿼리, 동적 쿼리는 이제 안녕! Querydsl로 자바 백엔드 기술을 단단하게. 🚩 본 강의는 로드맵 과정입니다. 본 강의는 자
www.inflearn.com