join fetch는 SQL에서 제공하는 기능은 아니다.
SQL의 조인을 활용하여 여러 엔티티를 한번에 가져오는 쿼리를 만들어 주는 기능이다.
https://qwefdg3.tistory.com/782
여기 참고
먼저 join fetch 안했을 때
@Autowired
EntityManagerFactory emf;
@Test
public void fetchJoinNo(){
em.flush();
em.clear();
Member member = query.selectFrom(m).where(m.username.eq("member1")).fetchOne();
boolean loaded = emf.getPersistenceUnitUtil().isLoaded(member.getTeam());
assertThat(loaded).as("join fetch 미적용").isFalse();
}
emf 저거는
https://qwefdg3.tistory.com/750
여기 참조. 그러니까 EntityManagerFactory라고 해서 EntityManager 만들어 주는 건데, 저거 기능 중에 영속성 유닛 유틸.isLoaded. 말 그대로 영속성 유닛이 로드 되었는지, 묻는거임.
구체적으로는 값이 다 불러와 졌는지.(LAZY 로딩 지연처리로 프록시로 씌우고 값은 아직 안 불러온 상태일 수도 있으니까.)
당연히 LAZY로딩 아니고 그래서 프록시도 아니고 그냥 불러온 거면 true임.
저거 보면 em.flush(), em.clear() 하는데, 이 테스트 클래스의 @BeforeEach에 영속성 컨텍스트에 데이터 집어넣고 시작하기 때문에, 트랜잭션 겹치면 영속성 컨텍스트 비워있는 상태가 아니라 데이터 가져올 때 영속성 컨텍스트에 있는 걸 가져올 까봐 비워놓고 시작.
보면 그냥 값 가져오는거임. where 해서 username이 member1 인 것만.
team은 LAZY 로딩 상태에다 건드리지 않았으니 당연히 isLoaded는 false임.
@Test
public void fetchJoin(){
em.flush();
em.clear();
// select m, t from m join fetch t where m.username = 'member1'
Member member = query.selectFrom(m).join(m.team, t).fetchJoin().where(m.username.eq("member1")).fetchOne();
boolean loaded = emf.getPersistenceUnitUtil().isLoaded(member.getTeam());
assertThat(loaded).as("join fetch 적용").isTrue();
}
다음은 join fetch 했을 때.
뭐 똑같은데, join(m.team, t) 다음에 .fetchJoin()
저렇게 하면 join fetch하는 쿼리로 나감.
나는 처음에 그냥 fetchJoin(m.team, t) 이런 식으로 하면 안되나 했는데,
join fetch가 jpql에만 있는 특별한 기능이라 join과 fetch를 분리해서 보도록 저렇게 만든 듯 함.
여튼
selectFrom(m).join(m.team, t).fetchJoin().fetch();
selectFrom(가져올것의별칭).join(가져올것의조인할거랑연결할것, 조인할대상).fetchJoin().fetch();
당연히 테스트는 join fetch로 바로 가져와서 데이터가 로드 되었으므로 통과 했음.
'스프링데이터 + JPA > QueryDSL' 카테고리의 다른 글
18. CASE 문 (0) | 2023.11.30 |
---|---|
17. 서브 쿼리 (0) | 2023.11.30 |
15. join on (0) | 2023.11.29 |
14. join (0) | 2023.11.29 |
13. 그룹 (0) | 2023.11.29 |