JPQL와 Querydsl을 비교하며 기본적인 문법을 알아보자.
먼저 username으로 select하는 JPQL을 보자.
@Test
void startJPQL() {
//member1을 찾아라.
Member findMember =
em.createQuery("select m from Member m where m.username = :username", Member.class)
.setParameter("username", "member1")
.getSingleResult();
Assertions.assertThat(findMember.getUsername()).isEqualTo("member1");
}
//->테스트 성공
이때 날아간 쿼리문은 아래와 같다.
select
member0_.member_id as member_i1_1_,
member0_.age as age2_1_,
member0_.team_id as team_id4_1_,
member0_.username as username3_1_
from
member member0_
where
member0_.username=?
이번에는 Querydsl로 username으로 조회를 해보자.
@Test
void startQuerydsl() {
JPAQueryFactory queryFactory = new JPAQueryFactory(em);
QMember m = new QMember("m");
Member findMember = queryFactory
.select(m)
.from(m)
.where(m.username.eq("member1"))//파라미터 바인딩 처리
.fetchOne();
Assertions.assertThat(findMember.getUsername()).isEqualTo("member1");
}
• EntityManager로 JPAQueryFactory생성
• Querydsl은 JPQL빌더
• JPQL : 문자(실행 시점 오류), Querydsl : 코드 (컴파일 시점 오류)
• JPQL : 파라미터 바인딩 직접, Querydsl : 파라미터 바인딩 자동 처리
날아간 쿼리는 위의 JPQL에서와 같다.
select
member0_.member_id as member_i1_1_,
member0_.age as age2_1_,
member0_.team_id as team_id4_1_,
member0_.username as username3_1_
from
member member0_
where
member0_.username=?
Q타입 인스턴스
Q타입 인스턴스를 사용하는 방법은 3가지가 있다.
1. new를 사용하는 방법
/*1번 방법*/ QMember m = new QMember("m");
Member findMember = queryFactory
.select(m)
.from(m)
.where(m.username.eq("member1"))
.fetchOne();
제일 권장하지 않는 방법이다.
2. static 필드 사용하기
/*2번 방법*/ QMember m = QMember.member;//더 짧은 방법
Member findMember = queryFactory
.select(m)
.from(m)
.where(m.username.eq("member1"))
.fetchOne();
3. static 필드를 import하여 사용하는 방법.
/*3번 방법 - 제일 권장하는 방법*/
import static study.querydsl.entity.QMember.member;
Member findMember = queryFactory
.select(member)
.from(member)
.where(member.username.eq("member1"))
.fetchOne();
검색 조건 쿼리
아래와 같이 검색 조건이 2개 이상일 때 and를 사용하여 검색 조건을 추가할 수 있다.
@Test
void search1() {
Member findMember = queryFactory
.selectFrom(member)//요렇게 select + from 합치기 가능
.where(member.username.eq("member1")
.and(member.age.eq(10)))//and 또는 or로 체인걸기
.fetchOne();
Assertions.assertThat(findMember.getUsername()).isEqualTo("member1");
}
• 검색 조건은 .and(), .or() 를 메서드 체인으로 연결할 수 있다.
참고 : select 와 from을 위의 search1처럼 합칠 수 있음
Querydsl은 JPQL이 제공하는 모든 검색조건을 제공한다.
member.username.eq("member1") // username = 'member1'
member.username.ne("member1") // username != 'member1'
member.username.eq("member1").not() // username != 'member1'
member.username.isNotNull() // 이름이 is not null
member.age.in(10, 20) // age in (10,20)
member.age.notIn(10, 20) // age not in (10, 20)
member.age.between(10,30) // between 10, 30
member.age.goe(30) // age >= 30
member.age.gt(30) // age > 30
member.age.loe(30) // age <= 30
member.age.lt(30) // age < 30
member.username.like("member%") // like 검색
member.username.contains("member") // like ‘%member%’ 검색
member.username.startsWith("member") // like ‘member%’ 검색 ...
또한 아래와 같이 and조건을 파라미터로 처리할 수 있다.
@Test
void searchAndParam() {
Member findMember = queryFactory
.selectFrom(member)
.where(
//and조건 2개 파라미터
member.username.eq("member1"), member.age.eq(10)
)
.fetchOne();
Assertions.assertThat(findMember.getUsername()).isEqualTo("member1");
}
• where에 파라미터로 검색조건을 추가하면 AND조건이 추가된다.
• 이 경우 null값은 무시 -> 메서드 추출을 총해서 동적쿼리를 깔끔하게 만들 수 있다.
결과 조회
• fetch() : 리스트 조회, 데이터가 없으면 빈 리스트를 반환한다. (null아님을 보장)
• fetchOne() :단 건 조회
- 결과가 없으면 null을 반환.
- 결과가 둘 이상이면 com.querydsl.core.NonuiqueResultException
• fetchFirst : limit(1).fetchOne() 와 같닫.
이들을 사용해보자.
@Test
void resultFetch() {
//다수 조회
List<Member> fetch = queryFactory.selectFrom(member)
.fetch();
//단건 조회
Member fetchOne = queryFactory.selectFrom(member)
.fetchOne(); //-> 얘는 지금 모든 member를 조회하므로 에러발생
//하여 아래와 같이 unique한 조건을 추가해야함
Member fetchOne = queryFactory.selectFrom(member)
.where(member.username.eq("member1"))
.fetchOne();
//처음 한 건 조회
Member fetchFirst = queryFactory.selectFrom(QMember.member)
.fetchFirst();
}
수행된 쿼리 : 위에서 부터
//List
select
member0_.member_id as member_i1_1_,
member0_.age as age2_1_,
member0_.team_id as team_id4_1_,
member0_.username as username3_1_
from
member member0_
//단건 조회
select
member0_.member_id as member_i1_1_,
member0_.age as age2_1_,
member0_.team_id as team_id4_1_,
member0_.username as username3_1_
from
member member0_
where
member0_.username=?
// 맨 처음 하나 조회
select
member0_.member_id as member_i1_1_,
member0_.age as age2_1_,
member0_.team_id as team_id4_1_,
member0_.username as username3_1_
from
member member0_ limit ?
김영한님의 인프런 강의와 PDF를 바탕으로 정리하였습니다.
'JPA > Querydsl' 카테고리의 다른 글
Querydsl 06 - Case문, 상수 문자 더하기 (0) | 2022.01.18 |
---|---|
Querydsl 05 - 서브쿼리 (0) | 2022.01.18 |
Querydsl 04 - 조인 (0) | 2022.01.17 |
Querydsl 03 - 기본문법(정렬, 페이징, 집합) (0) | 2022.01.17 |
Querydsl 01 - 프로젝트 만들고 설정하기 (0) | 2022.01.15 |