
1. updateForm.mustache에서 btnUpdate() 만들고 작동 확인하기
{{> layout/header}}
<div class="container p-5">
<div class="card">
<div class="card-header"><b>익명 글수정 화면입니다</b></div>
<div class="card-body">
<form action="#">
<div class="mb-3">
<input type="text" class="form-control" placeholder="Enter author" id="author">
</div>
<div class="mb-3">
<input type="text" class="form-control" placeholder="Enter title" id="title">
</div>
<div class="mb-3">
<textarea class="form-control" rows="5" id="content"></textarea>
</div>
<button type="button" onclick="btnUpdate()" class="btn btn-primary form-control">글수정완료</button>
</form>
</div>
</div>
</div>
<script>
function btnUpdate(){
alert("수정버튼 작동되?")
}
</script>
{{> layout/footer}}

2. UpdateDTO 만들기
package shop.mtcoding.blog.board;
import lombok.Data;
public class BoardRequest {
@Data
public static class WriteDTO{ // json으로 받을 DTO
private String title;
private String content;
private String author;
}
@Data
public static class UpdateDTO{ // json으로 받을 DTO
private String title;
private String content;
private String author;
}
}
3. json으로 전송할 서버(update) 만들기
package shop.mtcoding.blog.board;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RequiredArgsConstructor
@RestController // 데이러틀 리턴
public class BoardApiController {
private final BoardRepository boardRepository; // DI
@PostMapping("/api/boards/{id}")
public ApiUtil<?> update(@RequestBody BoardRequest.UpdateDTO requestDTO, @PathVariable Integer id){
boardRepository.updateById(requestDTO, id);
return new ApiUtil<>(null);
}
@PostMapping("/api/boards")
public ApiUtil<?> write(@RequestBody BoardRequest.WriteDTO requestDTO){
boardRepository.insert(requestDTO);
return new ApiUtil<>(null);
}
// 삭제하기
@DeleteMapping("api/boards/{id}") // 보드 중에 몇번을 삭제할게
public ApiUtil<?> deleteById(@PathVariable Integer id, HttpServletResponse response) {
Board board = boardRepository.selectOne(id);
if (board == null) {
response.setStatus(404);
return new ApiUtil<>(404, "해당 데이터를 찾을 수 없습니다");
}
boardRepository.deleteById(id);
return new ApiUtil<>(null); // 삭제는 데이터를 줄 것이 없음
}
// 주소 만들기
@GetMapping("api/boards") // 보드 줘라는 주소, 복수는 보드들 줘, 보드들 중에 1번 줘해서 복수형을 씀
public ApiUtil<List<Board>> findAll(HttpServletResponse response) {
//response.setStatus(401);
List<Board> boardList = boardRepository.selectAll(); // 상태코드랑 메세지랑 같이 줘야함
return new ApiUtil<>(boardList); // MessageConverter라는 클래스가 오브젝트를 응답할때 자동 발동함
}
}
4. BoardRepository에 updateById() 만들기
package shop.mtcoding.blog.board;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@RequiredArgsConstructor
@Repository
public class BoardRepository {
private final EntityManager em;
public List<Board> selectAll() {
Query query = em.createNativeQuery("select * from board_tb order by id desc ", Board.class);
List<Board> boardList = query.getResultList(); // 못찾으면 빈 컬렉션을 준다 (크기=0)
return boardList;
}
public Board selectOne(int id) {
Query query = em.createNativeQuery("select * from board_tb where id = ?", Board.class);
query.setParameter(1, id);
try {
Board board = (Board) query.getSingleResult();
return board;
} catch (Exception e) {
return null;
}
}
@Transactional
public void insert(BoardRequest.WriteDTO requestDTO){
Query query = em.createNativeQuery("insert into board_tb(title, content, author) values(?, ?, ?)");
query.setParameter(1, requestDTO.getTitle());
query.setParameter(2, requestDTO.getContent());
query.setParameter(3, requestDTO.getAuthor());
query.executeUpdate();
}
@Transactional
public void deleteById(Integer id) {
Query query = em.createNativeQuery("delete from board_tb where id = ?");
query.setParameter(1, id);
query.executeUpdate(); // insert, update, delete는 커밋이 발동
}
public void updateById(BoardRequest.WriteDTO requestDTO, int id) {
Query query = em.createNativeQuery("update board_tb set title=? content=? author=? where id =?");
query.setParameter(1, requestDTO.getTitle());
query.setParameter(2, requestDTO.getContent());
query.setParameter(3, requestDTO.getAuthor());
query.setParameter(4, id);
query.executeUpdate();
}
}
5. update_test()하기
package shop.mtcoding.blog.board;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.context.annotation.Import;
import org.springframework.test.annotation.Rollback;
import java.util.List;
@Import(BoardRepository.class) // 내가 만든 클래스는 import 해줘야 함.
@DataJpaTest // DB 관련 객체들이 IoC에 뜬다.
public class BoardRepositoryTest {
@Autowired // Test에서 DI 하는 코드
private BoardRepository boardRepository;
@Test
public void selectAll_test(){
// given
// when
List<Board> boardList = boardRepository.selectAll();
System.out.println(boardList.size());
// then (id=1, title=제목1, content=내용1, author=홍길동)
// System.out.println(boardList);
Assertions.assertThat(boardList.get(0).getTitle()).isEqualTo("제목1");
Assertions.assertThat(boardList.get(0).getContent()).isEqualTo("내용1");
Assertions.assertThat(boardList.get(0).getAuthor()).isEqualTo("홍길동");
Assertions.assertThat(boardList.size()).isEqualTo(8);
}
@Test
public void selectOne_test(){
// given
int id = 1;
// when
Board board = boardRepository.selectOne(id);
// then (상태 검사)
// System.out.println(board);
Assertions.assertThat(board.getTitle()).isEqualTo("제목1");
Assertions.assertThat(board.getContent()).isEqualTo("내용1");
Assertions.assertThat(board.getAuthor()).isEqualTo("홍길동");
}
@Test
public void insert_test(){ // 테스트 메서드는 파라미터가 없다. 리턴도 없다.
BoardRequest.WriteDTO requestDTO = new BoardRequest.WriteDTO();
// given
String title = "제목10";
String content = "내용10";
String author = "이순신";
// when
boardRepository.insert(requestDTO);
// then -> 눈으로 확인 (쿼리)
} // Rollback (자동)
@Test
public void update_test(){ // 테스트 메서드는 파라미터가 없다. 리턴도 없다.
BoardRequest.UpdateDTO requestDTO = new BoardRequest.UpdateDTO();
// given
int id=1;
String title = "제목10";
String content = "내용10";
String author = "이순신";
// when
boardRepository.updateById(requestDTO, id);
System.out.println(requestDTO);
// then -> 눈으로 확인 (쿼리)
} // Rollback (자동)
}

