JPA 기본 | JPQL 문법(3) - 페이징, 조인, 서브쿼리

2024. 7. 17. 16:22· 인프런 김영한 강의 정리/자바 ORM 표준 JPA 프로그래밍 기본편
목차
  1. 1. 페이징 API
  2. 2. 조인
  3. 2-1) JPQL 조인 예시
  4. 2-2) 컬렉션 조인
  5. 2-3) 연관관계 없는 엔티티 외부 조인 (하이버네이트 5.1이상 버전)
  6. 3. 서브 쿼리
  7. 3-1) 서브 쿼리 지원 연산자
  8. 3-2) 서브 쿼리 예시
728x90

1. 페이징 API

  • setFirstResult(int startPosition) : 조회 시작 위치 (0 부터 시작)
  • setMaxResults(int maxResult): 조회할 데이터 수

✅ 사용 예시

	//페이징 API
    List<Member> result = em.createQuery("select m from Member m order by m.age desc", Member.class)
            .setFirstResult(10)
            .setMaxResults(20)
            .getResultList();

이렇게 페이징API를 쓰면 10번 인덱스부터 20개의 결과를 받을 수 있다.

JPQL을 사용하면 이렇게 페이징 처리가 편하다.

 

관계형 데이터베이스인 Oracle에서는 페이징처리하는 쿼리가 3depth까지 가니

가독성도 떨어지고 매번 ROWNUM으로 페이징 쿼리를 작성하는 것이 귀찮은 부분이기도 하다.

 

✅Oracle 페이징 SQL쿼리 (참고용)

SELECT * 
FROM (
    SELECT 
        a.*, 
        ROWNUM rnum
    FROM (
        SELECT 
            m.username, 
            m.age
        FROM 
            Member m
        ORDER BY 
            m.username
    ) a
    WHERE ROWNUM <= :endRow
)
WHERE rnum > :startRow;

 

2. 조인

2-1) JPQL 조인 예시

--내부 조인
SELECT m FROM Member m [INNER] JOIN m.team t

--외부 조인
SELECT m FROM Member m LEFT [OUTER] JOIN m.team t

--세타 조인
select count(m) from Member m, Team t where m.username
= t.name

✔️ INNER, OUTER 생략 가능

✔️ 세타 조인

- 두 엔티티 간의 명시적인 관계 매핑이 없을 때 사용한다.

- 두 엔티티의 조합 중 where 조건에 만족하는 데이터만 결과로 반환한다.

 

2-2) 컬렉션 조인

한 엔티티가 다른 엔티티의 컬렉션을 가지고 있을 때 사용하는 조인이다.

일반적으로 @OneToMany , @ManyToMany 관계에서 사용된다.

 

✅'특정 팀과 그 팀에 속한 멤버 정보' 조회 예시

@Entity
@Getter
@Setter
public class Team {

    @Id
    @GeneratedValue
    private Long id;
    private String name;

    @OneToMany(mappedBy = "team")
    private List<Member> members = new ArrayList<>();
}

- team이 Member를 리스트로 가지고 있다.

 

✅JPQL 쿼리

select t, m from Team t join t.members m on t.name = :teamName

- 팀 이름이 (:teamName)인 팀에 속한 멤버(t.members)를 조회하는 쿼리다.

 

2-3) 연관관계 없는 엔티티 외부 조인 (하이버네이트 5.1이상 버전)

--연관관계 있는 엔티티 외부 조인
SELECT m, t FROM Member m LEFT JOIN m.team t on m.username = t.name

--연관관계 없는 엔티티 외부 조인
SELECT m, t FROM
Member m LEFT JOIN Team t on m.username = t.name

✔️연관관계가 있는 엔티티를 외부 조인 할 때는 m.team으로 가져온다. (m에 있는 team)

✔️연관관계가 없는 엔티티를 외부 조인 할 때는 Team 엔티티 자체를 가져온다.

 

✅두 쿼리를 실행 했을 때, 차이

--연관관계 있는 엔티티 외부조인 쿼리 실행
select
        m1_0.id,
        m1_0.age,
        m1_0.TEAM_ID,
        m1_0.username 
from
    Member m1_0 
