기록방

[8일차] 8장 : 게시글 삭제하기: Delet 본문

FrameWork/스프링

[8일차] 8장 : 게시글 삭제하기: Delet

Soom_1n 2024. 6. 21. 02:25

길벗 IT도서에서 주관하는 코딩 자율학습단 8기 : Spring Boot 파트에 참여한 기록입니다 [ 목록 ]

8.1 데이터 삭제 과정

  1. 클라이언트가 HTTP 메서드로 특정 게시글의 삭제 요청
  2. 삭제 요청을 받은 컨트롤러는 리포지토리를 통해 DB에 저장된 데이터를 찾아 삭제
  3. 삭제가 완료됐다면 클라이언트를 결과 페이지로 리다이렉트
    1. 삭제 완료 메시지를 띄워주기 위한 RedirectAttributes 클래스의 addFlashAttribute() 메서드
    2. 리다이렉트 된 페이지에서 사용할 일회성 데이터 등록

8.2 데이터 삭제하기

8.2.1 Delete 버튼 추가하기

{{>layouts/header}}

<table class="table">
    <thead>
    <tr>
        <th scope="col">Id</th>
        <th scope="col">Title</th>
        <th scope="col">Content</th>
    </tr>
    </thead>
    <tbody>
    {{#article}}
    <tr>
        <th>{{id}}</th>
        <td>{{title}}</td>
        <td>{{content}}</td>
    </tr>
    {{/article}}
    </tbody>
</table>

<a href="/articles/{{article.id}}/edit" class="btn btn-primary">Edit</a>
<a href="/articles/{{article.id}}/delete" class="btn btn-danger">Delete</a>
<a href="/articles">Go to Articles List</a>

{{>layouts/footer}}

8.2.2 Delete 요청을 받아 데이터 삭제하기

@GetMapping("/articles/{id}/delete")
public String delete(@PathVariable Long id) {
    log.info("삭제 요청이 들어왔습니다!!");
    // 1. 삭제할 대상 가져오기
    Article target = articleRepository.findById(id).orElse(null);
    log.info(target.toString());

    // 2. 대상 엔티티 삭제하기
    if (target != null) {
        articleRepository.delete(target);
    }
    // 3. 결과 페이지로 리다이렉트하기
    return "redirect:/articles";
}

삭제 잘 됨

8.2.2 Delete 요청을 받아 데이터 삭제하기

@GetMapping("/articles/{id}/delete")
public String delete(@PathVariable Long id, **RedirectAttributes rttr**) {
    log.info("삭제 요청이 들어왔습니다!!");
    // 1. 삭제할 대상 가져오기
    Article target = articleRepository.findById(id).orElse(null);
    log.info(target.toString());

    // 2. 대상 엔티티 삭제하기
    if (target != null) {
        articleRepository.delete(target);
        **rttr.addFlashAttribute("msg","삭제됐습니다!");**
    }
    // 3. 결과 페이지로 리다이렉트하기
    return "redirect:/articles";
}
  • RedirectAttributes를 이용해 리다이렉트 페이지에 일회성 데이터를 전달
  • delete() 메서드의 매개 변수로 받아와야 함

8.2.3 삭제 완료 메시지 넘기기

{{#msg}}
<div class="alert alert-primary alert-dismissible">
    {{msg}}
    <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{{/msg}}

8.2.4 SQL 문으로 직접 DB 삭제하기

DELETE article WHERE id = 3;

8.2.5 최종 정리

  • 삭제 요청은 컨트롤러의 delete() 매서드에서 @GetMapping으로 받음 (HTML에서는 @DeleteMapping으로 받을 수 없기 때문)
  • 삭제 대상의 id를 위해 @PathVariable 사용
  • DB 내부에서는 DELETE라는 SQL문이 자동 수행
  • 삭제 작업 후에는 결과 페이지로 리다이렉트
    • 삭제 메시지도 함께 출력하기 위해 RedirectAttributes 클래스의 addFlashAttribute() 메서드 사용
    • 리다이렉트 시점에 사용할 휘발성 데이터 등록

🚀 1분 퀴즈

  1. 다음 중 옳지 않은 것을 고르세요.
    1. HTTP는 POST, GET, PATCH(PUT), DELETE 등의 다양한 메서드를 제공한다.
    2. 데이터 삭제 요청은 반드시 HTTP의 DELETE 메서드로만 할 수 있다.
    3. @PathVariable은 클라이언트의 요청 중 특정 URL 값을 매개변수로 가져온다.
    4. CrudRepository는 데이터 삭제를 위해 delete() 메서드를 제공한다.
    5. RedirectAttributes 객체를 활용하면 리다이렉트 페이지에서 사용할 일회성 데이터를 등록할 수 있다.
    6. ⇒ b. 예제에서는 GET 메서드로 삭제 요청을 사용했다.

✅ 셀프 체크

Membe 게시판에 회원 정보 삭제 기능 추가하기

@GetMapping("/members/{id}/delete")
public String delete(@PathVariable Long id, RedirectAttributes redirectAttributes) {
    log.info("사용자 정보 삭제 요청 들어옴!!");
    Member memberEntity = memberRepository.findById(id).orElse(null);
    if (memberEntity != null) {
        memberRepository.delete(memberEntity);
        redirectAttributes.addFlashAttribute("msg", memberEntity.getEmail()+"의 정보가 삭제되었습니다.");
    }
    return "redirect:/members";
}
{{>layouts/header}}

<table class="table">
    <thead>
    <tr>
        <th scope="col">Id</th>
        <th scope="col">Email</th>
        <th scope="col">Password</th>
    </tr>
    </thead>
    <tbody>
    {{#member}}
    <tr>
        <th>{{id}}</th>
        <td>{{email}}</td>
        <td>{{password}}</td>
    </tr>
    {{/member}}
    </tbody>
</table>

<a href="/members/{{member.id}}/edit" class="btn btn-primary">Edit</a>
**<a href="/members/{{member.id}}/delete" class="btn btn-danger">Delete</a>**
<a href="/members">Go to Member List</a>

{{>layouts/footer}}

🏓 더 알아 볼 내용

1. JPA Repository delete

  • 책에서는 delete() 메서드를 사용해 객체를 삭제
  • 데이터를 삭제하는 방법은 delete() 메서드 외에도 다양한 방법이 존재
  • 그중에서 많이 사용되는 deleteById() 메서드
/**

* Deletes the entity with the given id.
* <p>
* If the entity is not found in the persistence store it is silently ignored.
* 
* @param id must not be {@literal null}.
* @throws IllegalArgumentException in case the given {@literal id} is {@literal null}
*/
void deleteById(ID id);
  • 주어진 id 값을 가진 데이터가 존재하지 않을 경우 조용히 무시
    • 해당 id의 데이터가 없어도 에러를 던지지 않음
  • 책에서 deleteById() 메서드를 사용하지 않고 delete() 메서드를 사용한 이유
    • 왜냐하면 이렇게 null 체크를 하기 때문
    • Article target = articleRepository.findBiyId(id).orElse(null); if(target != null) { articleRepository.delete(target); }
    • null 체크를 하는 이유는 우리가 원하는 행동이 정확한 ‘삭제’이기 때문
    • 그런데 deleteById() 메서드를 사용하면 최악의 경우 나도 모르는 사이 삭제가 이루어지지 않을 수 있음

2. 204 응답

  • delete() 메서드와 함께 따라오는 응답 : 204 No Content
  • 204는 200번 대 응답으로, ‘요청은 정상적으로 이루어졌으나 콘텐츠는 제공하지 않는다.’는 의미
    • 삭제된 데이터는 더 이상 유효한 데이터가 아니기 때문에 응답으로 내려주지 않는 게 좋음
    • 또한 JPA의 delete() 메서드의 리턴 타입이 void
  • 204 응답에 대해 자세히 알고 싶다면 아래 문서를 참고
728x90