[Querydsl] 기본 문법(1) - JPQL과 차이, 조회

2024. 8. 6. 23:35· 인프런 김영한 강의 정리/실전! Querydsl
목차
  1. 1. JPQL vs Querydsl
  2. 3. 검색 문법
  3. 4. 결과 조회
728x90

 

 

1. JPQL vs Querydsl

✅JPQL 조회, Querydsl 조회 비교

package study.querydsl;

import com.querydsl.jpa.impl.JPAQueryFactory;
import jakarta.persistence.EntityManager;
import jakarta.transaction.Transactional;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import study.querydsl.entity.Member;
import study.querydsl.entity.Team;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;
import static study.querydsl.entity.QMember.member;

@SpringBootTest
@Transactional
public class QuerydslBasicTest {

    @Autowired
    EntityManager em;
    JPAQueryFactory queryFactory; //필드로 만들어도됨

    @BeforeEach
    public void before(){
        queryFactory = new JPAQueryFactory(em);
        Team teamA = new Team("teamA");
        Team teamB = new Team("teamB");
        em.persist(teamA);
        em.persist(teamB);
        Member member1 = new Member("member1", 10, teamA);
        Member member2 = new Member("member2", 20, teamA);
        Member member3 = new Member("member3", 30, teamB);
        Member member4 = new Member("member4", 40, teamB);
        em.persist(member1);
        em.persist(member2);
        em.persist(member3);
        em.persist(member4);
    }

    @Test
    public void startJPQL(){
        //member1 찾기
        String qlString =
                "select m from Member m " +
                "where m.username = :username"; //런타임 시점에 오류확인
        Member findMember = em.createQuery(qlString, Member.class)
                .setParameter("username", "member1") //파라미터바인딩 직접 입력
                .getSingleResult();

        assertThat(findMember.getUsername()).isEqualTo("member1");
    }

    @Test
    public void startQuerydsl(){
        Member findMember = queryFactory //컴파일 시점에 오류확인
                .select(member)
                .from(member)
                .where(member.username.eq("member1")) //파라미터바인딩 자동
                .fetchOne(); //단일레코드 조회

        assertThat(findMember.getUsername()).isEqualTo("member1");
    }

}

- Querydsl은 EntityManager로 JPAQueryFactory 생성해줘야한다.

JPAQueryFactory는 필드로 빼줘도 된다.

 

 

✔️JPQL과 Querydsl 특징

  JPQL Querydsl
쿼리 작성 문자열 Java 코드
오류 확인 시점 런타임(실행 시점) 컴파일(코드 작성 시점)
파라미터 바인딩 수동 자동

 

 

2. Q-Type 활용

Querydsl을 사용하는 프로젝트에서 엔티티 클래스를 만들면 자동으로 Q-Type 클래스를 생성한다.

Querydsl로 쿼리를 작성할 때는 Q-Type 클래스를 사용한다.

QMember qMember = new QMember("m"); //별칭 직접 지정
QMember qMember = QMember.member; //기본 인스턴스 사용

 

Q-Type 인스턴스를 통해 쿼리를 작성해야하니 인스턴스를 생성해줘야한다.

위 코드처럼 직접 써도 되지만 자동 생성된 Q클래스에 이미 member 인스턴스가 만들어져있다.

 

import static study.querydsl.entity.QMember.*;

 

기본 인스턴스를 static import를 해주면 더 깔끔하게 코드를 작성할 수 있다.

💡같은 테이블을 조인해야 하는 경우가 아니면 기본 인스턴스를 사용하는 것이 좋다.

    @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가 Q클래스 인스턴스다.

 

 

 

 

3. 검색 문법

▪️ selectFrom()

select(member).from(member) 처럼 select와 from뒤에 오는 것이 같다면, selectFrom(member)로 합칠 수 있다.

 

▪️  eq()

eq()는 ' = ' 이고 

eq()로 파라미터 바인딩을 자동으로 할 수 있다.

eq()로는 null 비교를 할 수 없기 때문에 null인지 아닌지 판단할 때는 isNull(), isNotNull()을 쓴다.

 

▪️  ne()

ne()는 ' != ' 이다.  참고로, ne는 not equal의 줄임말이다.

ne()는 eq().not()으로 쓸 수도 있다.

 

▪️  goe()

'>='  greater or equal의 줄임말이다. 

member.age.goe(30) 는 age >= 30 를 의미.

 

▪️  gt()

'>' greater than의 줄임말이다. '크다'

member.age.gt(30) 는 age > 30 를 의미.

 

▪️  loe()

'<=' less or equal의 줄임말이다. '작거나 같다'

member.age.loe(30) 는 age <= 30 를 의미.

 

▪️  lt()

'<' less than의 줄임말이다. '작다'

member.age.lt(30) 는 age < 30 를 의미.

 

▪️  between(   ,   )

between(10,30)은 10 ≤ 값 ≤ 30 을 의미한다.

10과 30도 포함된다는 것을 헷갈리지 말자.

 

▪️  조건 추가 and

    @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");
    }

    @Test
    public void searchAndParam(){
        Member findMember = queryFactory
                .selectFrom(member)
                .where(member.username.eq("member1"),
                        member.age.eq(10))
                .fetchOne();

        assertThat(findMember.getUsername()).isEqualTo("member1");
    }

