Spring boot

블로그 - 게시글 수정

ryeonng 2024. 10. 24. 09:22
BoardController - 게시글 수정하기 화면 요청
// 게시글 수정 화면 요청
    // board/{id}/update
    @GetMapping("/board/{id}/update-form")
    public String updateForm(@PathVariable(name = "id") Integer id, HttpServletRequest request) {
        // 1. 게시글 조회
        Board board = boardNativeRepository.findById(id);
        // 2. 요청 속성에 조회한 게시글 속성 및 값 추가
        request.setAttribute("board", board);
        // 뷰 리졸브 - 템플릿 반환
        return "board/update-form"; // 폴더 찾아가는 경로 src/main/resources/templates/board/update-form.mustache
    }

 

board/update-form.mustache
{{> layout/header}}

<main class="container p-5 content">
    <article>
        <div class="card">
            <div class="card-header"><b>글 수정 화면입니다.</b></div>
            <div class="card-body">
                <form action="/board/xxxx/update" method="post">
                    <!-- 작성자 이름 -->
                    <div class="mb-3">
                        <input type="text" class="form-control" placeholder="enter username" name="username" value="" readonly >
                    </div>

                    <!-- 제목 입력 -->
                    <div class="mb-3">
                        <input type="text" class="form-control" placeholder="enter title" name="title" value="" required>
                    </div>

                    <!-- 내용 입력 -->
                    <div class="mb-3">
                        <textarea class="form-control" rows="5" name="content" required></textarea>
                    </div>

                    <button class="btn btn-primary form-controller">글 수정</button>
                </form>
            </div>
        </div>
    </article>

</main>

{{> layout/footer}}

 

Board.UpdateDTO 만들기
package com.tenco.blog_v1.board;

import com.tenco.blog_v1.user.User;
import lombok.Data;

public class BoardDTO {

    @Data
    public static class SaveDTO {
        private String title;
        private String content;

        public Board toEntity(User user) {
            return Board.builder()
                    .title(title)
                    .content(content)
                    .user(user)
                    .build();
        }

    }

    @Data
    public static class UpdateDTO {
        private String username;
        private String title;
        private String content;
    }
}

 

BoardController
 // 게시글 수정 요청 기능
  // board/{id}/update
  @PostMapping("/board/{id}/update")
  public String update(@PathVariable(name = "id") Integer id, @ModelAttribute BoardDTO.UpdateDTO reqDto) {

      // 1. 데이터 바인딩 방식 수정

      // 2. 인증 검사 - 로그은 여부 판단
      User sessionUser = (User) session.getAttribute("sessionUser");
      if(sessionUser == null) {
          return "redirect:/login-form";
      }
      // 3. 권한 체크 - 내 글이 맞니?
      Board board = boardRepository.findById(id);
      if(board == null) {
          return "redirect:/";  // 게시글이 없다면 에러 페이지 추후 수정
      }
      if (!board.getUser().getId().equals(sessionUser.getId())) {
          return "redirect:/error-403"; // 권한이 없습니다. 추후 수정
      }
      // 4. 유효성 검사 - 생략

      // 5. 서비스 측 위임 (직접 구현) - 레파지토리 사용
      boardRepository.updateByIdJPA(id, reqDto.getTitle(), reqDto.getContent());

      // 6. 리다이렉트 처리

      return "redirect:/board/" + id;
  }

 

BoardRepository 코드 추가
@RequiredArgsConstructor
@Repository // IoC
public class BoardRepository {

    private final EntityManager em;

    // 두 가지 방식으로 연습 - 1 - JPQL 사용 2 - JPA API 사용
    @Transactional
    public void updateByIdJPQL(int id, String title, String content) {
        // JPQL 쿼리 작성
        String jpql = " UPDATE Board b SET b.title = :title, b.content = :content WHERE b.id = :id ";
        Query query = em.createQuery(jpql);
        query.setParameter("title", title);
        query.setParameter("content", content);
        query.setParameter("id", id);
        query.executeUpdate();
    }

    @Transactional
    public void updateByIdJPA(int id, String title, String content) {
        Board board = em.find(Board.class, id);
        if(board != null) {
            board.setTitle(title);
            board.setContent(content);
        }
        // flush 명령, commit 명령할 필요 없이 트랜잭션 선언하면 -- 더티 체킹

    }
  • JPQL Update Query와 JPA API를 통한 엔티티 수정은 각각의 장단점이 있으므로, 사용 상황에 맞게 선택하는 것이 중요하다.
  • 단일 게시글 수정과 같은 경우에는 JPA API 방법이 더 적합하며, 대량 데이터 수정이 필요한 경우에는 JPQL Update Query를 사용하는 것이 효율적이다.
  • 영속성 컨텍스트와 트랜잭션 관리를 올바르게 설정하여 데이터 일관성을 유지하는 것이 중요하다.

'Spring boot' 카테고리의 다른 글

블로그 - 회원 정보 수정  (2) 2024.10.25
블로그 - 회원 가입 기능  (1) 2024.10.24
블로그 - 게시글 삭제  (4) 2024.10.23
블로그 - 게시글 쓰기  (0) 2024.10.23
블로그 - 로그인&로그아웃 구현  (0) 2024.10.23