AJAX : 게시글 수정하기

Feb 22, 2024
AJAX : 게시글 수정하기

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}}
notion image
 

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 (자동) }
notion image
 

6. postman으로 시도해보기

notion image
notion image
 

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}}
notion image
 

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}}
notion image
notion image
 
Share article
RSSPowered by inblog