2024. 1. 25. 23:42ㆍspring/JPA
페이징
JPA는 페이징을 처리하는 API를 제공한다.
- setFirstResult(int startPosition) : 조회 시작 위치
- setMaxResults(int maxResult) : 조회할 데이터 수
List<Member> resultList = em.createQuery("select m from Member m order by m.age desc", Member.class)
.setFirstResult(10)
.setMaxResults(20)
.getResultList();
위 예제는 11번째부터 시작해서 20건의 데이터를 조회한다.(11~30)
조인
JPQL도 조인을 지원한다. SQL과 거의 동일하고 문법만 약간 다르다.
-내부조인
List<Member> resultList =
em.createQuery("select m from Member m inner join m.team t", Member.class).getResultList();
select
member0_.MEMBER_ID as member_i1_6_,
member0_.age as age9_6_,
member0_.TEAM_ID as team_id16_6_,
member0_.USERNAME as usernam10_6_,
from
Member member0_
inner join
Team team1_
on member0_.TEAM_ID=team1_.TEAM_ID
JPQL 내부 조인 구문을 보며 SQL의 조인과 약간 다른 것을 확인할 수 있다.
JPQL 조인은 연관 필드를 사용한다. 여기서 m.team이 연관 필드이다.
- FROM Member m : 회원을 선택하고 m 이라는 별칭을 줬다.
- Member m JOIN m.team t : 회원이 가지고 있는 연관 필드로 팀과 조인한다.조인한 팀의 별칭은 t이다.
JPQL 은 JOIN 명령어 다음에 조인할 객체의 연관 필드를 사용한다. 다음은 잘못된 예제이다.
List<Member> resultList =
em.createQuery("select m from Member m inner join Team t", Member.class).getResultList();
-외부조인
List<Member> resultList =
em.createQuery("select m from Member m left join m.team t", Member.class).getResultList();
select
member0_.MEMBER_ID as member_i1_6_,
member0_.age as age9_6_,
member0_.TEAM_ID as team_id16_6_,
member0_.USERNAME as usernam10_6_,
from
Member member0_
left join
Team team1_
on member0_.TEAM_ID=team1_.TEAM_ID
페치 조인
페치 조인은 JPQL에서 성능 최적화를 위해 제공하느 기능이다. 페치 조인을 하면 연관된 엔티티나 컬렉션을 한 번에 같이 조회할 수 있는데 join fetch 명령어로 사용할 수 있다.
select m from Member m join fetch m.team
select
member0_.MEMBER_ID as member_i1_6_,
member0_.age as age9_6_,
member0_.TEAM_ID as team_id16_6_,
member0_.USERNAME as usernam10_6_,
team1_.TEAM_ID as team_id1_11_1_,,
team1_.name as name2_11_1_
from
Member member0_
inner join
Team team1_
on member0_.TEAM_ID=team1_.TEAM_ID
위에서의 join 쿼리와 다르게 team 엔티티도 함께 조회해온다.
팀을 지연 로딩으로 설정했다고 해도 회원을 조회할 때 페치 조인을 사용해서 팀도 함께 조회했으므로 프록시가 아닌 실제 엔티티 객체를 반환한다.
*주의 fetch join 에서는 m.team 에 별칭을 사용할 수 없다.
페치 조인의 특징과 한계
페치 조인을 사용하면 SQL 한 번으로 연관된 엔티티들을 함께 조회할 수 있어서 SQL 호출 횟수를 줄여 성능을 최적화 할 수 있다.
최적화를 위해 fetch 전략을 즉시 로딩으로 설정하면 일부에서는 빠를 수 있지만 애플리케이션 전체로 보면 사용하지 않는 엔티티를 자주 로딩하므로 오히려 성능에 안좋을 수도 있다. 따라서 글로벌 로딩 전략은 웬만하면 지연 로딩을 사용하고 꼭 필요할 때 최적화를 하자.
* 페치 조인 대상에는 별칭을 줄 수 없다.
- 따라서 SELECT, WHERE, 서브 쿼리에 페치 조인 대상을 사용할 수 없다.
- JPA 표준에서는 지원하지 않지만 하이버네이트를 포함한 몇몇 구현체들은 페치 조인에 별칭을 지원한다. 하지만 별칭을 잘못 사용하면 연관된 데이터 수가 달라져서 데이터 무결성이 깨질 수 있으므로 조심해야 한다.
* 둘 이상의 대상에는 별칭을 줄 수 없다.
* 컬렉션을 페치 조인하면 페이징 API를 사용할 수 없다.
- 컬렉션이 아닌 단일 값 연관 필드들은 페치 조인을 사용해도 페이징 API를 사용할 수 있다.
'spring > JPA' 카테고리의 다른 글
성능 최적화(2) - 읽기 전용 (0) | 2024.02.13 |
---|---|
성능 최적화(1) - N+1 (0) | 2024.02.07 |
JPQL(2) - 프로젝션 (0) | 2024.01.24 |
JPQL(1) - 기본 문법 (0) | 2024.01.24 |
JPA - 값 타입 (0) | 2024.01.20 |