대량 운영
- 특정 PK가 있는 엔터티의 업데이트/삭제를 제외한 모든 업데이트/삭제 쿼리.
- 하나의 쿼리로 여러 테이블의 행을 변경합니다. (법인)
- executeUpdate()의 결과는 영향을 받는 엔터티의 수를 반환합니다.
- Insert 문은 Hibernate에서 지원됩니다. (.. 선택에 삽입)
// 재고가 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();
지침
대량 작업은 지속성 컨텍스트를 우회하고 DB를 직접 쿼리합니다. (데이터 무결성)
2가지 해결 방법
- 대량 작업을 먼저 실행
- 대량 작업 실행 후 지속성 컨텍스트 초기화(em.clear())
다형성 쿼리
유형
검색 대상은 특정 하위 클래스로 제한될 수 있습니다.
예를 들어 Item이 상위 클래스이고 Book, Movie 및 Song과 같은 하위 클래스가 있다고 가정합니다.
Item의 하위 클래스 중에서 Book과 Movie를 찾아봅시다.
String query = "select i from Item i where type(i) in (Book, Movie)";
처리(JPA 2.1)
- Java의 typecasting과 유사합니다.
- 상위 유형을 상속 트리의 특정 하위 유형으로 처리하는 데 사용됩니다.
- FROM, WHERE, SELECT를 사용하십시오(Hibernate가 지원됨).
상위 유형 다운캐스팅의 예
String query = "select i from Item i where treat(i as Book).auther="Kim"";
명명된 쿼리 – 정적 쿼리
- 엔티티 클래스에서 미리 정의된이름을 부여하여 사용하는 JPQL
- 쿼리에 이름을 지정하고 이름으로 쿼리를 호출할 수 있습니다.
- XML로 정의된 주석(XML이 항상 우선함)
- 어플리케이션 로딩 시 초기화 후 재사용 (쿼리를 캐시하기 위해 SQL로 구문 분석)
- 애플리케이션 로드 시 쿼리 유효성 검사 – 컴파일 타임 오류로 인한 쉬운 디버깅
- 일반적으로 @Query는 엔터티에 대해 @NamedQuery보다 사용하기 더 편리하고 좋습니다.
// 엔티티 클래스에 정의
@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);
}
엔터티 직접 사용
JPQL에서 직접 엔터티를 사용하는 경우 SQL은 해당 엔터티의 기본 키 값을 사용합니다.
엔터티가 직접 사용되거나 매개변수로 전달되더라도 동일한 PK로 조회됩니다.
# 엔티티의 아이디를 사용
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