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/{{board.id}}/update" method="post">
<!--작성자 이름-->
<div class="mb-3">
<input type="text" class="form-control" placeholder="enter username" name="username" value="{{board.user.username}}" readonly >
</div>
<!--제목 입력 -->
<div class="mb-3">
<input type="text" class="form-control" placeholder="enter title" name="title" value="{{board.title}}" required>
</div>
<!--내용 입력 -->
<div class="mb-3">
<textarea class="form-control" rows="5" name="content" required>{{{board.content}}}</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;
// 두가지 방식으로 연습 - JQPL 사용, 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를 사용하는 것이 효율적이다.
- 영속성 컨텍스트와 트랜잭션 관리를 올바르게 설정하여 데이터 일관성을 유지하는 것이 중요하다.
728x90
'Spring boot > Blog 프로젝트 만들기(JPA)' 카테고리의 다른 글
완성 코드 STEP 02 - 회원정보 수정 ( JPA API , JPQL 쿼리 사용, 인증(세션 로직 추가 ) (0) | 2024.10.10 |
---|---|
완성 코드 STEP 02 - 회원 가입 ( JPA API , JPQL 쿼리 사용, 인증(세션 로직 추가 ) (0) | 2024.10.10 |
완성 코드 STEP 02 - 게시글 삭제 ( JPA API , JPQL 쿼리 사용, 인증(세션 로직 추가 ) (0) | 2024.10.08 |
완성 코드 STEP 02 - 게시글 쓰기 ( JPA API , JPQL 쿼리 사용, 인증(세션 로직 추가 ) (0) | 2024.10.08 |
완성 코드 STEP 02 - 로그인 & 로그아웃 구현하기 ( JPA API , JPQL 쿼리 사용, 인증(세션 로직 추가 ) (1) | 2024.10.08 |