자바 ORM 표준 JPA 프로그래밍 - 기본편-10

존스노우·2022년 1월 11일
0

JPA

목록 보기
9/10

경로 표현식

. 점을 찍어 객체 그래프를 탐색 하는 것

경로 표현식 용어 정리

상태필드 -> 단순히 값을 저장하기 위한 필드

연관필드 -> 연관관계를 위한 필드

단일 값 연관 필드 - > ManyToOne ,OneToOne 대상이 엔티티

컬렉션 값 연관필드 - > OneToMany, ManyToMnay 대상이 컬렉션

경로 표현식 특징

상태 필드 -> 경로 탐색의 끝 탐색 X

단일 값 연관 경로 : 묵시적 내부 조인 발생 탐색 O (LAZY)

-> 편해보이지만 쿼리 튜닝 할 때 어렵다..
묵시적 내부 조인 사용하면 안됀다...

컬렉션 값 연관 경로 : 묵시적 내부조인 발생 탐색 X

-> 여러개의 나오기 때문에 난감.. 쓸 수 있는건 size뿐

FROM 절에서 명시적 조인을 통해 별칭을 얻으면 별칭을 통해 탐색 가능
(조인으로 해서 보여 줄 수 있다.)

결론 -> 묵시적 조인 쓰면 안됀다, 명시적 조인만

상태 필드 경로 탐색

sql 따라가면 됨.

이러면 망합니당..

명시적 조인, 묵시적 조인

결론 -> 명시적 조인 만 사용

조인은 SQL 튜닝의 포인트

묵시적 조인은 조인이 일어나는 상황을 한눈에 파악하기 어려움

페치 조인

중요

SQL 조인 종류 X

JPQL에서 성능 최적화를 위해 제공하는 기능

연관된 엔티티나 컬렉션을 SQL 한 번에 함께 조회하는 기능

join fetch 명령 사용

select m만 적었는데..

두 테이블 전체 조회 이너조인.(즉시로딩 이랑 같다)

이 시나리오 대로..

프록시인 member.getTeam().getName()

회원1 , 팀A(SQL)
회원2 , 팀A(1차캐시)
회원3 , 팀B(SQL)

회원 100명을 조회하면?? 쿼리가 100방나가면.. N+1
즉시 로딩 지연 로딩 이든 발생

해결은 fetch Join!

조인으로 한방 쿼리가 나간다.

member.getTeam().getName() 프록시가 아니게 된다. 실제 데이터
지연로딩해도 fetch 조인이 먼저 실행됨

컬렉션 페치 조인

컬렉션 조회시 중복 데이터가 !

1:N 관계이기 때문에 데이터가 뻥튀기 된다.

페치 조인과 DISTINCT

페치 조인과 일반 조인의 차이

멤버스에 데이터가 아직조회가 안돼있기 때문에..

fetch 조인으로 한번에..

페치 조인 2 - 한계

별칭 안돼? 사용하지말자
페치 조인은 나와 관련된거 다 가져와란 뜻.
객체그래프는 전부 다 조회야된다
ex) 그러면 나이가 10살 이상 가져오고싶어 -> 따로 10살 이상 쿼리만따로 만들자
객체 그래프 설계는 이런식으로 옵션 넣고하면 잘못하면 이상하게 동작하기 때문에
age>10 이런거는 따로조회하자
알리아스를 스면안됌.

결론: fetch join의 대상은 on, where 등에서 필터링 조건으로 사용하면 안된다.
사상 데이터 정합성 .. 이런 문제가 생기기 때문에

둘 이상의 컬렉션은 페치 조인 하면 안됌 -> 1:다:대 곱하기 곱하기 가 되버리기 때문에 안돼

이런식 다대 일로 바꿔서 페이징 하자

아니면 이런식..
이런식이면 성능이 안나온다.

이런식으로 배치사이즈 옵션을 줘도 된다.

N+1 이 터지는 곳만 페치 조인

  1. 페치 조인을 해서 엔티티를 조회함
  2. 페치 조인을 해서 애플리케이션 DTO 반환
  3. 처음 부터 JPQL DTO 반환??

어렵드아..

다형성 쿼리

엔티티 직접 사용 - 기본 키 값

JPQL에서 엔티티를 직접 사용하면 SQL에서 해당 엔티티의 기본 키값 사용함

엔티티를 식별할 수 있는건 기본키 값이기 때문

id도 똑같이..

엔티티 직접 사용 - 외래 키 값

이 외래키 값을 쓴다
기본키와 마찬가지로 id로 해도됨

Named 쿼리 - 정적 쿼리

메리트를 얻을 수 있다.

로딩시점에 쿼리를 sql로 파싱해서 캐시하고 있다.
코스트가 없다.

XML에서 설정

spring DataJPA

네임드 쿼리로 등록함

벌크 연산

SQL로 치면 Update /DELETE 문 이라고 생각하면됨
Pk 로 찍어서 한개만 적용하는 나머지 update/delete 문

벌크 연산 예

플러쉬는 커밋을 하거나 쿼리가 나갈때 강제로 호출 된다.

문제는

디비에는 플러쉬가 되서 20이 됨

영속성 컨텍스트에 있는거는 아직 반영이 안됐다

이렇게 클리어해서

가져오게 하자

profile
어제의 나보다 한걸음 더

0개의 댓글