cleanUrl: /posts/jpa-use-not-deleteAll-but-deleteAllInBatch
share: true

최근 받은 코드 리뷰에서 deleteAll 대신에 deleteAllInBatch 를 사용하라는 리뷰를 받았다. 내부적인 구현이 어떠한지 궁금하여 알아본 내용을 포스팅한다

최근에 받은 코드리뷰

최근에 받은 코드리뷰

이런 리뷰를 받게 되었다.

repository.deleteAll()repository.deleteAllInBatch 는 차이가 무엇일까?

<script async src="<https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js>"></script>
<ins class="adsbygoogle"
     style="display:block; width: 100%;"
     data-ad-format="fluid"
     data-ad-layout-key="-fb+5w+4e-db+86"
     data-ad-client="pub-8946038251809377"
     data-ad-slot="5490836264"></ins>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({});
</script>

repository.deleteAll()

/*
 * (non-Javadoc)
 * @see org.springframework.data.repository.Repository#deleteAll()
 */
@Override
@Transactional
public void deleteAll() {

	for (T element : findAll()) {
		delete(element);
	}
}

어쩐지 show-sql 옵션으로 보면 delete 쿼리가 하나씩 날아갔다.

하지만, 테스트 코드이기 때문에 딱히 문제 되지 않는다고 생각하고 넘어갔다.

만약 테스트 데이터로 1000개 의 item 을 삭제해야 한다면 1000번의 delete 쿼리가 실행되는 것이다.

repository.deleteAllInBatch()

/*
 * (non-Javadoc)
 * @see org.springframework.data.jpa.repository.JpaRepository#deleteInBatch(java.lang.Iterable)
 */
@Override
@Transactional
public void deleteAllInBatch(Iterable<T> entities) {

	Assert.notNull(entities, "Entities must not be null!");

	if (!entities.iterator().hasNext()) {
		return;
	}

	applyAndBind(getQueryString(DELETE_ALL_QUERY_STRING, entityInformation.getEntityName()), entities, em)
			.executeUpdate();
}

여기서 보면 getQueryString 에 매개변수로 DELETE_ALL_QUERY_STRING 을 받는다.

public abstract class QueryUtils {

	public static final String COUNT_QUERY_STRING = "select count(%s) from %s x";
	public static final String DELETE_ALL_QUERY_STRING = "delete from %s x";
	public static final String DELETE_ALL_QUERY_BY_ID_STRING = "delete from %s x where %s in :ids";

해당하는 상수를 타고 들어가면 QueryUtilsDELETE_ALL_QUERY_STRING 이라는 상수가 있고

delete from %s x 와 같이 작성된 쿼리가 있다.

즉, delete from 테이블 이름 이 되는것이다.