left join
    Team t1_0 
        on t1_0.id=m1_0.TEAM_ID 
        and t1_0.name=m1_0.username
        
--연관관계 없는 엔티티 외부조인 쿼리 실행
select
        m1_0.id,
        m1_0.age,
        m1_0.TEAM_ID,
        m1_0.username 
from
    Member m1_0 
left join
    Team t1_0 
        on t1_0.name=m1_0.username

- 연관관계가 있는 엔티티를 외부조인 할때는 PK, FK를 조인하는 쿼리가 자동생성된다.

- 연관관계가 없는 엔티티를 외부조인 할 때는 PK, FK를 조인하지 않고 on절에 있는 조건만 실행된다.

 

 

3. 서브 쿼리

서브쿼리는 다른 쿼리의 결과를 조건이나 값으로 사용하는 쿼리다.

JPA 표준에서는 WHERE, HAVING 절에서 서브 쿼리를 사용할 수 있다.

하이버네이트 6이전 버전은 SELECT절에도 서브쿼리를 사용할 수 있고

하이버네이트 6이후 버전은 FROM 절에도 사용가능하다.

 

3-1) 서브 쿼리 지원 연산자

- [NOT] EXISTS : 서브쿼리에 결과가 존재하면 참 ( NOT EXISTS는 결과가 존재하지 않으면 참 )

- ALL : 서브 쿼리 결과와 비교하여 모두 만족하면 참

- ANY, SOME : 서브쿼리 결과와 비교하여 조건을 하나라도 만족하면 참

- IN : 서브 쿼리의 결과 중 하나라도 같은 것이 있으면 참

 

3-2) 서브 쿼리 예시

✅(EXISTS) 특정 조건을 만족하는 팀이 존재하는 멤버 찾기

SELECT m FROM Member m WHERE EXISTS (SELECT t FROM m.team t WHERE t.name = :teamName)

- 이 쿼리는 더 쉽게 표현하자면, teamName이름을 가진 team에 속한 멤버를 찾는 쿼리다.

- 각 Member에 대해 m.team을 기준으로 Team 엔티티를 조회하고 Team의 이름이 :teamName과 일치하는 경우에만 Member를 결과에 포함시킨다.

- 이 방식은 각 멤버에 대해 서브쿼리가 실행되어 특정 조건을 만족하는지 확인한다.

 

✅(IN) 특정 팀에 속한 모든 멤버 찾기

SELECT m FROM Member m WHERE m.team.id IN (SELECT t.id FROM Team t WHERE t.name = :teamName)

- 특정 팀이름을 가진 팀에 속한 모든 멤버를 찾는다.

- 첫번째 예시와 논리적으로 결과는 동일하지만 내부 처리 방식에 차이가 있다.

서브 쿼리를 먼저 실행해서 조건에 맞는 team의 id를 가져오고 그 id와 일치하는 멤버를 찾는다.

 

✅(ALL) 모든 제품의 재고량보다 주문량이 많은 주문 찾기

SELECT o FROM Order o WHERE o.orderAmount > ALL (SELECT p.stockAmount FROM Product p)

- 각 Order 인스턴스의 주문량이 모든 제품의 재고량보다 큰지 하나하나 비교한다.

- 주문량이 모든 재고량보다 큰 주문을 찾는다. 

 

✅(ANY) 제품의 재고량보다 주문량이 많은 주문 찾기

SELECT o FROM Order o WHERE o.orderAmount > ANY (SELECT p.stockAmount FROM Product p)

- 주문량과 제품의 재고량과 비교하여 한 건이라도 큰 게 있는 주문을 찾는다.

 

✅(HAVING) 각 팀의 평균 연령이 특정 값 이상인 팀 찾기

SELECT t FROM Team t JOIN t.members m GROUP BY t.id HAVING AVG(m.age) > :age

- 멤버들의 나이 평균이 :age보다 큰 팀을 찾는다.

 

🤔WHERE절에 집계함수를 쓰면 안될까? (안됨)

SELECT t FROM Team t JOIN t.members m WHERE AVG(m.age) > :age --틀린 쿼리

HAVING절 예제를 보고 써본 쿼리다.

