스프링/QueryDsl

[QueryDsl] 벌크 update,delete

nomoreFt 2022. 3. 13. 22:06

전체 데이터를 한번에 수정하는 경우를 벌크 연산이라고 한다.
종종 전체 데이터를 수정해야 하는 일이 생기는데, 어떻게 QueryDsl에서 벌크연산을 하는지 알아보자.

조건부로 특정 값 일괄 Update

    @Test
    public void bulkUpdate() throws Exception {
        //28살 미만은 다 비회원으로 이름을 변경하는 예시


        long updateCnt = queryFactory
                .update(member)
                .set(member.username, "비회원")
                .where(member.age.lt(28))
                .execute();


        em.flush();
        em.clear();
        /* update Member member1
            set member1.username = '비회원'1
            where member1.age < 282 */
    }

조건 부로 숫자 값들 덧셈,뺄셈,곱셈

뺄때는 minus 메서드가 없어서 add(-1) 식으로 수행한다.


    @Test
    public void bulkAdd() throws Exception {
        //모든 회원의 나이를 1살씩 더하기

        long updateCnt = queryFactory
                .update(member)
                .set(member.age, member.age.multiply(2))
                //.set(member.age, member.age.add(-1))
                //.set(member.age, member.age.add(1))
                .execute();

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

    }

삭제


    @Test
    public void bulkDelete() throws Exception {

        long updateCnt = queryFactory
                .delete(member)
                .where(member.age.eq(18))
                .execute();

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

주의사항

bulk 연산은 영속성 context와 별개로 db에 바로 Update를 하기 때문에,
연산 이후 영속성 context와 db값이 차이가 생긴다.
bulk 연산 이후, select를 한다면 db가 아닌, 영속성 Context에서 가져온다. (항상 우선권은 영속성Context)
그래서 💥 bulk연산 이후는 꼭 em.flush(), em.clear() 를 수행해주자.