Spring boot

2024.10.10 Blog 프로젝트 만들기(JPA) 게시글 수정 하기

정훈5 2024. 10. 10. 09:30

 

학습 목표 

JPA를 활용하여 게시글 수정 기능을 구현하는 방법을 학습합니다

 

BoardController.java

update 메서드 updateForm()으로 변경

더보기
// 게시글 수정 화면 요청
    @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);
        // 템플릿 뷰 리졸브 - 템플릿 반환
        // src/main/resource/templates/board/update-form.mustache
        return "board/update-form";
    }

 

update-form.mustache

더보기
{{> layout/header}}

<main class="container p-5 content">
    <div class="card">
        <div class="card-header"><b>{{name}}</b></div>
        <div class="card-body">
            <form action="/user/update" method="post" enctype="application/x-www-form-urlencoded">
                <div class="mb-3">
                    <input type="text" class="form-control" placeholder="enter username" name="username" disabled>
                </div>

                <div class="mb-3">
                    <input type="password" class="form-control" placeholder="enter password" name="password">
                </div>

                <div class="mb-3">
                    <input type="email" class="form-control" placeholder="enter email" name="email">
                </div>

                <button type="submit" class="btn btn-primary form-control">회원정보수정</button>
            </form>

        </div>
    </div>

</main>

{{> layout/footer}}

 

http://localhost:8080/ 접속한다.

게시글 '상세보기' 클릭한다.

'수정' 버튼을 클릭하면 아래의 그림과 같이 나타난다. 

 

 

BoardDTO.java

더보기
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(this.title)
                    .content(this.content)
                    .user(user)
                    .build();
        }
    }

    // 정적 메서드
    @Data
    public static class UpdateDTO {
        private String username;
        private String title;
        private String content;
    }

}

 

BoardRepository.java

더보기
// 두 가지 방식으로 연습 - JPQL 사용, 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) {
        // JPA API 쿼리 작성
        // 1차 캐시에서 찾아서 들고온다 DB까지 가지않음
       Board board = em.find(Board.class, id);
       if(board != null) {
           board.setTitle(title);
           board.setContent(content);
       }
       // flush 명령, commit 명령 할 필요없이
        // 트랜잭션을 선언하면 ---> 더티 체킹
    }

 

BoardController.java 코드 추가

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

        // 1. 데이터 바인딩 방식 수정
       //  @ModelAttribute : 모델 객체로 바인딩할 때 사용
        // 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. 서비스 측에 위임 (직접 구현) - repository 사용
        boardRepository.updateByIdJPA(id, reqDto.getTitle(), reqDto.getContent());

        // 6. 리다이렉트 처리

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

 

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