첫번째 테스트처럼 where뒤에 and()로 조건을 추가해줄 수 있고, 두번째 테스트처럼 and조건을 where()에 쉼표로 이어서 조건을 추가해줄 수 있다.

 

▪️  like()

기존 SQL 문법에 있는 like처럼 사용한다.

like("member%")는 member로 시작하는 문자열을 찾는 것이다.

 

▪️  contains()

like("%member%")와 같다. 문자열 위치 상관없이 포함하는 것을 찾는 것이다.

 

▪️  startsWith()

like("member%")와 같다. member로 시작하는 문자열을 찾는다.

 

 

4. 결과 조회

        List<Member> fetch = queryFactory
                .selectFrom(member)
                .fetch();

        Member fetchOne = queryFactory
                .selectFrom(member)
                .fetchOne();

        Member fetchFirst = queryFactory
                .selectFrom(member)
                .fetchFirst();

select, from, where등을 사용해서 검색 쿼리를 다 작성하고 리스트로 결과를 받을 때 결과조회 메서드를 사용한다.

안붙이면 타입이 JPAQuery<Member>가 된다.

 

▪️  fetch()

리스트 조회를 할 수 있고 데이터가 없으면 빈 리스트를 반환한다.

 

▪️   fetchOne()

단 건 조회가 확실할 때, fetchOne()을 사용한다.

결과가 둘 이상이면 NonUniqueResultException 예외가 발생한다.

 

▪️   fetchFirst()

첫번째 결과 행을 가져온다.

limit(1).fetchOne()과 같다. 

limit()은 쿼리 결과의 최대 행의 수를 제한하는 메서드다.

 


🤔강의를 보면 fetchResults()와 fetchCount()가 나오는데, 이 두 메서드는 향후 지원되지 않을 메서드라서 

다른 쿼리로 대체해야한다.

김영한님 강의 수강자는 강의자료 섹션8을 보면 된다. 여기에 최신 버전에 맞춘 설명이 나온다.

fetchResult(), fetchCount()를 대체하는 법은 다음 포스팅에서 다룰 예정이다.

 

 

 

 

 

 

 

728x90

'인프런 김영한 강의 정리 > 실전! Querydsl' 카테고리의 다른 글

[Querydsl] 기본 문법(4) - Case문  (0) 2024.08.09
[Querydsl]기본 문법(3) - 서브 쿼리  (0) 2024.08.09
[Querydsl] 기본 문법(2) - 조인  (0) 2024.08.08
[Querydsl] fetchResults(), fetchCount() 대체하기  (0) 2024.08.07
프로젝트 환경설정 (SpringBoot 3.x 버전), Querydsl 설정  (0) 2024.07.27
  1. 1. JPQL vs Querydsl
  2. 3. 검색 문법
  3. 4. 결과 조회
'인프런 김영한 강의 정리/실전! Querydsl' 카테고리의 다른 글
  • [Querydsl]기본 문법(3) - 서브 쿼리
  • [Querydsl] 기본 문법(2) - 조인
  • [Querydsl] fetchResults(), fetchCount() 대체하기
  • 프로젝트 환경설정 (SpringBoot 3.x 버전), Querydsl 설정
백엔드 개발자 - 젤리곰
백엔드 개발자 - 젤리곰
오늘도 배움이 있는 하루가 되길 바라는 개발자
백엔드 개발자 - 젤리곰
backend-gummyBear
백엔드 개발자 - 젤리곰
전체
오늘
어제
  • 분류 전체보기 (144)
    • 인프런 김영한 강의 정리 (60)
      • 스프링 핵심원리 기본편 (12)
      • 모든 개발자를 위한 HTTP 웹 기본 지식 (10)
      • 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 (3)
      • 자바 ORM 표준 JPA 프로그래밍 기본편 (28)
      • 실전! Querydsl (6)
    • Spring (2)
    • 프로젝트일지 (6)
    • 프로그래밍 언어 (20)
      • Java (17)
      • JavaScript (3)
      • Python (0)
    • 데이터베이스 (4)
      • Oracle (2)
      • ORM (1)
      • SQL 튜닝 (1)
    • 형상관리 (1)
      • Git (0)
    • 알고리즘&자료구조 (34)
      • Algorithm (31)
      • Data Structure (1)
    • CS지식 (4)
    • Cloud (5)
    • 일기 (7)
      • 공부 일기 (3)
      • 독서 일기 (2)
      • 마음 일기 (2)

블로그 메뉴

  • 홈
  • 태그

공지사항

인기 글

태그

  • dfs알고리즘
  • 업캐스팅
  • 커스텀annotation
  • 객체지향방법론
  • 인터페이스
  • LeetCode200번
  • 프론트엔드역사
  • ORM프레임워크
  • 인프콘
  • 프론트엔드개발자업무
  • jquery와javascript
  • 클라이언트서버통신
  • 데이터베이스정규화
  • SublimeText단축키
  • #{}와${}의차이
  • 스프링컨텍스트
  • 힙자료구조
  • 객체지향의사실과오해
  • LeetCode17번
  • 다운캐스팅

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
백엔드 개발자 - 젤리곰
[Querydsl] 기본 문법(1) - JPQL과 차이, 조회
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.