기본 Q-Type 활용
Q클래스 인스턴스를 사용하는 2가지 방법
QMember qMember = new QMember("m"); //별칭 직접 지정
QMember qMember = QMember.member; //기본 인스턴스 사용
이렇게 2가지 방법이 있습니다. 하지만 이것보다 더 간편하게 사용할 수 있는 방법은 static import를 사용하는 것 입니다.
이렇게 static imprort로 사용할 수 있습니다.
쿼리를 보면 별칭으로 member1으로 되어있습니다. 이것은 default 값으로
Qmember에 설정되어 있습니다!!
Querydsl을 실행하다가 JPQL 형식을 보고 싶으면
spring.jpa.properties.hibernate.use_sql_comments: true
이걸 application.yml에 추가하면 됩니다.
그럼 이렇게 JPQL 쿼리도 볼 수 있습니다.
검색 조건 쿼리
기본 검색 쿼리
만약 멤버중에 이름이 member1이고 나이가 10살인 사람을 찾을려면 어떻게 해야할까??
만약 JPQL로 짠다면 아래의 코드처럼 짜야 합니다.
select m from Member m where m.username = "member1" and member.age = 10;
이것을 Querydsl로 짠다면
Member findMember = queryFactory
.selectFrom(member)
.where(member.username.eq("member1")
.and(member.age.eq(10)))
.fetchOne();
이렇게 짤 수 있습니다. selectFrom으로 select와 from을 합치고 and로 where절 조건을 이어 나갑니다. 처음 써보는 입장에서 진짜 편리하고 가독성이 좋다고 느꼈습니다.
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%’ 검색
...
거의 대부분은 뒤에 오는 축약어를 보면 어떤 것을 하는 메소드인지 쉽게 알 수 있었습니다.
하지만 goe, gt, loe, lt가 머의 약자일지 궁금했습니다.
- goe: "Greater Than or Equal"의 약자로서, 값이 주어진 값보다 크거나 같음을 나타냅니다.
- gt: "Greater Than"의 약자로서, 값이 주어진 값보다 큼을 나타냅니다.
- loe: "Less Than or Equal"의 약자로서, 값이 주어진 값보다 작거나 같음을 나타냅니다.
- lt: "Less Than"의 약자로서, 값이 주어진 값보다 작음을 나타냅니다.
AND 조건을 파라미터로 처리
@Test
public void searchAndParam() throws Exception {
// when
Member findMember = queryFactory
.selectFrom(member)
.where(
member.username.eq("member1"),
member.age.eq(10))
)
.fetchOne();
//then
assertThat(findMember.getUsername()).isEqualTo("member1");
}
이렇게 ,로 and를 대체할 수 있습니다!!
이 경우 null 값은 무시하기 때문에 메서드 추출을 활용해서 동적 쿼리를 깔끔하게 만들 수 있습니다.
결과 조회
- fetch() : 리스트 조회, 데이터 없으면 빈 리스트 반환
- fetchOne() : 단 건 조회
- 결과가 없으면 : null
- 결과가 둘 이상이면 : com.querydsl.core.NonUniqueResultException
- fetchFirst() : limit(1).fetchOne()
- fetchResults() : 페이징 정보 포함, total count 쿼리 추가 실행
- fetchCount() : count 쿼리로 변경해서 count 수 조회
//List
List<Member> fetch = queryFactory
.selectFrom(member)
.fetch();
//단 건
Member findMember1 = queryFactory
.selectFrom(member)
.fetchOne();
//처음 한 건 조회
Member findMember2 = queryFactory
.selectFrom(member)
.fetchFirst();
//페이징에서 사용
QueryResults<Member> results = queryFactory
.selectFrom(member)
.fetchResults();
//count 쿼리로 변경
long count = queryFactory
.selectFrom(member)
.fetchCount();
강의안에 있는 fetchResults와 fetchCount는 스프링부트 3.0으로 변경되면서 deprecated 되었습니다.
왜냐하면 fetchResult의 경우 count 하기위해선 count용 쿼리를 만들어서 실행해야 하는데, 복잡한 쿼리는 count 쿼리가 잘 동작하지 않는다고 합니다. 구글링을 해보니 group by having 절을 사용하는 등의 복잡한 쿼리 문에서 예외가 생긴다고 합니다.
그래서 fetch()로 값을 가져오고 페이징 하는게 더 좋다고 합니다.
출처
https://www.inflearn.com/course/querydsl-%EC%8B%A4%EC%A0%84/dashboard
실전! Querydsl - 인프런 | 강의
Querydsl의 기초부터 실무 활용까지, 한번에 해결해보세요!, 복잡한 쿼리, 동적 쿼리는 이제 안녕! Querydsl로 자바 백엔드 기술을 단단하게. 🚩 본 강의는 로드맵 과정입니다. 본 강의는 자바 백엔
www.inflearn.com
'BackEnd > Querydsl' 카테고리의 다른 글
Querydsl 기본 문법 (정렬, 페이징, 집합) (1) | 2023.08.28 |
---|---|
JPQL과 Querydsl에 차이 (0) | 2023.08.28 |
Querydsl 세팅 (0) | 2023.08.27 |