페치조인은 SQL에서 제공하는 기능은 아니다!
SQL 조인을 활용해서 연관된 엔티티를 SQL 1번으로 조회하는 기능이다.
주로 성능 최적화에 사용한다!
여러번의 쿼리가 날라갈 것을 한번의 쿼리로 데이터를 한꺼번에 많이 가져온다.
join(),leftJoin()등 조인 기능 뒤에fetchJoin()을 추가
@PersistenceUnit
EntityManagerFactory emf;
@Test
public void fetchJoinNo() throws Exception {
// 영속성 컨텍스트 깨끗하게 비움
em.flush();
em.clear();
// 멤버 1명 조회
// member(N) - team(1) : LAZY -> member 조회시 team은 프록시
Member findMember = queryFactory
.selectFrom(member)
.where(member.username.eq("member1"))
.fetchOne();
boolean loaded = emf.getPersistenceUnitUtil().isLoaded(findMember.getTeam()); // emf.getPersistenceUnitUtil().isLoaded(객체)) : 해당 객체가 초기화되었는지 여부
assertThat(loaded).as("페치 조인 미적용").isFalse();
}

member 관련 select 쿼리 1방 나간다.
/**
* 페치 조인 - 적용
*/
@Test
public void fetchJoinUse() throws Exception {
// 영속성 컨텍스트 깨끗하게 비움
em.flush();
em.clear();
// 멤버 1명 조회
// member(N) - team(1) : LAZY -> member 조회시 team은 프록시
Member findMember = queryFactory
.selectFrom(member)
.join(member.team, team).fetchJoin() // join 뒤에 .fetchJoin() : member 조회시 연관된 Team까지 한방쿼리로 가져옴
.where(member.username.eq("member1"))
.fetchOne();
boolean loaded = emf.getPersistenceUnitUtil().isLoaded(findMember.getTeam()); // emf.getPersistenceUnitUtil().isLoaded(객체)) : 해당 객체가 초기화되었는지 여부
assertThat(loaded).as("페치 조인 적용").isTrue();
}

JPQL 보면 inner join fetch member1.team as team으로 team까지 땡겨온다.
SQL 보면 select 절에 team.team_id, team.name 조회해온다.
페치 조인은 실무에서 정말 많이 사용한다고 하셨다!