Spring/QueryDSL

조인 - 페치 조인

느리지만 꾸준하게 2022. 4. 20. 03:18
  • 페치 조인은 SQL에서 제공하는 기능은 아니고 SQL조인 활용해서 연관된 엔티티 SQL 한번에 조회하는 기능이다.
  • 주로 성능 최적화에 사용하는 방법

 

Member에 team은 lazy로 세팅

// 연관관계(team과의 연관관계)의 주인은 여기 => JPA 완벽히 숙지
// ManyToOne은 항상 fetch를 lazy로
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "team_id")
private Team team;

 

fetchjoin test를 돌려보면

@Test
    public void fetchJoinNo() {
        // 데이터를 깔끔하게 지우자.
        // fetchjoin 테스트 할 때는 영속성 컨텍스트에 남아있는 거 안지워주면 결과를 제대로 못본다.
        // 영속성 컨텍스트에 있는거 db에 반영하고 깔끔하게 날린다음에 시작. 
        em.flush();
        em.clear();

        Member findMember = queryFactory
                .selectFrom(member)
                .where(member.username.eq("member1"))
                .fetchOne();

        // db에서 조회할 때 member만 조회되고 team은 조회가 안됨

    }

실행결과를 보면 member만 조회한다.

// member만 조회한다.

/* select
        member1 
    from
        Member member1 
    where
        member1.username = ?1 */ select
            member0_.id as id1_1_,
            member0_.age as age2_1_,
            member0_.team_id as team_id4_1_,
            member0_.username as username3_1_ 
        from
            member member0_ 
        where
            member0_.username=?

 

 

 

 

 

테스트 증명할 때는 @PersistenceUnit을 써보자.

@PersistenceUnit
EntityManagerFactory emf;

@Test
public void fetchJoinNo() {
    // 데이터를 깔끔하게 지우자.
    // fetchjoin 테스트 할 때는 영속성 컨텍스트에 남아있는 거 안지워주면 결과를 제대로 못본다.
    // 영속성 컨텍스트에 있는거 db에 반영하고 깔끔하게 날린다음에 시작. 
    em.flush();
    em.clear();

    Member findMember = queryFactory
            .selectFrom(member)
            .where(member.username.eq("member1"))
            .fetchOne();


    // 로딩된 엔티티인지 로딩 안된 즉 초기화가 안된 엔티티인지 가르쳐줌
    // false가 당연히 나올 것이다.
    boolean loaded = emf.getPersistenceUnitUtil().isLoaded(findMember.getTeam());
    assertThat(loaded).as("패치 조인 미적용").isFalse();


}

 

 

 

 

 

// 패치조인 적용을 해주면
@Test
public void fetchJoinUse() {
    // 데이터를 깔끔하게 지우자.
    // fetchjoin 테스트 할 때는 영속성 컨텍스트에 남아있는 거 안지워주면 결과를 제대로 못본다.
    // 영속성 컨텍스트에 있는거 db에 반영하고 깔끔하게 날린다음에 시작.
    em.flush();
    em.clear();

    Member findMember = queryFactory
            // member를 조회하는데 연관된 team을 다 끌어올려면
            .selectFrom(member)
            .join(member.team, team).fetchJoin()
            .where(member.username.eq("member1"))
            .fetchOne();


    // 로딩된 엔티티인지 로딩 안된 즉 초기화가 안된 엔티티인지 가르쳐줌
    // false가 당연히 나올 것이다.
    boolean loaded = emf.getPersistenceUnitUtil().isLoaded(findMember.getTeam());
    assertThat(loaded).as("패치 조인 적용").isTrue();


}
// JPQL 은 아래와 같고

/* select
        member1 
    from
        Member member1   
    inner join
        fetch member1.team as team 
    where
        member1.username = ?1
        
        
// SQL은 member와 team 필드 다 조회해온다.
select
            member0_.id as id1_1_0_,
            team1_.id as id1_2_1_,
            member0_.age as age2_1_0_,
            member0_.team_id as team_id4_1_0_,
            member0_.username as username3_1_0_,
            team1_.name as name2_2_1_ 
        from
            member member0_ 
        inner join
            team team1_ 
                on member0_.team_id=team1_.id 
        where
            member0_.username=?

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<출처 김영한: 실전! Querydsl >

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

 

실전! Querydsl - 인프런 | 강의

Querydsl의 기초부터 실무 활용까지, 한번에 해결해보세요!, - 강의 소개 | 인프런...

www.inflearn.com

 

 

 

 

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

Case 문 & 상수, 문자 더하기  (0) 2022.04.20
서브 쿼리  (0) 2022.04.20
조인 - on 절  (0) 2022.04.20
조인 - 기본 조인  (0) 2022.04.20
집합  (0) 2022.04.20