Search
Duplicate

[Spring JPA] 객체지향 쿼리 언어2 - 중급 문법

날짜
2022/04/29 06:54
상태
스프링 JPA 기본
속성 1
Spring
JAVA
JPA
담당자

경로 표현식 특징

상태 필드 (state field): 경로 탐색의 끝, 탐색 X
단일 값 연관 경로: 묵시적 내부 조인(inner join) 발생, 탐색 O
컬렉션 값 연관 경로: 묵시적 내부 조인 발생, 탐색 X
FROM 절에서 명시적 조인을 통해 별칭을 얻으면 별칭을 통해 탐색 가능
결론 : 묵시적 조인은 실무에서 쓰면 안 된다. 유지보수하기도 힘들다. 그러므로 명시적 조인으로 항상 작성해야 된다.!

상태 필드 경로 탐색

JPQL: select m.username, m.age from Member m
SQL: select m.username, m.age from Member m
단일 값 연관 경로 탐색
JPQL:
select o.member from Order o
SQL
복사
SQL:
select m.* from Orders o inner join Member m on o.member_id = m.id
SQL
복사
묵시적 조인은 망할 가능성이 강하다.

명시적 조인, 묵시적 조인

명시적 조인: join 키워드 직접 사용
select m from Member m join m.team t
묵시적 조인: 경로 표현식에 의해 묵시적으로 SQL 조인 발생 (내부 조인만 가능)
select m.team from Member m

경로 표현식 - 예제

select o.member.team from Order o : 성공
select t.members from Team : 성공
select. tmembers.username from Team t : 실패
select m.username from Team t join t.members m : 성공

경로 탐색을 사용한 묵시적 조인 시 주의사항

항상 내부 조인
컬렉션은 경로 탐색의 끝, 명시적 조인을 통해 별칭을 얻어야 함
경로 탐색은 주로 SELECT, WHERE 절에서 사용하지만 묵시적 조인으로 인해 SQL의 FROM (JOIN) 절에 영향을 줌

실무 조언

가급적 묵시적 조인 대신에 명시적 조인 사용
조인은 sql 튜닝에 중요 포인트
묵시적 조인은 조인이 일어나는 상황을 하순에 파악하기 어려움

페치 조인(fetch join)

SQL 조인 종류가 아니다.
JPQL에서 성능 최적화를 위해 제공하는 기능
연관된 엔티티나 컬렉션을 SQL 한 번에 함께 조회하는 기능
join fetch 명령어 사용
페치 조인 ::= [ LEFT [OUTHER] | INNER] JOIN FETCH 조인 경로
String jpql = "select m from Member m join fetch m.team"; List<Member> members = em.createQuery(jpql, Member.class) .getResultList(); for (Member member : members) { //페치 조인으로 회원과 팀을 함께 조회해서 지연 로딩X System.out.println("username = " + member.getUsername() + ", " + "teamName = " + member.getTeam().name()); }
Java
복사

컬렉션 페치 조인

일대다 관계, 컬렉션 페치 조인
[JPQL]
select t from Team join fetch t.members where t.name = '팀A'
Java
복사
[SQL]
SELECT T.*, M.* FROM TEAM T INNER JOIN MEMBER M ON T.ID=T.TEAM_ID WHERE T.NAME = '팀A'
Java
복사
예제
Code
결과 값이 중복으로 나온다.

페치 조인과 DISTINCT

JPQL의 DISTINCT 2가지 기능 제공
1. SQL에 DISTINCT를 추가
2. 애플리케이션에 엔티티 중복 제거

페치 조인과 DISTINCT 설명

SQL에 DISTINCT를 추가하지만 데이터가 다르므로 SQL 결과에서 종복 제거 실패
SQL의 DISTINCT는 결과값이 완전히 일치해야지 제거된다.!
현재 소스 코드에서는 애플리케이션에서 올라올 때 컬렉션 안에 값이 중복이라 JPA가 제거해주는 것이다.

페치 조인과 일반 조인의 차이

일반 조인 실행 시 연관된 엔티티를 함께 조회하지 않음
[JPQL]
select t from Team t join t.members m where t.name = '팀A'
Java
복사
[SQL]
SELECT T.* FROM TEAM T INNER JOIN MEMBER M ON T.ID = M.TEAM_ID WHERE T.NAME = '팀A'
Java
복사

페치 조인

페치 조인을 사용할 때만 연관된 엔티티도 함께 조회
페치 조인은 객체 그래프를 SQL 한 번에 조회하는 개념

페치 조인의 특징과 한계

페치 조인 대상에는 별칭을 줄 수 없다.
하이버네이트 가능, 가급적 사용 x
둘 이사의 컬렉션은 페치 조인할 수 없다.
컬렉션을 페치 조인하면 페이지 API를 사용할 수 없다.
일대일, 다대일 같은 단일 값 연관 필드들은 페치 조인해도 페이징 가능
하이버네이트 경고 로그를 남기고 메모리에서 페이지(매우 위험) 절대 쓰면 안 된다.

페치 조인의 특징과 한계

연관된 엔티티들은 SQL 한 번으로 조회 - 성능 최적화
엔티티에 직접 적용하는 글로벌 로딩 전략보다 우선함
실무에서 글로벌 로딩 전략은 모두 지연 로딩
최적화가 필요한 곳은 페치 조인 적용

페치 조인 - 정리

모든 것을 페치 조인으로 해결할 수는 없음
페치 조인은 객체 그래프를 유지할 때 사용하면 효과적
여러 테이블을 조인해서 엔티티가 가진 모양이 아닌 전혀 다른 결과를 내야 하면, 페치 조인보다는 일반 조인을 사용하고 필요한 데이터들만 조회해서 DTO로 반환하는 것이 효과적s
이 글은 인프런의
제목 : 자바 ORM 표준 JPA 프로그래밍 - 기본 편
강사 : 김영한 님의 동영상을 참조해 만들었습니다.