1. 💡 벌크 연산
- PK를 특정한 엔티티의 Update, Delete를 제외한 모든 Update, Delete 쿼리이다.
- 쿼리 한 번으로 여러 테이블의 Row를 변경한다. (Entity)
- executeUpdate()의 결과는 영향을 받은 Entity의 수를 반환한다.
- Insert 문을 Hibernate에서 지원한다. (insert into .. select)
<java />
// 재고가 10개 미만인 Product의 Price를 쿼리 한 번으로 10% 인상
String qlString =
"update Product p " +
"set p.price = p.price * 1.1 " +
"where p.stockAmount < :stockAmount";
int resultCount = em.createQuery(qlString)
.setParameter("stockAmount", 10)
.executeUpdate();
1.1. 주의점
벌크연산은 영속성 컨텍스트를 무시하고 DB에 직접 쿼리한다. (데이터 정합성)
2가지 해결 방법
- 벌크 연산을 먼저 실행
- 벌크 연산 실행 후 영속성 컨텍스트 초기화 (em.clear())
2. 💡 다형성 쿼리
2.1. Type
조회 대상을 특정 하위 클래스로 한정할 수 있다.
예를 들어서 Item이 상위클래스이고 Book, Movie, Song 등 하위 클래스들이 있다고 가정한다.
Item의 하위 클래스 중 Book, Movie만 조회해보자.
<java />
String query = "select i from Item i where type(i) in (Book, Movie)";
2.2. Treat (JPA 2.1)
- 자바의 타입 캐스팅과 유사하다.
- 상속 구조에서 부모 타입을 특정 자식 타입으로 다룰 때 사용한다.
- FROM, WHERE, SELECT(Hibernate 지원)를 사용한다.
부모 타입의 다운캐스팅 예시
<java />
String query = "select i from Item i where treat(i as Book).auther = 'Kim'";
3. 💡 Named 쿼리 - 정적 쿼리
- 엔티티 클래스에 미리 정의해서 이름을 부여해두고 사용하는 JPQL
- 쿼리에 이름을 부여하며, 이름을 통해 쿼리를 불러오기가 가능하다.
- 어노테이션, XML에 정의 (XML이 항상 우선권을 가진다.)
- 어플리케이션 로딩 시점에 초기화 후 재사용 (SQL 로 파싱하여 쿼리를 캐싱함)
- 어플리케이션 로딩 시점에 쿼리를 검증 - 컴파일 타임 시 에러 발생으로 인해 디버깅 용이
- 보통 엔티티에 @NamedQuery보단 @Query가 사용하기 더 편하고 좋다.
<java />
// 엔티티 클래스에 정의
@Entity
@NamedQuery(
name = "Member.findByUsername",
query = "select m from Member m where m.username = :username")
public class Member {
...
}
// 사용
List<Member> resultList =
em.createNamedQuery("Member.findByUsername", Member.class)
.setParameter("username", "회원1")
.getResultList();
// 이름 없는 Named Query
public interface MemberRepository extends JPARepository<Member, Long> {
@Query("select m from Member m where m.address = ?1")
Member findByAddress(String address);
}
4. 💡 엔티티 직접 사용
JPQL에서 엔티티를 직접 사용하면 SQL에서 해당 엔티티의 기본 키 값을 사용한다.
엔티티를 직접 사용하거나 파라미터로 넘겨도 동일하게 PK로 조회한다.
<sql />
# 엔티티의 아이디를 사용
select count(m.id) from Member m
# 엔티티를 직접 사용
select count(m) from Member m
# 엔티티를 파라미터로 전달
select m from Member m where m = :member
# 식별자를 직접 전달
select m from Member m where m.id = :memberId
'Database > JPQL' 카테고리의 다른 글
JPQL Fetch Join (0) | 2023.03.19 |
---|---|
JQPL 경로표현식 (2) | 2023.03.19 |
JPQL Type Query & Sub Query (0) | 2023.03.11 |
JPQL Paging API & Search Result API (0) | 2023.03.11 |
JPQL Projection (0) | 2023.03.11 |