빙응의 공부 블로그

[Spring]QueryDSL 기본문법 본문

Spring/QueryDSL

[Spring]QueryDSL 기본문법

빙응이 2024. 7. 28. 20:36

목차

 

📝 개요 

QueryDSL에서 제공하는 검색 조건에 대해 알아보자!!
기본 검색 조건 쿼리
 @Test
 public void search() {
Member findMember = queryFactory
            .selectFrom(member)
            .where(member.username.eq("member1")
                    .and(member.age.eq(10)))
            .fetchOne();
 assertThat(findMember.getUsername()).isEqualTo("member1");
 }

 

코드 기능
member.username.eq("member1") username = 'member1'
member.username.ne("member1") 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%’ 검색

 

📌 결과 조회

코드 기능
fetch() 리스트 조회, 데이터 없으면 빈 리스트 반환
fetchOne() 단 건 조회
fetchFirst()  처음 한 건 조회
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();

📌 정렬

  • 오름차순 : ASC
  • 내림차순 : DESC
List<Member> result = queryFactory
            .selectFrom(member)
            .where(member.age.eq(100))
            .orderBy(member.age.desc(), member.username.asc().nullsLast())
            .fetch();
  • nullsLast()
    • null 값을 정렬 결과 마지막에 위치시킨다.
  • nullsFirst()
    • null 값을 정렬 결과의 처음에 위치시킨다.

📌 페이징

@Test
 public void paging1() {
 	List<Member> result = queryFactory
            	.selectFrom(member)
            	.orderBy(member.username.desc())
            	.offset(1) //0부터 시작(zero index)
            	.limit(2) //최대 2건 조회
            	.fetch();
 	assertThat(result.size()).isEqualTo(2);
 }

📌 집합

코드 기능
member.count() 회원 수
member.age.sum() 나이 합
member.age.avg() 평균 나이
member.age.max() 최대 나이
member.age.min() 최소 나이
 @Test
 public void aggregation() throws Exception {
 	List<Tuple> result = queryFactory
            	.select(member.count(),
                    	member.age.sum(),
                    	member.age.avg(),
                    	member.age.max(),
                    	member.age.min())
            	.from(member)
            	.fetch();
 	Tuple tuple = result.get(0);
 	assertThat(tuple.get(member.count())).isEqualTo(4);
 	assertThat(tuple.get(member.age.sum())).isEqualTo(100);
 	assertThat(tuple.get(member.age.avg())).isEqualTo(25);
 	assertThat(tuple.get(member.age.max())).isEqualTo(40);
 	assertThat(tuple.get(member.age.min())).isEqualTo(10);
 }

📌 조인

코드 기능
join(), innerJoin() 내부조인
leftJoin(0 left 외부조인
rightJoin() right 외부조인
 @Test
 public void join() throws Exception {
 	QMember member = QMember.member;
 	QTeam team = QTeam.team;
 	List<Member> result = queryFactory
            	.selectFrom(member)
            	.join(member.team, team)
            	.where(team.name.eq("teamA"))
            	.fetch();
 	assertThat(result)
            	.extracting("username")
            	.containsExactly("member1", "member2");
 }

📌세타 조인

 @Test
 public void theta_join() throws Exception {
    	em.persist(new Member("teamA"));
    	em.persist(new Member("teamB"));
 	List<Member> result = queryFactory
            	.select(member)
            	.from(member, team)
            	.where(member.username.eq(team.name))
            	.fetch();
	 assertThat(result)
            	.extracting("username")
            	.containsExactly("teamA", "teamB");
 }

📌조인 대상 필터링 - On절

  • On절은 조인 대상을 필터링해서 지정할 수 있다.
 @Test
 public void join_on_filtering() throws Exception {
 	List<Tuple> result = queryFactory
            	.select(member, team)
            	.from(member)
            	.leftJoin(member.team, team).on(team.name.eq("teamA"))
            	.fetch();
 	for (Tuple tuple : result) {
 		System.out.println("tuple = " + tuple);
        }
 }

📌 페치 조인

  • 페치조인은 SQL에서 제공하는 기능이 아니다. SQL 조인을 활용하여 연관된 엔티티를 SQL 한번에 조회하는 기능이다. 주로 최적화에 사용된다.
 @Test
 public void fetchJoinUse() throws Exception {
    	em.flush();
    	em.clear();
 	Member findMember = queryFactory
            	.selectFrom(member)
            	.join(member.team, team).fetchJoin()
            	.where(member.username.eq("member1"))
            	.fetchOne();
 	boolean loaded = emf.getPersistenceUnitUtil().isLoaded(findMember.getTeam());
 	assertThat(loaded).as("페치 조인 적용").isTrue();
 }
  • 사용 방법은 join() 뒤에 fetchJoin()을 추가하면 된다. 

📌서브쿼리

  • 서브 쿼리는 SQL에서 사용하는 다중 쿼리 문이다. 
  • 사용 방식만 기억해두자 
 @Test
 public void subQuery() throws Exception {
	QMember memberSub = new QMember("memberSub");
 	List<Member> result = queryFactory
            	.selectFrom(member)
            	.where(member.age.eq(
 				JPAExpressions
                            	.select(memberSub.age.max())
                            	.from(memberSub)
            	))
            	.fetch();
 	assertThat(result).extracting("age").containsExactly(40);
 }

 

📌Case 문

  • 특정 수치에 대해 조건을 걸 수 있다.
 List<String> result = queryFactory
        .select(new CaseBuilder()
                .when(member.age.between(0, 20)).then("0~20살")
                .when(member.age.between(21, 30)).then("21~30살")
                .otherwise("기타"))
        .from(member)
        .fetch();

 

'Spring > QueryDSL' 카테고리의 다른 글

[Spring]QueryDSL 중급 문법  (0) 2024.07.29
[Spring]QueryDSL에 대해 알아보자!  (0) 2024.07.28