본문 바로가기

개인적으로 공부한 것을 정리해 놓은 블로그입니다 틀린 것이 있으면 댓글 부탁 드립니다!


JPA

JPA 공부 20 - JPQL . 9 벌크 연산

반응형

 

재고가 10개 미만인 모든 상품의 가격을 10% 상승시키는 쿼리를 날려야 한다면?

 

JPA의 변경 감지 기능으로 실행하기에는 너무 많은 SQL이 실행된다 .

 

1. 재고 10개 미만 재품을 리스트로 조회하고 , 

 

2. 상품 엔티티 가격을 10% 증가시키고 

 

3.트랙잭션 커밋 시점에 변경 감지 동작

 

변경된 데이터 수만큼 업데이트 문이 나갈 것이다.

 

이런 문제를 위해 JPA에서는 벌크연산을 제공한다. 

 

쿼리 한 번으로 여러 테이블 로우를 변경할 수 있다.

 

간단한 예시로 멤버의 나이를 모두 20살로 바꿔야 한다고 하자 

 

 

int resultCount = em.createQuery("update Member m set m.age = 20")
                    .executeUpdate();

 

 

 

쿼리는 한번만 나가고 모든 값이 20으로 변경됬다.

 

 

update delete를 모두 지원하고 파라미터 셋팅해서 조건을 줄 수도 있다.

 

 

벌크 연산 주의점

 

-벌크 연산은 영속성 컨텍스트를 무시하고 데이터베이스에 직접 쿼리를 날리기 떄문에 영속성 컨텍스트가 꼬일 수있다.

 

 

           //벌크연산은 영속성 컨텍스트를 무시한다
            em.createQuery("update Member m set m.age = 20")
                    .executeUpdate();

            //아래의 문제 때문에 벌크연산 후에는 영속성을 초기화해주는 것이좋다.
            //영속성 컨텍스트가 초기화 되었기떄문에 DB에서 값을 가져오고 영속성 컨텍스트에 다시 올릴 것이다.
            em.clear();
            em.flush();

            //DB에는 update 되었지만 조회시에는 영속성컨텍스트에 저장된 것을 가져온다
            Member member = em.find(Member.class, member1.getId());
            System.out.println("member.getAge() = " + member.getAge());

 

 

영속성 초기화 없이 값을 가져왔을때 결과

 

반응형