728x90
재고가 10개 미만인 모든 상품의 가격을 10% 올리려면 어떻게 해야 할까?
- JPA 변경 감지 기능으로 실행하려면 너무 많은 SQL이 실행될 것이다.
- 1. 재고가 10개 미만인 상품을 리스트로 조회한다.
- 2. 상품 엔티티의 가격을 10% 증가한다.
- 3. 트랜잭션 커밋 시점에 변경 감지가 동작한다.
- 변경된 데이터가 100건이라면 100번의 UPDATE SQL문이 실행될 것이다.
벌크 연산
- 쿼리 한 번으로 여러 테이블의 로우(엔티티)를 변경한다.
- executeUpdate()를 사용하여 연산할 수 있다.
// 모든 Member의 나이를 20살로 변경한다.
int resultCount = em.createQuery("update Member m set m.age = 20")
.executeUpdate();
- executeUpdate()의 결과는 벌크 연산으로 변경되거나 삭제되는 등 영향받은 엔티티 수를 반환한다.
- UPDATE, DELETE를 지원한다.
- JPA 스펙에는 없지만 하이버네이트를 쓰면 INSERT(insert into .. select, 하이버네이트 지원)에도 사용할 수 있다.
벌크 연산 사용시 주의할 점
- 벌크 연산은 영속성 컨텍스트를 무시하고 데이터베이스에 직접 쿼리를 날린다.
- 영속성 컨텍스트가 비었을 때 : 벌크 연산을 먼저 실행한다.
- 영속성 컨텍스트에 데이터가 있을 때 : 벌크 연산 수행 후에 영속성 컨텍스트를 초기화한다.
- EX) 벌크 연산으로 직원 연봉을 10% 인상시켰다.
- 데이터베이스는 10% 인상된 연봉으로 업데이트되었지만 영속성 컨텍스트 안의 연봉 데이터는 인상 전 그대로이기 때문에 꼬인다. 따라서 초기화를 해야 한다.
double resultCount = em.createQuery("update Member m set m.salary = m.salary * 1.1") // 5000 * 1.1 = 5500
.executeUpdate();
em.clear(); // 영속성 컨텍스트 초기화
Member findMember = em.find(Member.class, member1.getId());
System.out,println("findMember = " + findMember.getSalary());
// 출력
findMember = 5500.0;
@Modifying
@Modifying
@Query("update ~ set") // Spring Data JPA에서 @Modifying을 이용해 벌크 연산을 할 수 있다.
728x90
'[JAVA] > JPA' 카테고리의 다른 글
Entity 클래스에서 @Builder 제대로 알고 사용하자 (5) | 2023.05.23 |
---|---|
JPARepository의 findAll() 호출 시 하나의 Row가 중복해서 여러 개 들어가는 경우와 특정 컬럼만 null이 들어가 있는 경우 (엔티티명과 컬럼명의 올바른 매핑 방법) (0) | 2023.05.19 |
JPQL - @NamedQuery 애너테이션 (0) | 2023.05.13 |
JPQL - 엔티티 직접 사용 (0) | 2023.05.13 |
JPQL - 다형성 쿼리 (0) | 2023.05.13 |