결론적으로 WHERE절에는 집계함수를 쓰면 안된다.

왜냐하면, WHERE절은 개별 행을 필터링하는 데에 사용되고, 집계 함수는 그룹화된 데이터를 기반으로 계산되기 때문에 WHERE절에 쓸 수 없다.

 

 

 

 

 

 


🤓이번 포스팅에서 fetch join을 다루지 않았는데 fetch join은 단독 포스팅으로 다룰 예정!

728x90

'인프런 김영한 강의 정리 > 자바 ORM 표준 JPA 프로그래밍 기본편' 카테고리의 다른 글

JPA 기본 | JPQL 문법(5) - 조건식  (0) 2024.07.17
JPA 기본 | JPQL 문법(4) - ENUM 타입,상속관계 엔티티 표현  (0) 2024.07.17
JPA 기본 | JPQL 문법(2) - 프로젝션(SELECT)  (0) 2024.07.16
JPA 기본 | JPQL 기본 문법(1) 쿼리 API, 파라미터 바인딩  (0) 2024.07.15
JPA 기본 | 객체지향 쿼리 언어 알아보기(JPQL, QueryDSL 등)  (0) 2024.07.15
  1. 1. 페이징 API
  2. 2. 조인
  3. 2-1) JPQL 조인 예시
  4. 2-2) 컬렉션 조인
  5. 2-3) 연관관계 없는 엔티티 외부 조인 (하이버네이트 5.1이상 버전)
  6. 3. 서브 쿼리
  7. 3-1) 서브 쿼리 지원 연산자
  8. 3-2) 서브 쿼리 예시
'인프런 김영한 강의 정리/자바 ORM 표준 JPA 프로그래밍 기본편' 카테고리의 다른 글
  • JPA 기본 | JPQL 문법(5) - 조건식
  • JPA 기본 | JPQL 문법(4) - ENUM 타입,상속관계 엔티티 표현
  • JPA 기본 | JPQL 문법(2) - 프로젝션(SELECT)
  • JPA 기본 | JPQL 기본 문법(1) 쿼리 API, 파라미터 바인딩
백엔드 개발자 - 젤리곰
백엔드 개발자 - 젤리곰
오늘도 배움이 있는 하루가 되길 바라는 개발자
백엔드 개발자 - 젤리곰
backend-gummyBear
백엔드 개발자 - 젤리곰
전체
오늘
어제
  • 분류 전체보기 (145) N
    • 인프런 김영한 강의 정리 (60)
      • 스프링 핵심원리 기본편 (12)
      • 모든 개발자를 위한 HTTP 웹 기본 지식 (10)
      • 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 (3)
      • 자바 ORM 표준 JPA 프로그래밍 기본편 (28)
      • 실전! Querydsl (6)
    • Spring (2)
    • 프로젝트일지 (6)
    • 프로그래밍 언어 (20)
      • Java (17)
      • JavaScript (3)
      • Python (0)
    • 데이터베이스 (4)
      • Oracle (2)
      • ORM (1)
      • SQL 튜닝 (1)
    • 형상관리 (1)
      • Git (0)
    • 알고리즘&자료구조 (34)
      • Algorithm (31)
      • Data Structure (1)
    • CS지식 (4)
    • Cloud (5)
    • 일기 (8) N
      • 공부 일기 (3)
      • 독서 일기 (2)
      • 마음 일기 (3) N

블로그 메뉴

  • 홈
  • 태그

공지사항

인기 글

태그

  • 객체지향방법론
  • 다운캐스팅
  • 데이터베이스정규화
  • #{}와${}의차이
  • 프론트엔드개발자업무
  • ORM프레임워크
  • LeetCode17번
  • LeetCode200번
  • 프론트엔드역사
  • 객체지향의사실과오해
  • SublimeText단축키
  • 클라이언트서버통신
  • 힙자료구조
  • 인터페이스
  • 인프콘
  • 스프링컨텍스트
  • 커스텀annotation
  • jquery와javascript
  • dfs알고리즘
  • 업캐스팅

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
백엔드 개발자 - 젤리곰
JPA 기본 | JPQL 문법(3) - 페이징, 조인, 서브쿼리
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.