Back-End/JPA

JPQL 과 QueryDSL 문법 비교 및 Q-Type활용

LightSource 2023. 10. 27. 08:53

https://www.inflearn.com/course/querydsl-%EC%8B%A4%EC%A0%84/dashboard

 

실전! Querydsl - 인프런 | 강의

Querydsl의 기초부터 실무 활용까지, 한번에 해결해보세요!, 복잡한 쿼리, 동적 쿼리는 이제 안녕! Querydsl로 자바 백엔드 기술을 단단하게. 🚩 본 강의는 로드맵 과정입니다. 본 강의는 자바 백엔

www.inflearn.com

 

테스트 초기 설정

@SpringBootTest
@Transactional
public class QuerydslBasicTest {

    @Autowired
    EntityManager em;

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

JPQL vs QueryDSL

JPQL

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

QueryDSL

      @Test
    public void startQuerydsl() {
        JPAQueryFactory queryFactory = new JPAQueryFactory(em);
        QMember m = new QMember("m");

        Member findMember = queryFactory.select(m)
                                     .from(m)
                                     .from(m)
                                     .where(m.username.eq("member1")) //파라미터 바인딩 처리
                                     .fetchOne();

        assertThat(findMember.getUsername()).isEqualTo("member1");
    }
  • EntityManagerJPAQueryFactory를 생성 시키고, 해당 객체로 쿼리를 작성한다.

JPAQueryFactory를 필드로 사용하는 경우?

@SpringBootTest
@Transactional
public class QuerydslBasicTest {

    @Autowired
    EntityManager em;

    JPAQueryFactory queryFactory;  //JPAQueryFactory를 필드로 사용

    @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);
    }
}
  • JPAQueryFactory를 생성할 때 제공하는 EntityManager는 여러 쓰레드에서 동시에 같은 EntityManager에 접근해도, 트랜잭션 마다 별도의 영속성 컨텍스트를 제공하는 기능을 스프링 프레임워크에서 제공하기 때문에, 동시성 문제는 걱정하지 않아도 된다.

기본 Q-Type활용

Q클래스 인스턴스를 사용하는 2가지 방법

QMember qMember = new QMember("m"); //별칭 직접 지정 -> 같은 테이블을 조인하는 경우에만 사용
QMember qMember = QMember.member; //기본 인스턴스 사용

기본 인스턴스를 static import와 함께 사용

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

@Test
public void startQuerydsl() {
   Member findMember = queryFactory.select(member)
                                   .from(member)
                                   .from(member)
                                   .where(member.username.eq("member1")) //파라미터 바인딩 처리
                                   .fetchOne();

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

→ 코드가 훨씬 깔끔해진다.

반응형