학습 목표
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 Query와 JPA API를 통한 엔티티 수정은 각각의 장단점이 있으므로, 사용 상황에 맞게 선택하는 것이 중요합니다.
- 단일 게시글 수정과 같은 경우에는 JPA API 방법이 더 적합하며, 대량 데이터 수정이 필요한 경우에는 JPQL Update Query를 사용하는 것이 효율적입니다.
- 영속성 컨텍스트와 트랜잭션 관리를 올바르게 설정하여 데이터 일관성을 유지하는 것이 중요합니다.
'Spring boot' 카테고리의 다른 글
| 2024.10.10 Blog 프로젝트 만들기(JPA) 회원 정보 수정 (1) | 2024.10.10 |
|---|---|
| 2024.10.10 Blog 프로젝트 만들기(JPA) 회원 가입 기능 만들기 (0) | 2024.10.10 |
| 2024.10.08 Blog 프로젝트 만들기(JPA) 게시글 삭제 (5) | 2024.10.08 |
| 2024.10.08 Blog 프로젝트 만들기(JPA) 게시글 쓰기 (0) | 2024.10.08 |
| 2024.10.08 Blog 프로젝트 만들기(JPA) 로그인 & 로그아웃 구현하기 (0) | 2024.10.08 |