- 조인
1. 내부 조인 :
SELECT m FROM Member m [INNER] JOIN m.team t
2. 외부 조인 :
SELECT m FROM Member m LEFT [OUTER] JOIN m.team t
3. 세타 조인 :
select count(m) from Member m, Team t where m.username = t.name
- 조인 - ON 절
1. 조인 대상 필터링
2. 연관관계 없는 엔티티 외부 조인
1. 조인 대상 필터링
- ex) 회원과 팀을 조인하면서, 팀 이름이 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'
2. 연관관계 없는 엔티티 외부 조인
- ex) 회원의 이름과 팀의 이름이 같은 대상 외부 조인
- 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
Team team = new Team();
team.setName("teamA");
em.persist(team);
Member member = new Member();
member.setUsername("teamA");
member.setAge(10);
member.setTeam(team);
em.persist(member);
em.flush();
em.clear();
- InnerJoin
String query = "select m from Member m inner join m.team t";
List<Member> result = em.createQuery(query, Member.class)
.getResultList();
- LeftJoin
String query = "select m from Member m left join m.team";
List<Member> result = em.createQuery(query, Member.class)
.getResultList();
- 세터 조인
String query = "select m from Member m, Team t where m.username = t.name";
List<Member> result = em.createQuery(query, Member.class)
.getResultList();
System.out.println("result = " + result.size());
- (현재 teamName과 userName에 동일한 값이 있다는 가정)
- 세터 조인 2번째
String query1 = "select m from Member m left join Team t on m.username = t.name";
List<Member> result1 = em.createQuery(query1, Member.class)
.getResultList();
System.out.println("result = " + result1.size());
String query2 = "select m from Member m left join m.team t on t.name = 'teamA'"; // 원래는 파라미터 바인딩 해야한다.
List<Member> result2 = em.createQuery(query2, Member.class)
.getResultList();
System.out.println("result = " + result2.size());
- 서브 쿼리
- 서브 쿼리 지원 함수
1. [NOT] EXISTS (subquery): 서브쿼리에 결과가 존재하면 참
1.1. {ALL | ANY | SOME} (subquery)
1.2. ALL 모두 만족하면 참
1.3. ANY, SOME: 같은 의미, 조건을 하나라도 만족하면 참
2. [NOT] IN (subquery): 서브쿼리의 결과 중 하나라도 같은 것이 있으면 참
String query1 = "select (select avg(m1.age) From Member m1) from Member m left join Team t on m.username = t.name";
List<Member> result1 = em.createQuery(query1, Member.class)
.getResultList();
System.out.println("result = " + result1.size());
- EX)
1.
팀A 소속인 회원
select m from Member m
where exists (select t from m.team t where t.name = ‘팀A')
2.
전체 상품 각각의 재고보다 주문량이 많은 주문들
select o from Order o
where o.orderAmount > ALL (select p.stockAmount from Product p)
3.
어떤 팀이든 팀에 소속된 회원
select m from Member m
where m.team = ANY (select t from Team t)
- JPA 서브 쿼리 한계
1. JPA는 WHERE, HAVING 절에서만 서브 쿼리 사용이 가능하다.
2. SELECT절도 가능(하이버네이트에서 지원)
3. FROM절의 서브 쿼리는 현재 JPQL에서 불가능
3.1. 조인으로 풀 수 있으면 풀어서 해결한다.
*하이버네이트6 부터는 FROM 절의 서브쿼리를 지원한다.
- JPQL 타입 표현과 기타식
- JPQL 타입 표현
1. 문자: ‘HELLO’, ‘She’’s’
2. 숫자: 10L(Long), 10D(Double), 10F(Float)
3. Boolean: TRUE, FALSE • ENUM: jpabook.MemberType.Admin (패키지명 포함)
4. 엔티티 타입: TYPE(m) = Member (상속 관계에서 사용)
- JPQL 기타
1. SQL과 문법이 같은 식
2. EXISTS, IN
3. AND, OR, NOT
4. =, >, >=, <, <=, <>
5. BETWEEN, LIKE, IS NULL
String query1 = "select m.username, 'HELLO', TRUE From Member m " +
"where m.type = :userType";
List<Object[]> result1 = em.createQuery(query1)
.setParameter("userType", MemberType.ADMIN)
.getResultList();
for (Object[] objects : result1) {
System.out.println("objects = " + objects[0]);
System.out.println("objects = " + objects[1]);
System.out.println("objects = " + objects[2]);
}
출처 : 인프런 - 우아한 형제들 기술이사 김영한의 스프링 완전 정복 (자바 ORM 표준 JPA 프로그래밍 - 기본편)
'Programming > JPA' 카테고리의 다른 글
JPA - 경로 표현식 (0) | 2023.07.18 |
---|---|
JPA - 기본 문법 (조건식(CASE 등등), JPQL 함수) (0) | 2023.07.18 |
JPA - 기본 문법과 기능 (기본 문법, 프로젝션, 페이징) (0) | 2023.07.18 |
JPA - 값 타입 컬렉션 (0) | 2023.07.17 |
JPA - 값 타입과 불변 객체, 값 타입의 비교 (0) | 2023.07.17 |