학습목표
JPA를 활용하여 게시글 작성 기능을 구현하는 방법을 학습합니다.
이 과정에서는 데이터 저장, DTO 사용, 컨트롤러 구현 등을 다루며, ORM의 영속성 관리에 대한 이해를 심화합니다.
BoardRepository save 메서드 구현하기
목표: Board 엔티티를 데이터베이스에 저장하는 save 메서드를 구현합니다.
boardRepository.java 추가
@ModelAttribute 와 @RequestBody 에 대한 차이점을 이해하자
더보기
/**
* em.persist(board) --> 비영속 상태인 엔티티를 영속상태로 전환
* @param board
* @return
*/
@Transactional
public Board save(Board board) {
em.persist(board);
return board;
}

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();
}
}
}
BoardController.java
게시글 저장 save( ) 메서드 수정
더보기
package com.tenco.blog_v1.board;
import com.tenco.blog_v1.user.User;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Slf4j
@RequiredArgsConstructor
@Controller
public class BoardController {
// DI
// @Autowired
// 네이티브 쿼리 연습
private final BoardNativeRepository boardNativeRepository;
// JPA API, JPQL
private final BoardRepository boardRepository;
// 세션을 받기위한 준비
private final HttpSession session;
// 특정 게시글 요청 확인
// 주소설계 - http://localhost:8080/board/1
@GetMapping("/board/{id}")
public String detail(@PathVariable(name = "id") Integer id, HttpServletRequest request) {
// JPA API 사용
// Board board = boardNativeRepository.findById(id);
// request.setAttribute("board", board);
// JPQL FETCH join 사용
Board board = boardRepository.findByIdJoinUser(id);
request.setAttribute("board", board);
return "board/detail";
}
/**
* http://localhost:8080/
* @param model
* @return
*/
@GetMapping("/")
public String index(Model model) {
//List<Board> boardList = boardNativeRepository.findAll();
List<Board> boardList = boardRepository.findAll();
model.addAttribute("boardList", boardList);
log.warn("여기까지 오나?");
// log.info("boardList : " + boardList);
// templates 폴더 안에 있는 index.mustache 실행
return "index";
}
// 주소설계 - http://localhost:8080/board/save-form
// 게시글 작성 화면
@GetMapping("/board/save-form")
public String saveForm() {
return "board/save-form";
}
// 게시글 저장
// 주소설계 - http://localhost:8080/board/save
@PostMapping("/board/save")
public String save(@ModelAttribute BoardDTO.SaveDTO reqDto) {
User sessionUser = (User)session.getAttribute("sessionUser");
if(sessionUser == null) {
return "redirect:/login-form";
}
// 파라미터가 올바르게 전달 되었는지 확인하기 위해서 사용
log.warn("save 실행: 제목={}, 내용={}", reqDto.getTitle(), reqDto.getContent());
// boardNativeRepository.save(title, content);
// SaveDTO에서 toEntity 메서드를 사용해서 Board 엔티티로 변환하고 인수값으로 User 정보를 넣었다.
// 결국 Board 엔티티로 반환이 된다.
boardRepository.save(reqDto.toEntity(sessionUser));
return "redirect:/";
}
// 주소설계 - http://localhost:8080/board/10/delete (form 활용하기 때문에 delete 선언)
// form 태그에서는 GET, POST 방식만 지원하기 때문이다.
@PostMapping("/board/{id}/delete")
public String delete(@PathVariable(name = "id") Integer id) {
boardNativeRepository.deleteById(id);
return "redirect:/";
}
// 게시글 수정 화면 요청
@GetMapping("/board/{id}/update-form")
public String update(@PathVariable(name = "id")Integer id, HttpServletRequest request) {
Board board = boardNativeRepository.findById(id);
request.setAttribute("board", board);
// src/main/resource/templates/board/update-form.mustache
return "board/update-form";
}
// 게시글 수정 요청 기능
// board/{id}/update
@PostMapping("/board/{id}/update")
public String update(@PathVariable(name = "id")Integer id, @RequestParam(name = "title") String title, @RequestParam(name = "content") String content) {
// 업데이트 기능이 완료되면 디테일로 자기자신
boardNativeRepository.updateById(id, title, content);
return "redirect:/board/detail" + id;
}
}
login-form.mustache value값 추가
더보기
{{> 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="/login" method="post" enctype="application/x-www-form-urlencoded">
<div class="mb-3">
<input type="text" class="form-control" placeholder="enter your name" name="username" value="길동">
</div>
<div class="mb-3">
<input type="password" class="form-control" placeholder="enter your password" name="password" value="1234">
</div>
<button type="submit" class="btn btn-primary form-control">로그인</button>
</form>
</div>
</div>
</main>
{{> layout/footer}}
save-form.mustache value값 추가
더보기
{{> layout/header}} {{! Partial 태그 (부분 템플릿 태그) }}
<main class="container p-5 content">
<article>
<div class="card">
<div class="card-header"><b>글쓰기 화면입니다</b></div>
<div class="card-body">
<form action="/board/save" method="post">
<div class="mb-3">
<input type="text" class="form-control" placeholder="Enter title" name="title" value="샘플 제목1">
</div>
<div class="mb-3">
<textarea class="form-control" rows="5" name="content">샘플 컨텐트1</textarea>
</div>
<button class="btn btn-primary form-control">글쓰기완료</button>
</form>
</div>
</div>
</article>
</main>
{{> layout/footer}}
JPA API를 만들어 보자
BoardRepository.java
더보기
/**
* 나중에 JPA API를 만들어 보자
* 게시글 삭제
*/
@Transactional
public void deleteById1(int id) {
Board board = em.find(Board.class, id);
if(board != null) {
em.remove(board);
}
}
BoardController.java
더보기
/** JPA API를 통해서 만들어보자?
* 주소 테스트 http://localhost:8080/board/1/delete1
* @param id
* @return
*/
@PostMapping("/board/{id}/delete1")
public String deleteTest(@PathVariable(name = "id") Integer id) {
User sessionUser = (User)session.getAttribute("sessionUser");
// 회원정보 없으면 로그인 페이지 이동
if(sessionUser == null) {
return "redirect:/login-form";
}
'Spring boot' 카테고리의 다른 글
| 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) 게시글 목록보기 (Post List View) (1) | 2024.10.08 |
| 2024.10.07 Blog 프로젝트 만들기(JPA) 게시글 상세보기 (Post Details View) (0) | 2024.10.07 |