수정
기본적으로 JPA는 수정, 삭제 시에 1건당 1번의 쿼리문을 날립니다. 연봉 인상같은 전체 적용사항은 한명씩 처리하는 것보다, 한번의 쿼리로 처리하는게 훨씬 효율성이 좋습니다. 이를 벌크 연산이라고 합니다.
수정을 실행해봅니다. 벌크연산은, 모든 member를 영속성 컨텍스트에 올리고 바로 DB에 반영합니다. 그런데, 영속성 컨텍스트에 수정된 값을 반영하지 않기 때문에 영속성 컨텍스트와 DB는 정합성이 맞지 않습니다.
//member1 = 10 -> DB member1
//member2 = 20 -> DB member2
//member3 = 30 -> DB member3
//member4 = 40 -> DB member4
long count = queryFactory
.update(member)
.set(member.username, "비회원")
.where(member.age.lt(28))
.execute();
//member1 = 10 -> DB 비회원
//member2 = 20 -> DB 비회원
//member3 = 30 -> DB member3
//member4 = 40 -> DB member4
즉, 영속성 컨텍스트에서는 여전히 username이 member1, member2, member3, member4 형태로 남아있습니다. DB에만 비회원으로 수정되어 있습니다.
심지어, 수정 이후 select()로 조회쿼리를 날리더라도 과거 값인 username이 member1, member2, member3, member4 형태로 남아있습니다. 이미 member1, member2, member3, member4는 영속성 컨텍스트에 존재하기 때문에, member들을 DB에 저장된 값으로 최신화 하지 않습니다.
따라서, 벌크 연산을 하고 나면 꼭 영속성 컨텍스트를 비워야 합니다.
long count = queryFactory
.update(member)
.set(member.username, "비회원")
.where(member.age.lt(28))
.execute();
em.clear();
em.flush();
덧셈 쿼리는 다음과 같습니다.
long count = queryFactory
.update(member)
.set(member.age, member.age.add(1))
.execute();
곱셈 쿼리는 다음과 같습니다.
long count = queryFactory
.update(member)
.set(member.age, member.age.multiply(2))
.execute();
삭제
삭제 쿼리는 다음과 같습니다.
long count = queryFactory
.delete(member)
.where(member.age.gt(18))
.execute();
JPQL, SQL 모두 잘 나옵니다.
* 출처
Inflearn : 실전! Querydsl 강의
반응형
'Spring > Querydsl' 카테고리의 다른 글
스프링 데이터와 Querydsl (0) | 2022.02.13 |
---|---|
순수 JPA와 Querydsl (0) | 2022.02.13 |
Querydsl 동적쿼리 (0) | 2022.02.13 |
QueryDsl 프로젝션 문법 (0) | 2022.02.13 |
QueryDsl 기본문법 (0) | 2022.02.12 |