이 글은 프로젝트를 진행하면서 delete를 진행 시 mybatis 및 jpa를 사용하였을 때 DB에 접근하는 횟수 및 쿼리 횟수에 대해 비교하여 주관적으로 작성한 글이다.
Article 테이블이 DB에 저장되어 있다고 하자. 여기서 Ariticle 하나를 delete 하려고 한다.
jpa는 영속성 컨테스트라는 1차 캐시를 가지고 있다. 그렇기에 트랜젝션 안에서 select를 통해 Article 테이블 정보를 객체로 가져오면은 이에 해당하는 정보가 영속성 컨테스트에 저장된다. 그리고 delete를 실행하면 쿼리를 따로 저장해 놓았다가 트랜젝션 종료 시 저장해 놓은 쿼리를 DB에서 전달하여 실행하게 된다.
즉, article를 select하기 위해 DB접근 1회, 쿼리 실행 1회, 트랜젝션이 종료되면 쿼리 실행 1회가 실행되어 총 DB접근 1회, 쿼리 실행 2회가 된다.
jpa에 spring data jpa에는 deleteById가 있지 않나? articleId를 프론트로부터 받으면 이를 가지고 바로 deleteById를 실행하면 되지 않나 생각할 수 있다. 하지만 select를 하는 이유는 articleId 및 article에 대한 작성자 등 검증하는 과정이 필요하기 때문이다.
그렇기에 select를 할 때 예외가 발생하면 커스텀 예외로 처리를 진행하고 예외가 발생하지 않았다면 delete를 실행하는 것이다.
물론 deleteById를 실행했을 때, Id에 해당하는 데이터가 DB에 존재하지 않으면 예외를 발생하긴 한다.
EmptyResultDataAccessException 예외가 발생한다. 이를 가지고 ExceptionAdvice에 등록하면 문제는 없다. 하지만 커스텀 예외가 아니라는 점이다. 아니면 Try Catch문으로 커스텀 예외를 적용할 수는 있지만 코드가 더 길어지게 된다. 만약 위와 같이 적용하면 DB접근은 1회, 쿼리 실행도 1회가 된다.
그렇다면 mybatis mapper로 바로 delete쿼리를 발생하면 어떨까?
select를 하지않고 delete만 실행하면 1번의 DB접근과 1번의 쿼리실행만이 이루어진다.
그렇다면 예외처리는 어떻게 하는가? articleId는 작성자 Id 등 조건들을 where로 delete를 실행하였을 때 리턴값을 int로 설정하면 몇 개의 행이 삭제되었는지를 리턴하게 된다.
즉, 리턴 값이 1이면 정상적으로 delete가 실행된 것이고, 0이면 하나도 delete를 못한 것이니 커스텀 예외를 발생시키면 된다.
정리하면
JPA로 select 후 커스텀 예외처리 후 delete, DB접근 1회, 쿼리 실행 2회
JPA로 deleteById 바로 실행 시 EmptyResultDataAccessException 예외가 발생하면 예외 처리, DB접근 1회, 쿼리 실행 1회
Mybatis로 delete 쿼리를 실행 후 리턴 값이 이상이 있으면 예외 처리, DB접근 1호, 쿼리 실행 1회
이렇게 3가지가 되겠다. 이는 delete 뿐만 아니라 update에서도 동일하게 적용된다.
어느 방법이 정답인지는 모르겠다. 자신의 스타일 대로 가거나 회사마다 특성이 있고 그 회사에 맞는 방식을 사용하는 것이 정답일 것이다.
잘못된 내용이 있거나 추가적인 정보가 있다면 댓글로 알려주시면 감사하겠습니다...
참고
https://hwanchang.tistory.com/7
'프로젝트 관련' 카테고리의 다른 글
Springboot With React: 커서 기반 페이징 기법을 통한 댓글 무한 스크롤 구현 (1) | 2023.10.19 |
---|---|
스프링부트 With Mysql - easyRandom을 통한 bulk Insert 및 Index 적용 (0) | 2023.08.03 |
React: react-router-dom:v6에서 경로 설정 및 PathVariable(경로 변수) 가져오기 (0) | 2023.06.10 |
sprigboot 프로젝트 진행중 리펙토링 적용 (0) | 2023.04.01 |
Postman API를 통한 API 문서 작성 (0) | 2023.03.12 |