-
Spring delete 메소드 주의사항Spring 2023. 2. 14. 22:33
Delete 쿼리 종류
TL;DR
- 속도 측면에서는 deleteAllInBatch() 가 가장 빠르다.
- test 코드를 제외하고는 deleteAllInBatch() 를 사용하지 말자
설명
delete(entity)
해당 메서드는 CrudRepository 에 등록되어 있는 메서드 입니다. 엔티티를 파라미터로 받아 해당 엔티티를 삭제합니다.
deleteAll()
해당 메서드는 CrudRepository 에 등록되어 있는 메서드로 해당 레포지토리에서 관리 되는 모든 entity 를 삭제합니다.
deleteAllInBatch()
해당 메서드는 JpaRepository 에 등록되어 있는 메서드로 모든 entity 를 한번의 함수 실행으로 삭제합니다.
예시
코드의 예시로 설명해보겠습니다.
예시로 다룰 엔티티는 Member 로 다음과 같습니다.
@Where(clause = "deleted_at is null") @SQLDelete(sql = "update member set deleted_at = now() where id = ?") @Entity class Member( @Column(name = "name") val name: String, ) { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private val id: Long? = null @Column(name = "deleted_at") private val deletedAt: String? = null }
@SpringBootTest @TestConstructor(autowireMode = TestConstructor.AutowireMode.ALL) class MemberRepositoryTest( val memberRepository: MemberRepository, ) { @Test @DisplayName("멤버 삭제") fun deleteMember() { println("---------------------MemberSave START---------------------") val member = memberRepository.save(MemberFactory.of("test")) val member2 = memberRepository.save(MemberFactory.of("test")) val member3 = memberRepository.save(MemberFactory.of("test")) println("---------------------MemberSave END---------------------") println("---------------------Member DELETE START---------------------") memberRepository.delete(member) println("---------------------Member DELETE END---------------------") println("---------------------Member DELETE ALL START---------------------") memberRepository.deleteAll() println("---------------------Member DELETE ALL END---------------------") println("---------------------Member DELETE ALL IN BATCH START---------------------") memberRepository.deleteAllInBatch() println("---------------------Member DELETE ALL IN BATCH END---------------------") } }
---------------------MemberSave START--------------------- Hibernate: insert into member (deleted_at, name) values (?, ?) Hibernate: insert into member (deleted_at, name) values (?, ?) Hibernate: insert into member (deleted_at, name) values (?, ?) ---------------------MemberSave END--------------------- ---------------------Member DELETE START--------------------- Hibernate: select member0_.id as id1_0_0_, member0_.deleted_at as deleted_2_0_0_, member0_.name as name3_0_0_ from member member0_ where member0_.id=? and ( member0_.deleted_at is null ) Hibernate: update member set deleted_at = now() where id = ? ---------------------Member DELETE END--------------------- ---------------------Member DELETE ALL START--------------------- Hibernate: select member0_.id as id1_0_, member0_.deleted_at as deleted_2_0_, member0_.name as name3_0_ from member member0_ where ( member0_.deleted_at is null ) Hibernate: update member set deleted_at = now() where id = ? Hibernate: update member set deleted_at = now() where id = ? ---------------------Member DELETE ALL END--------------------- ---------------------Member DELETE ALL IN BATCH START--------------------- Hibernate: delete from member ---------------------Member DELETE ALL IN BATCH END---------------------
코드의 결과를 살펴보면 delete(entity) 와 deleteAll() 는 soft delete 가 잘 작동하는 것을 확인할 수 있습니다. 또한 deleteAll() 은 하나의 레코드마다 하나의 update 쿼리가 생성되는것을 확인할 수 있습니다. 하지만 deleteAllInBatch() 는 모든 레코드는 hard delete 하는것을 확인할 수 있습니다.
따라서 속도를 위해 deleteAllInBatch() 를 사용할 수 있지만 비즈니스 로직에서 쓰는것은 hard delete 할 일이 아닌 이상 매우 경계하면서 사용해야 합니다.
'Spring' 카테고리의 다른 글
Kotlin 에서 Spring 으로 테스트할 때 주의사항 (0) 2023.02.14 Spring Bean (0) 2022.07.25 Spring에 비해 SpringBoot 가 가지는 특징 (0) 2022.07.03 Filter 와 Interceptor 의 차이 (0) 2022.06.26 @Transaction(readOnly = True) (0) 2022.05.08