ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 04. Querydsl Join
    BackEnd/Querydsl 2021. 7. 18. 17:19
    반응형

    1. 기본 조인


    @Test
    public void join() throws Exception {
        List<Member> result = queryFactory
                      .selectFrom(member)
                      // join(조인 대상, 별칭으로 사용할 Q타입)
                      /**
                      * join() , innerJoin() : 내부 조인(inner join)
                      * leftJoin() : left 외부 조인(left outer join)
                      * rightJoin() : rigth 외부 조인(rigth outer join
                      */
                      .join(member.team, team)
                      .where(team.name.eq("teamA"))
                      .fetch();

        assertThat(result)
                      .extracting("username")
                      .containsExactly("member1", "member1");
    }


    2. 세타 조인


    /**
    * 세타 조인(연관관계가 없는 필드로 조인)
    * 회원의 이름이 팀 이름과 같은 회원 조회
    * 외부조인(OUTER) 불가능
    */
    @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");
    }


    3. On절


     /**
    * 1. 조인 대상 필터링
    * ) 회원과 팀을 조인하면서, 팀 이름이 teamA인 팀만 조인, 회원은 모두 조회
    * JPQL: SELECT m, t FROM Member m LEFT JOIN m.team t on t.name = 'teamA'
    * SQL: SELECT m.*, t.* FROM Member m LEFT JOIN Team t ON m.TEAM_ID=t.id and
    t.name='teamA'
    */
    @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);
        }
    }

    /**
    * 2. 연관관계 없는 엔티티 외부 조인
    * ) 회원의 이름과 팀의 이름이 같은 대상 외부 조인
    * JPQL: SELECT m, t FROM Member m LEFT JOIN Team t on m.username = t.name
    * SQL: SELECT m.*, t.* FROM Member m LEFT JOIN Team t ON m.username = t.name
    */
    @Test
    public void join_on_no_relation() throws Exception {
        em.persist(new Member("teamA"));
        em.persist(new Member("teamB"));

        List<Tuple> result = queryFactory
                      .select(member, team)
                      .from(member)
                      .leftJoin(team).on(member.username.eq(team.name))
                      .fetch();

        for (Tuple tuple : result) {
            System.out.println("t=" + tuple);
        }
    }


    4. 페치 조인


    @PersistenceUnit
    EntityManagerFactory emf;

     

    @Test
    public void fetchJoin() throws Exception {
        em.flush();
        em.clear();

        /**
        * Memeber EntityTeam
        * @ManyToOne(fetch = FetchType.LAZY)
        * @JoinColumn(name = "team_id")
        * private Team team;
        * > FetchType.LAZY(지연로딩)이기에 일반 조인할 경우 로딩하지 않는다.
        */
        Member result = queryFactory
                      .selectFrom(member)
                      .join(member.team, team)
                      .where(member.username.eq("member1"))
                      .fetchFirst();

        boolean loaded =
            emf.getPersistenceUnitUtil().isLoaded(result.getTeam());
        System.out.println("loaded = " + loaded); // false

        /**
        * fetch join : SQL 조인을 활용해서 연관된 엔티티를 한번에 조회하는 기능 (즉시로딩)
        * > 성능 최적화에 사용
        * 사용방법) join(), leftJoin() 등 조인 기능 뒤에 fetchJoin() 추가
        */
        Member fetchResult = queryFactory
                      .selectFrom(member)
                      .join(member.team, team).fetchJoin()
                      .where(member.username.eq("member1"))
                      .fetchFirst();

        System.out.println("findMember.getTeam() = " + fetchResult.getTeam());

        boolean fetchLoaded =
            emf.getPersistenceUnitUtil().isLoaded(result.getTeam());
        System.out.println("loaded = " + fetchLoaded); // true
    }


     

    반응형

    'BackEnd > Querydsl' 카테고리의 다른 글

    06. Querydsl Case  (0) 2021.07.27
    05. Querydsl Subquery  (0) 2021.07.25
    03. Querydsl 기본 문법  (0) 2021.07.17
    01. Querydsl 레퍼런스 문서  (0) 2021.07.11
    02. Querydsl 설정  (0) 2021.07.11

    댓글

Designed by Tistory.