Java/JPA

JPQL - fetch join(패치조인) - 적극활용 권장

amungstudy 2023. 11. 21. 17:09

이거 모르면 실 무 못 함. 데이터 여러개 조회할 때 좋음

 

JPQL에서 성능 최적화를 위해 제공함.
페치 조인은 객체 그래프를 SQL한번에 조회한다.(즉시로딩)

명시적으로 즉시로딩 하는거라고 볼 수 있음, 프록시 아니고 진짜데이터 들고옴. 주로 조회성 기능할때 사용

        String jpql = "select m from Member m join fetch m.team";
        List<Member> members = em.createQuery(jpql,Member.class)
                .getResultList();
        for (Member member : members) {
            System.out.println("username = " + member.getUsername());
        }

페치 조인과 DISTINCT : 일대 다 조인 시 데이터 뻥튀기 막기

JPQL에서 DISTINCT는

  1. sql에 distinct를 추가함
  2. 애플리케이션에서 엔티티 중복을 제거함
  3. 하이버네이트6부터는 자동으로 중복제거 적용됨

사용예시

String query = "select distinct t From Team t join fetch t.members";

List<Team> result = em.createQuery(query, Team.class)
                .getResultList();

for (Team team : result) {
    System.out.println("team = " + team.getName() + " members = " + team.getMembers().size());
    for(Member member : team.getMembers()){
        System.out.println("->member = " + member);
    }
}

페치조인의 한계

  • 페치 조인 대상에는 별칭을 줄 수 없다.
  • 둘 이상의 컬렉션은 페치조인 할 수 없다.
  • 컬렉션을 페치조인하면 페이징API를 사용할 수 없다. 따라서 컬럭션은 페이징처리 시 페치조인이 안된다.이때 해결방안으로 batch size 조절이 있다.(컬렉션 페이징 처리 시 즉시로딩하는 )

글로벌셋팅을해준다(persistence.xml에 해당 값 입력) value값은 1000이하를 권장함.(실무에서 자주 씀)

<property name="hibernate.default_batch_fetch_size" value="100" />

만일 아래 코드를 작성한 경우

String query = "select t From Team t";

List<Team> result = em.createQuery(query, Team.class)
                .setFirstResult(0)
                .setMaxResults(2)
                .getResultList();

System.out.println("result = " + result.size());

for (Team team : result) {
    System.out.println("team = " + team.getName() + " members = " + team.getMembers().size());
    for(Member member : team.getMembers()){
        System.out.println("->member = " + member);
    }

batch size 세팅안해주면 team마다 select member쿼리가 나가는데, (쿼리 여러개 나오면 성능 안나옴)

적용하면 쿼리가 테이블 수 만큼 최적화된다.


복잡한 통계자료 만들때는 여러테이블 조인해서 엔티티가 가진 모양이 아닌 전혀 다른 결과를 내야 하는 경우

페치조인보다 일반조인을 사용해서 필요한 데이터만 조회해서 DTO로 반환하는 것이 효과적임.