JPA의 JPQL 또는 QueryDSL에서 연관된 엔티티를 한 번의 SQL 조회로 함께 가져오는 방법.
- SQL의
Join과 동일한 코드OneToMany관계에서 기본적으로
지연 로딩(Lazy Loading)이 적용된 연관 엔티티들은 처음에는 조회되지 않고, 실제 사용할 때 추가적인 N+1 문제를 발생시킴
이를 해결하기 위해 페치 조인(fetch join) 을 사용하면 한 번의 SQL 쿼리로 필요한 데이터를 모두 가져올 수 있음.
fetchJoin은 DB에서 table이 나누어져 있어 DB에서 JOIN을 할 수 있으면 가능하다. 직접참조(@ManyToOne / @ElementCollection) 일 때만 사용하고 간접참조일 때는 Join자체를 하지 않는다.
public List<Programmer> findAll(
List<Field> fieldNames,
Integer personalHistory,
Pageable pageable
) {
return jpaQueryFactory
.selectFrom(programmer)
.leftJoin(programmer.fieldName, QField.field).fetchJoin() // fetchJoin 추가
.where(
fieldNameCriteria(fieldNames),
personalHistoryCriteria(personalHistory)
)
.orderBy(programmer.likeCount.desc())
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
}
이런식으로 fetchJoin을 하게 되면 N+1문제를 해결할 수 있는 가장 큰 해결방법이다.
구인구직 서비스같은 경우에는 전체 조회할 때 개발자의 분야까지 보여줘야하기 때문에 개발자와 개발자 분야에 대해 join도 해야하고, 데이터가 너무 많아짐을 방지해 페이징도 해야한다.
이게 왜 문제가 되냐면 페이징을 나중에하면 너무 많은 데이터를 join을 하게 되니까 페이징을 먼저 하고 싶었다. 그런 방법이 없을까,,ㅜ