Soft Delete with @SQLDelete + @Where
1. Soft Delete Soft Delete란 soft delete는 database 의 테이블에서 물리적으로 데이터를 삭제하는 대신 마킹을 통해서 delete 를 구현하는 방식이다. soft delete를 구현하는 가장 보편화된 방식은 삭제여부를 나타내는 field 를 추가하는 방식이다. 다음은 deleted 란 field 를 통해 삭제 여부를 관리하는 방식의 예시이다. Soft Delete 수행법 해당 테이블에서 다음과 같은 SQL command를 통해 delete 작업을 수행할 수 있다. update from post set deleted=1 where id=1\n soft delete 방식을 도입하면 테이블 조회 방식도 바뀌게 된다. select * from post where deleted=0\n 2. Soft Delete 구현 post entity @Entity\n@Getter\n@NoArgsConstructor(access = AccessLevel.PROTECTED)\n@AllArgsConstructor(access = AccessLevel.PROTECTED)\n@Builder\npublic class Post {\n\n @Id @GeneratedValue(strategy = GenerationType.IDENTITY)\n private Long id;\n\n @NotNull\n private String title;\n\n @NotNull\n private String content;\n\n @NotNull\n private String writer;\n\n private boolean deleted = Boolean.FALSE;\n}\n\n 위 코드를 보면 post 엔티티에 default 값을 false 로 둔 deleted 변수를 추가하여 soft delete를 구현한 것을 확인할 수 있다. 이런 방식으로 구현하면 삭제할 때마다 update 쿼리를 날려야 하고 조회 할때마다 where 절을 통해 deleted=false 인 데이터만 조회하도록 쿼리를 작성해야 한다. 다음과 같은 JPA repsitory 의 delete command를 오버라이드하여 해당 작업을 간편화 할 수 있다. @Entity\n@Getter\n@NoArgsConstructor(access = AccessLevel.PROTECTED)\n@AllArgsConstructor(access = AccessLevel.PROTECTED)\n@Builder\n@SQLDelete(sql = \"UPDATE post SET deleted = true WHERE id=?\") - (1)\n@Where(clause = \"deleted=false\") - (2)\npublic class Post {\n\n @Id @GeneratedValue(strategy = GenerationType.IDENTITY)\n private Long id;\n\n @NotNull\n private String title;\n\n @NotNull\n private String content;\n\n @NotNull\n private String writer;\n\n private boolean deleted = Boolean.FALSE;\n\n public void update(String title, String content) {\n this.title = title;\n this. content = content;\n }\n}\n\n (1) @SQLDelete annotation을 통해 delete command를 deleted=true 로 update 하는 SQL command로 바꾼다. (2) @Where annotation을 통해 deleted=false 인 데이터만 조회하도록 한다. Repository public interface PostRepository extends JpaRepository<Post, Long> {\n}\n PostRepository 에는 특별한 변경점이 없다. Service @RequiredArgsConstructor\n@Service\npublic class PostService {\n\n private final PostRepository postRepository;\n\n public Long create(PostRequest postRequest) {\n Post post = postRequest.toEntity();\n return postRepository.save(post).getId();\n }\n\n public PostResponse getPost(long postId) {\n Post findPost = findPostById(postId);\n return PostResponse.builder()\n .post(findPost)\n .build();\n }\n\n public PostsResponse getPosts() {\n List<Post> posts = postRepository.findAll();\n return PostsResponse.builder()\n .postResponses(posts.stream()\n .map(post -> PostResponse.builder()\n .post(post)\n .build())\n .collect(Collectors.toList()))\n .build();\n }\n\n public Long update(Long postId,PostUpdateRequest postUpdateRequest) {\n Post findPost = findPostById(postId);\n findPost.update(postUpdateRequest.getTitle(), postUpdateRequest.getContent());\n return postRepository.save(findPost).getId();\n }\n\n public void delete(long postId) {\n postRepository.deleteById(postId);\n }\n\n private Post findPostById(long postId) {\n return postRepository.findById(postId).orElseThrow(() -> new NotFoundException(ErrorCode.ENTITY_NOT_FOUND.getMessage()));\n }\n}\n PostService 에도 특별한 변경사항 없이 원래 쓰던 deleteById 를 사용하면 update 쿼리로 변환되어 soft delete가 수행된다. 조회 메소드 또한 조회시 where 절에 deleted=false 가 추가되어 쿼리를 날리게 된다. 출처 How to Implement a Soft Delete with Spring JPA
3개의 댓글
0개의 질문