JPQL 에서 객체의 원하는 필드를 .을 찍어 경로를 탐색한다.
상태필드 , 단일값 연관필드, 컬렉션 값 연관 필드 3가지 방식이있다 .
상태필드는 단순히 값을 저장하기위한 필드이다 . m.username, m.age 값 타입에 대한 필드들을 말한다 .
단일값 연관필드는 @ManyToOne @OneToMany 등의 연관관계에서 대상이 단일 엔티티 일 경우를 말한다 ( ex) m.team )
컬렉션 값 연관 필드는 @OneToMany , @ManyToMany 처럼 연관관계 대상이 엔티티 컬렉션일 경우를 말한다 (ex ) m.orders )
경로 표현식 특징
-상태필드 : 경로 탐색의 끝, 탐색
-단일 값 연관 경로 : 묵시적 내부조인 발생 탐색
-컬랙션 값 연관 경로 :묵시적 내부조인 발생 ,
From 절에서 명시적 조인을 통해 별칭을 얻으면 별칭을 통해 탐색이 가능하다 .
// 상태 필드 표현
// 더 이상 객체 탐색이 불가능하다
String query = "select m.username from Member m";
List<Member> result = em.createQuery(query, Member.class)
.getResultList();
//단일값 연관 필드
//team 은 엔티티 이기 떄문에 팀에서 한번더 탐색이 가능하다 .
//m.team 에서 묵시적 내부조인이 일어나고 name을 찾을때는 상태필드기 때문에 탐색이 끝난다.
//JPQL 에서는 Join 문을 적지 않아도 연관관계에 의해 묵시적으로 조인이 일어나고 SQL에는 join문이 나가기 떄문에
// JPQL에서도 SQL 과 마찬가지로 Join문을 명시적으로 써주는 것이 좋다 .
String query1 = "select m.team.name from Member m";
List<Member> result1 = em.createQuery(query1, Member.class)
.getResultList();
//컬랙션값 연관경로
//컬렉션값 연관경로는 컬렉션에 몇번째 값을 원하는지에 대해 알수 없음으로 탐색을할 수 없다
String query2 = "select t.members from Team t";
Collection result2 = em.createQuery(query2, Collection.class)
.getResultList();
//컬랙션값 연관경로 해결 (명시적 조인 사용)
//명시적 조인을 하면 별칭을 얻을 수 있기 떄문에 탐색이 가능하다 .
String query3 = "select t.members,m.username from Team t join t.members m ";
Collection result3 = em.createQuery(query3, Collection.class)
.getResultList();
경로 탐색의 주의사항
- 항상 내부조인만 나간다 .
- 컬렉션은 경로 탐색의 끝 이거 , 원한다면 명시적 조인을 통해 별칭을 얻어 접근해야 한다 .
- 경로 탐색은 주로 select , where 절에서 사용하지만 from(join) 절에 영향을 준다 (직관적으로 알아내기 힘들다.)
* 결과적으로는 묵시적 조인을 사용하지 않는 것이 좋다 . JPQL에 join을 직접 입력하는 명시적 조인을 항상 사용하자 .
'JPA' 카테고리의 다른 글
JPA 공부 19 - JPQL . 8 Named 쿼리 (0) | 2021.06.08 |
---|---|
JPA 공부 18 - JPQL . 7 페치조인 (0) | 2021.06.07 |
JPA 공부 16 - JPQL . 4 JOIN (0) | 2021.06.06 |
JPA 공부 15 - JPQL . 3 페이징 (0) | 2021.06.06 |
JPA 공부 14 - JPQL . 2 프로젝션 (0) | 2021.06.06 |