출처
https://www.inflearn.com/course/ORM-JPA-Basic/dashboard
목차
벌크 연산
- 재고가 10개 미만인 모든 상품의 가격을 10% 상승하려면?
- JPA 변경 감지 기능으로 실행하려면 너무 많은 SQL 실행됩니다.
- 재고가 10개 미만인 상품을 리스트로 조회한다.
- 각각 상품 엔티티의 가격을 10% 증가한다.
- 트랜잭션 커밋 시점에 변경감지가 동작한다.
- 변경된 데이터가 100건이라면 100번의 UPDATE SQL 실행됩니다.
- UPDATE, DELETE 지원합니다.
- INSERT(insert into .. select)도 지원합니다. (하이버네이트 한정)
[예제]
- 쿼리 한 번으로 여러 테이블 로우 변경합니다. (엔티티)
- executeUpdate()의 결과는 영향받은 엔티티 수 반환합니다.
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();
참고 Insert Into
테이블에 새 행을 추가합니다.insert into 'table_name' (column_1, column_2, ...) values (value_1, value_2, ...)
참고 Insert Into ... select
다른 테이블의 데이터를 현재 테이블에 삽입합니다.insert into 'table_1' select * from 'table_2'
💡주의
벌크 연산은 영속성 컨텍스트를 무시하고 데이터베이스에 직접 쿼리를 날립니다. → 잘못하면 쿼리 순서가 꼬일 수 있습니다.
- 영속성 컨텍스트에 저장된 값이 없다면, 벌크 연산을 먼저 수행합니다.
- 영속성 컨텍스트에 저장된 값이 있다면, 벌크 연산 수행 후 영속성 컨텍스트를 초기화해야 합니다.
[예제]
Member member = new Member();
member.setAge(0);
em.persist(member);
em.createQuery("update Member m set m.age = 20")
.executeQuery();
//em.clear(); //영속성 컨텍스트 초기화 필요
Member findMember = em.find(Member.class, member.getId());
System.out.println(findMember.getAge()); //0 출력 (벌크 연산은 db 에만 반영이 되고, 영속성 컨텍스트의 member는 그대로이기 때문)
- 벌크 연산이 수행되면, 영속성 컨텍스트가 flush()됩니다.
- 만약, 영속성 컨텍스트에 저장된 회원의 나이가 0이었는데 벌크 연산을 통해 20으로 수정되었다면, 변경은 db에만 이뤄졌으므로 영속성 컨텍스트에 저장된 회원의 나이도 20으로 반영이 되어야 합니다.
'Backend > JPA' 카테고리의 다른 글
[JPQL] 경로 표현식 (0) | 2023.12.25 |
---|---|
[JPQL] 서브 쿼리 (0) | 2023.12.24 |
[JPQL] 조인 (0) | 2023.12.24 |
[JPQL] 프로젝션 (0) | 2023.12.24 |
[JPQL] 객체 지향 쿼리 기본 문법과 기능 (0) | 2023.12.24 |