JPA 강의 (벌크성 수정 쿼리)

minyeob·2023년 4월 2일
0

Spring

목록 보기
7/11

벌크성 수정 쿼리

JPA는 데이터를 변경하게 되면 변경감지에 의해서 트랜잭션 커밋시점에 update 쿼리를 날리게 된다.(단건 처리)
하지만 모든 직원의 연봉을 10% 올린다고 가정해보자.하나씩 끌어와서 하는 것 보다는 DB에 update 쿼리를 날려 일괄적으로 처리하는 것이 편할 것이다.
이렇게 일괄적으로 한번에 처리하는 쿼리를 벌크성 쿼리 라고 한다.

순수 JPA를 사용한 벌크성 수정 쿼리

public int bulkAgePlus(int age) {
        int resultCount = em.createQuery(
        "update Member m set m.age = m.age + 1" +
        "where m.age >= :age")
        .setParameter("age", age)
        .executeUpdate();
        return resultCount;
}

스프링 데이터 JPA를 사용한 벌크성 수정 쿼리

@Modifying   //excuteUpdate를 호출하기 위해 꼭 필요하다.(안쓰면 getResultList, getSingleResult를 호출)
@Query("update Member m set m.age = m.age + 1 where m.age >= :age")
int bulkAgePlus(@Param("age") int age);
  • 벌크성 수정, 삭제 쿼리는 @Modifying 어노테이션을 사용
    • 사용하지 않으면 org.hibernate.hql.internal.QueryExecutionRequestException: Not supported for DML operations 예외 발생
  • JPA는 영속성컨텍스트에 의해서 엔티티들이 관리가 되어야 하는데 벌크연산은 그것들을 무시하고 DB에 바로 쿼리를 날리게 된다.따라서 벌크연산을 수행한 후에
    영속성 컨텍스트를 비워주는 것이 좋다.(em.clear() 혹은 @Modifying(clearAutomatically = true))
@Test
public void bulkUpdate() throws Exception {
 //given
 memberRepository.save(new Member("member1", 10));
 memberRepository.save(new Member("member2", 19));
 memberRepository.save(new Member("member3", 20));
 memberRepository.save(new Member("member4", 21));
 memberRepository.save(new Member("member5", 40));
 //when
 int resultCount = memberRepository.bulkAgePlus(20);
 em.clear();
 
 List<Member> result = memberRepository.findByUsername("member5");
 Member member5 = result.get(0);
 //40살일까 41살일까?
 
 //then
 assertThat(resultCount).isEqualTo(3);
}

오늘의 한마디

주말병을 버리자.주말도 평소와 똑같은 생활패턴을 지녀야 한다.
profile
백엔드 개발자를 꿈꾸며 공부한 내용을 기록하고 있습니다.

0개의 댓글