프로젝트 git url | github.com/rtef23/JpaStudy |
필요 | 1. docker 2. docker-compose |
프로젝트 정보 | mysql : 5.7 - docker image java : 1.8 |
조인
내부 조인
- Inner Join
- [JPQL] SELECT m FROM Member m [INNER] JOIN m.team t
@Entity
public class Member {
@Id @GeneratedValue private Long id;
private String username;
private int age;
//JPQL로 실행하더라도 엔티티 클래스의 Fetch 타입에 따라서 Team을 조인하는 시점이 달라진다.
//xxxToOne 어노테이션의 기본 fetch는 EAGER이다.
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "team_id")
private Team team;
...
}
List<Member> findMembers = entityManager.createQuery("select m from Member m inner join m.team t", Member.class).getResultList();
System.out.println(findMembers);
System.out.println("#### before getTeam()");
System.out.println(findMembers.get(0).getTeam());
외부 조인
- Outer Join
- [JPQL] SELECT m FROM Member m LEFT [OUTER] JOIN m.team t
세타 조인
- 연관관계가 없는 테이블간의 조인(카테시안 곱)
- [JPQL] SELECT COUNT(m) FROM Member m, Team t WHERE m.username = t.name
List<Member> result =
entityManager.createQuery("select m from Member m ,Team t", Member.class).getResultList();
System.out.println(result);
/* team row 수 * member row 수의 결과 집합이 생성된다.(카테시안 곱)*/
ON절 활용
- 조인 대상 필터링
//회원과 팀을 조인하면서, 팀 이름이 A인 팀만 조인
//[JPQL]
SELECT m, t
FROM Member m
LEFT JOIN m.team t
ON t.name = 'A'
//[SQL]
SELECT m.*, t.*
FROM Member m
LEFT JOIN Team t
ON m.team_id = t.id
AND t.name = 'A'
- 연관관계 없는 엔티티 외부 조인 (hibernate 5.1 이후 버전부터 사용 가능)
//회원 이름과 팀의 이름이 같은 대상 외부 조인
//[JPQL]
SELECT m, t
FROM Member m
LEFT JOIN Team t
ON m.username = t.name
//[SQL]
SELECT m.*, t.*
FROM Member m
LEFT JOIN Team t
ON m.username = t.name
서브쿼리
- 나이가 평균보다 많은 회원
//[JPQL]
SELECT m
FROM Member m
WHERE m.age > (SELECT AVG(m2.age)
FROM Member m2)
- 한 건이라도 주문한 고객
//[JPQL]
SELECT m
FROM Member m
WHERE (SELECT COUNT(o)
FROM Order o
WHERE m = o.member) > 0
지원 함수
- [NOT] EXISTS : 서브쿼리에 결과가 존재하면 참
//[JPQL]
SELECT m
FROM Member m
WHERE EXISTS (SELECT t
FROM m.team t
WHERE t.name = 'teamA')
- ALL : 모두 만족하면 참
//[JPQL]
SELECT o
FROM Order o
WHERE o.orderAmount > ALL (SELECT p.stockAmount
FROM Product p)
- ANY, SOME : 조건을 하나라도 만족하면 참
//[JPQL]
SELECT m
FROM Member m
WHERE m.team = ANY (SELECT t
FROM Team t)
SELECT m
FROM Member m
WHERE m.team = SOME (SELECT t
FROM Team t)
- [NOT] IN : 서브 쿼리의 경과중 하나라도 같은 것이 있으면 참
JPQ 서브쿼리 한계
- JPA는 WHERE, HAVING 절에서만 서브 쿼리 사용 가능
- Hibernate의 경우, SELECT 절(스칼라 서브 쿼리)에서도 가능
- FROM 절의 서브 쿼리(인라인 뷰)는 현재 JPQL에서 불가능
'JPA' 카테고리의 다른 글
[JPA] 25. 경로표현식 (0) | 2021.02.11 |
---|---|
[JPA] 24. JPQL - 타입 표현, 기타식 (0) | 2021.01.31 |
[JPA] 22. JPQL - 기본 문법 2 (0) | 2021.01.27 |
[JPA] 21. JPQL - 기본 문법 1 (0) | 2021.01.26 |
[JPA] 20. JPA 쿼리 방법 소개 (0) | 2021.01.25 |