본문 바로가기
Backend/JPA

QueryDSL - 한 번의 SQL 쿼리로 여러 건의 데이터를 일괄 수정 또는 삭제하는 방법 (벌크 연산)

by 개발자-제이 2025. 3. 25.

 

1. 벌크 연산이란?

벌크 연산(Bulk Operation)이란, 한 번의 SQL 쿼리로 여러 건의 데이터를 일괄 수정 또는 삭제하는 작업을 말한다.
이는 개별 엔티티를 하나씩 수정하거나 삭제하는 것보다 훨씬 빠르고 효율적이다.

특징 설명
목적 대량 데이터 일괄 처리
성능 단건 처리보다 뛰어남
JPA에서 JPQL의 update, delete로 수행
QueryDSL에서 queryFactory.update(), queryFactory.delete() 사용

 

2. QueryDSL 벌크 수정 (Update)

예시 1: 조건에 따라 특정 값으로 일괄 수정

long count = queryFactory
    .update(member)
    .set(member.username, "비회원")
    .where(member.age.lt(28))
    .execute();
설명 내용
수정 대상 username 필드를 "비회원"으로
조건 age < 28인 멤버만
반환값 영향을 받은 row 수 (long)

예시 2: 숫자 필드 계산식으로 수정

queryFactory
    .update(member)
    .set(member.age, member.age.add(1)) // 나이 + 1
    .execute();
.set(member.age, member.age.multiply(2)) // 나이 * 2
특징 내용
연산 적용 add(), multiply() 등 지원
SQL로 변환 UPDATE member SET age = age + 1 등

 

 

3. QueryDSL 벌크 삭제 (Delete)

long count = queryFactory
    .delete(member)
    .where(member.age.gt(18))
    .execute();

 

설명 내용
삭제 대상 age > 18인 모든 member
동작 방식 DB에 직접 DELETE 쿼리 실행
대안 deleteFrom()도 사용 가능

 

4. 주의사항: 영속성 컨텍스트와의 관계

* 벌크 연산은 영속성 컨텍스트를 무시한다

예시

em.persist(new Member("user1", 25)); // 영속 상태
queryFactory.update(member)
    .set(member.username, "비회원")
    .where(member.age.lt(28))
    .execute();

이후에 em.find() 또는 user1.getUsername()을 출력하면 "비회원"이 아니라 기존 값 "user1"이 반환된다.

해결책: flush() + clear()

em.flush();
em.clear();

 

  • flush(): 변경사항을 DB에 반영
  • clear(): 영속성 컨텍스트 초기화
  • 이후 조회 시 실제 DB 상태 기준으로 동작

 

5. 추가로 알아야 할 개념

 

1. execute() vs fetch()

메서드 용도 반환값
execute() update, delete, insert에서 사용 영향을 받은 row 수 (long)
fetch() select 쿼리 결과 조회 리스트 또는 단건

2. 벌크 연산 vs 일반 연산

항목 벌크 연산 일반 연산
대상 여러 건 (조건 기반) 엔티티 단건 또는 반복 처리
성능 빠름 상대적으로 느림
컨텍스트 반영 ❌ 무시 ✅ 영속성 컨텍스트 자동 반영
후처리 flush(), clear() 필요 별도 필요 없음

3. Spring Data JPA에서 벌크 연산

@Modifying(clearAutomatically = true)
@Query("update Member m set m.username = '비회원' where m.age < :age")
int bulkUpdate(@Param("age") int age);
  • @Modifying → JPQL로 벌크 연산 허용
  • clearAutomatically = true → 자동으로 컨텍스트 초기화

 

6. 정리

 

항목 설명
update() 조건에 따라 여러 행 수정
delete() 조건에 따라 여러 행 삭제
execute() 벌크 연산 실행 및 결과 row 수 반환
주의 영속성 컨텍스트를 무시하므로 flush + clear 필수
숫자 연산 .add(), .multiply() 등 사용 가능
장점 한 번의 쿼리로 대량 데이터 처리 → 성능 향상
단점 컨텍스트와의 불일치로 인해 혼동 발생 가능
반응형