6. postman으로 시도해보기


7. 오브젝트로 데이터 받기 확인하기
{{> layout/header}}
<div class="container p-5">
<div class="card">
<div class="card-header"><b>익명 글수정 화면입니다</b></div>
<div class="card-body">
<form action="#">
<div class="mb-3">
<input type="text" class="form-control" placeholder="Enter author" id="author">
</div>
<div class="mb-3">
<input type="text" class="form-control" placeholder="Enter title" id="title">
</div>
<div class="mb-3">
<textarea class="form-control" rows="5" id="content"></textarea>
</div>
<button type="button" onclick="btnUpdate()" class="btn btn-primary form-control">글수정완료</button>
</form>
</div>
</div>
</div>
<script>
function btnUpdate(){
let board = { // js 오브젝트
title: $("#title").val(), // value값 들고 옴
content: $("#content").val(),
author: $("#author").val(),
};
console.log(board);
}
</script>
{{> layout/footer}}

8. BoardController에서 updateForm 수정하기
- mustache 문법으로 boardId 받아오기
package shop.mtcoding.blog.board;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
@RequiredArgsConstructor
@Controller
public class BoardController {
private final BoardRepository boardRepository;
@GetMapping("/")
public String index() {
return "index";
}
@GetMapping("/board/saveForm")
public String saveForm() {
return "board/saveForm";
}
@GetMapping("/board/{id}/updateForm")
public String updateForm(@PathVariable int id, BoardRequest.UpdateDTO requestDTO, HttpServletRequest request) {
Board board = boardRepository.selectOne(id); // 해당 보드의 정보를 가져옴
request.setAttribute("board", board); // HttpServletRequest에 보드 객체를 추가
return "board/updateForm";
}
@PostMapping("/board/save")
public String save(){
return "redirect:/";
}
@PostMapping("/board/{id}/update")
public String update(@PathVariable int id) {
return "board/updateForm";
}
@PostMapping("/board/{id}/delete")
public String delete(@PathVariable int id){
return "redirect:/";
}
}
- url에 board.id 적용하기
{{> layout/header}}
<div class="container p-5">
<div class="card">
<div class="card-header"><b>익명 글수정 화면입니다</b></div>
<div class="card-body">
<form action="#">
<div class="mb-3">
<input type="text" class="form-control" placeholder="Enter author" id="author">
</div>
<div class="mb-3">
<input type="text" class="form-control" placeholder="Enter title" id="title">
</div>
<div class="mb-3">
<textarea class="form-control" rows="5" id="content"></textarea>
</div>
<button type="button" onclick="btnUpdate()" class="btn btn-primary form-control">글수정완료</button>
</form>
</div>
</div>
</div>
<script>
function btnUpdate() {
let board = { // js 오브젝트
title: $("#title").val(), // value값 들고 옴
content: $("#content").val(),
author: $("#author").val(),
};
console.log(board);
// 통신해서 보내기 위해 json으로 변경
let boardJson = JSON.stringify(board);
console.log(boardJson);
$.ajax({
url: "/api/boards/{{board.id}}",
type: "post",
data: JSON.stringify(board),
contentType: "application/json; charset=utf-8"
}).done((res) => {
location.href = "/";
}).fail((res) => {
alert(res.responseJson.msg);
});
}
</script>
{{> layout/footer}}


Share article