다형성 쿼리

다형성 관계에 있는 객체를 대상으로 JPA가 지원하는 기능
TYPE
: 조회 대상을 특정 자식으로 한정
ex) Item중에 Book,Movie를 조회해라
TREAT
: 상속 구조에서 부모 타입을 특정 자식 타입으로 다룰 때 사용
[JPQL]
select i from Item i
where TYPE(i) IN (Book, Movie)
[SQL]
select i from i
where i DTYPE in ('B', 'M')
=======================================
[JPQL]
select i from Item i
where treat(i as Book).author = 'kim'
[SQL]
select i.* from Item as i
where i.DTYPE = 'B' and i.author = 'kim'
엔티티 직접 사용
JPQL에서 엔티티 자체를 직접 사용하면 SQL에서 해당 엔티티의 기본키 값(PK)을 사용
[JPQL]
select count(m.id) from Member m
select count(m) from Member m
[SQL]
select count(m.id) from Member as m
연관관계가 있는 객체들은외래키(FK)로 사용됨
[JPQL]
select m from Member m where m.team=:team
[SQL]
select m.* from Member as m where m.team_id=?
Named 쿼리
[ 설명 ]
미리 정의해서 이름을 부여해두고 사용하는 정적 JPQL
어노테이션 or XML에 정의하여 사용
- 애플리케이션
로딩 시점에 초기화 후 재사용
: 애플리케이션 로딩 시점에 Named쿼리를 파싱해서 캐시에 들고있다가 필요시 사용
- 애플리케이션
로딩 시점에 쿼리를 검증
: 애플리케이션 로딩 시점에 오타가 있을 경우 문법 검사를 해서 컴파일 오류를 냄!
[ 예시 ]

- 호출할
name을 지정할 때 관례로 엔티티.함수이름 이렇게 많이 사용함
스프링 데이터 JPA에서 @Query()로 지원함
[ XML 정의 ]

XML파일로 정의할 수도 있다
어노테이션 지정보다 XML 파일로 지정하는 것이 우선권을 가짐
벌크 연산
[ 설명 ]
-
벌크연산 ?
: pk를 정해서 하나에 대해 실행하는 update, delete를 제외한 모든 연산
(여러개를 대상으로 진행하는 update, delete 쿼리)
- 필요성
: JPA 더티 체킹으로 실행하려면 많은 SQL이 수행될때 하나의 쿼리로 변환
ex) 재고가 10개 미만인 모든 상품의 가격을 10% 상승하는 경우
더티 체킹(Dirty Checking)
: 트랜잭션이 끝나는 시점에 변화가 있는 Entity를 스냅샷과 비교해서 변화가 있는 경우 자동으로 DB에 변경하는 쿼리를 날려주는 것
- 사용 방법
- 쿼리를 작성 후
query.executeUpdate()로 실행
반환 값은 영향 받은 엔티티의 수
[ 예시 ]

[ 주의할 점 ]
UPDATE 와 DELETE 만 공식 지원
Hibernate는 INSERT도 추가 지원
벌크 연산은 영속성 컨텍스트를 무시하고 DB에 직접 접근한다! (중요)
(영속성 컨텍스트를 무시하기 때문에 로직에서 오류가 날 수 있음)
벌크 연산을 안전하게 사용하는 방법 2가지
벌크 연산 먼저 실행
: 먼저 수행하면 영속성 컨텍스트와 상관 없어짐
벌크 연산 수행 후 영속성 컨텍스트 초기화
: 중간에 벌크 연산을 사용하면 영속성 컨텍스트와 데이터 동기화가 되지 않아서 문제가 발생할 수 있다
--> 중간에 사용시 반드시 영속성 컨텍스트를 초기화 한 후 사용
(JPQL 날리면 자동 flush되지만, clear는 안되니까 clear는 해줘야함!)