Tools & Libraries/Querydsl
[Querydsl] Querydsl 기본문법 2 (검색 조건, 결과 조회, 정렬, 페이징)
대기업 가고 싶은 공돌이
2024. 9. 3. 05:30
검색 조건 쿼리
@Test
public void search(){
Member findMember = queryFactory
.selectFrom(member)
.where(member.username.eq("member1")
.and(member.age.eq(10)))
.fetchOne();
Assertions.assertThat(findMember.getUsername()).isEqualTo("member1");
}
우선 다음과 같이 테스트 코드를 작성해주었다.
where절에서는 위와 같이 메소드 형식으로 and, or 을 비롯한 무수하게 많은 검색 조건을 제공한다.
- equal, not equal
- member.username.eq("member1")
- member.username.ne("member1")
- isNotNull
- member.username.isNotNull();
- in, between
- member.age.in(10,20)
- member.age.notIn(10,20)
- member.age.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
- like
- member.username.like("member%")
- member.username.contains("member") // like %member% 과 동일
- member.username.startWith("member") // like %member
검색 조건 쿼리 추가 팁
and 같은 경우엔 다음과 같이 and를 생략하고 ,으로 넘겨줄 수도 있다.
@Test
public void search(){
JPAQueryFactory queryFactory = new JPAQueryFactory(em);
Member findMember = queryFactory
.selectFrom(member)
.where(member.username.eq("member1")
,member.age.eq(10))
.fetchOne();
Assertions.assertThat(findMember.getUsername()).isEqualTo("member1");
}
결과 조회
- fetch(): 리스트 조회, 데이터 없으면 빈 리스트 반환
List<Member> fetch = queryFactory.selectFrom(member)
.fetch();
- fetchOne(): 단 건 조회
- 결과가 없으면 null 반환
- 결과가 둘 이상이면 com.querydsl.core.NonUniqueResultException 호출
Member fetchOne = queryFactory.selectFrom(member)
.fetchOne();
- fetchFirst(): limit(1).fetchOne() //리미트를 걸면서 페치하는 것
Member fetchFirst = queryFactory
.selectFrom(member)
.fetchFirst();
- fetchResults(): 페이징 정보 포함, total count 쿼리 추가 실행
- 페이징 쿼리를 같이 날리면서 total count를 같이 가져온다.
- 복잡한 페이징 쿼리를 날릴 때는 해당 메소드를 사용하면 성능이 떨어지기 때문에 사용하면 안 된다.
QueryResults<Member> results = queryFactory
.selectFrom(member)
.fetchResults();
results.getTotal();
List<Member> content = results.getResults();
results를 가져온 후 getResults를 해야 안에 담긴 Member List를 가져올 수 있다.
- fetchCount(): count 쿼리로 변경해서 count 수만 조회하는 기능
long l = queryFactory
.selectFrom(member)
.fetchCount();
위의 코드를 실행 시키면 select count(member1) 쿼리가 나간 것을 확인할 수 있다.
정렬
/**
*회원 정렬 순서
* 1. 회원 나이 내림차순
* 2. 회원 이름 올림차순
* 3. 2에서 회원 이름이 없으면 마지막에 출력 (nulls last 기능)
*/
@Test
public void sort(){
JPAQueryFactory queryFactory = new JPAQueryFactory(em);
em.persist(new Member(null,100));
em.persist(new Member("member5",100));
em.persist(new Member("member6",100));
List<Member> result = queryFactory
.selectFrom(member)
.where(member.age.eq(100))
.orderBy(member.age.desc(), member.username.asc().nullsLast())
.fetch();
Member member5 = result.get(0);
Member member6 = result.get(1);
Member memberNull = result.get(2);
Assertions.assertThat(member5.getUsername()).isEqualTo("member5");
Assertions.assertThat(member6.getUsername()).isEqualTo("member6");
Assertions.assertThat(memberNull.getUsername()).isNull();
}
order by 절 안에서 다음과 같이 desc, asc, nullsLast, nullsFirst 등의 옵션을 전부 사용할 수 있다.
페이징
@Test
public void paging1(){
JPAQueryFactory queryFactory = new JPAQueryFactory(em);
List<Member> result = queryFactory.selectFrom(member)
.orderBy(member.username.desc()) // order by를 사용하는 이유는 결과 확인을 위해서
.offset(1)
.limit(2)
.fetch();
Assertions.assertThat(result.size()).isEqualTo(2);
}
querydsl에서는 위와 같이 offset과 limit를 통해 페이징을 지원한다.
만약 토탈 카운트도 한 번에 알아내고 싶다면 다음과 같이 쿼리를 작성할 수도 있다.
@Test
public void paging1(){
JPAQueryFactory queryFactory = new JPAQueryFactory(em);
QueryResults<Member> results = queryFactory.selectFrom(member)
.orderBy(member.username.desc()) // order by를 사용하는 이유는 결과 확인을 위해서
.offset(1)
.limit(2)
.fetchResults();
Assertions.assertThat(results.getTotal()).isEqualTo(4);
Assertions.assertThat(results.getLimit()).isEqualTo(2);
Assertions.assertThat(results.getResults().size()).isEqualTo(2);
}
카운트 쿼리를 조인을 하지 않고 간단하게 작성할 수 있을 경우엔 위의 코드를 사용하지 않고,
카운트 쿼리를 따로 작성하여 성능을 향상시켜야 한다.
참고 영상: 김영한 실전! Querydsl