SpringBoot
[Spring] #3. 게시판 만들기 _ Controller
도하루박
2022. 11. 23. 01:06
반응형
<insert id="insert">
<selectKey keyProperty="boardNumber" order="BEFORE" resultType="long">
SELECT SEQ_BOARD.NEXTVAL FROM DUAL
</selectKey>
INSERT INTO TBL_BOARD(BOARD_NUMBER, BOARD_TITLE, BOARD_WRITER, BOARD_CONTENT)
VALUES(#{boardNumber}, #{boardTitle}, #{boardWriter}, #{boardContent})
</insert>
<selectKey keyProperty="boardNumber" order="BEFORE" resultType="long">
SELECT SEQ_BOARD.NEXTVAL FROM DUAL
</selectKey>
여기서 NEXTVAL 을 쓰면 게시글을 쓸 때 마다 시퀀스가 계속 올라가게 될 것이다.
지금 필요한 것은 지금 추가된 시퀀스인데 위에서 order는 순서를 뜻하는 것으로 BEFORE 원래 쿼리인 insert보다 먼저 된다는 뜻이다.
// 게시글 등록
@GetMapping("/write")
// 로그인할 때, 세션 접근할 때 이렇게 쓴다.
public void write(HttpServletRequest request, Model model){
model.addAttribute("memberId", request.getSession().getAttribute("memberId"));
}
boardController 작성
package com.example.app.controller;
import com.example.app.domain.vo.BoardVO;
import com.example.app.service.BoardService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.view.RedirectView;
import javax.servlet.http.HttpServletRequest;
@Controller
@RequiredArgsConstructor
@RequestMapping("/board/*")
public class BoardController {
private final BoardService boardService;
// 게시글 목록
public void list(Model model){
model.addAttribute("boards",boardService.showAll());
}
// 게시글 등록
@GetMapping("/write")
public void write(){
@PostMapping("/write")
public RedirectView write(BoardVO boardVO, RedirectAttributes redirectAttributes){
boardService.register(boardVO);
redirectAttributes.addFlashAttribute("boardNumber", boardVO.getBoardNumber());
return new RedirectView("/board/list");
}
// 게시글 상세보기
@GetMapping(value = {"/read", "/update"})
public void read(Long boardNumber, Model model){
model.addAttribute("board", boardService.show(boardNumber));
}
// 게시글 수정
// 게시글 수정 완료
@PostMapping("/update")
public RedirectView update(BoardVO boardVO, RedirectAttributes redirectAttributes){
boardService.modify(boardVO);
redirectAttributes.addAttribute("boardNumber", boardVO.getBoardNumber());
return new RedirectView("/board/read");
}
// 게시글 삭제
@PostMapping("/delete")
public RedirectView delete(Long boardNumber){
boardService.remove(boardNumber);
return new RedirectView("/board/List");
}
}
게시글 등록
@PostMapping("/write")
public RedirectView write(BoardVO boardVO, RedirectAttributes redirectAttributes){
boardService.register(boardVO);
redirectAttributes.addFlashAttribute("boardNumber", boardVO.getBoardNumber());
return new RedirectView("/board/list");
}
화면이 아닌 다른 컨트롤러로 이동할 때에는 RedirectView를 사용하여 Redirect 방식으로 전송할 수 있다.
Redirect 방식일 때 데이터를 전달하는 방법
1. Query String : 다음 컨트롤러에 데이터 전달
2. Flash : 화면에 데이터 전달
Session의 Flash 영역을 사용하여 request가 초기화된 뒤 Flash 영역에 담아뒀던 데이터를 꺼내올 수 있다.
RedirectAttrivutes는 addAttrbute()를 사용하여 쿼리 스티링을 제작해주고, addFlashAttribute()를 사용하여 Seccion의 Flash영역을 사용하게 해준다.
redirect를 써서 페이지 이동이아닌 위에 있는 컨트롤러를 거쳐서 위에 서 db를 조회하는 쿼리가 있기 때문에 db조회가 왼료된 list를 볼수 있게 되는 것이다.
BoardControllerTest
WAS는 톰캣에 내장되어있는 어플리케이션 컨텍스트에서 돌아간다.
Test의 모든 메서드를 실행시키기 위해서 모든 WAS 환경이 구축되어야 할 것이다.
package com.example.app.controller;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@SpringBootTest
@Slf4j
public class BoardControllerTest {
@Autowired
// 요청을 처리해주는 기능
private WebApplicationContext webApplicationContext;
// 브라우저에서 URL을 요청한 것과 같은 환경을 구성해준다. 요청을 보낼때 필요한 기능
// 이것을 쓰기 위해서 WebApplicationContext가 필요하다.
private MockMvc mockMvc;
@BeforeEach
// 각 단위테스트를 실행시키기 이전에 setUp() 메서드를 실행시키겠단 의미이다.
public void setUp(){
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@Test
void list() throws Exception{
log.info("boards: " + mockMvc.perform(MockMvcRequestBuilders.get("/board/list")).andReturn().getModelAndView().getModelMap());
// enter를 치면 브라우저에서 엔터를 친것처럼 쏴주는 역할
}
@Test
void write() throws Exception{
log.info("flash map: " + mockMvc.perform(MockMvcRequestBuilders.post("/board/write")
.param("boardTitle", "새로 작성한 글 제목" )
.param("boardContent", "새로 작성한 글 내용")
.param("boardWriter", "TEST")).andReturn().getFlashMap());
}
@Test
void read() throws Exception{
log.info("model map: " + mockMvc.perform(MockMvcRequestBuilders.get("board/read").param("boardNumber","22"))
.andReturn().getModelAndView().getModelMap());
}
@Test
void update() throws Exception{
log.info("model map: " + mockMvc.perform(MockMvcRequestBuilders.post("/board/update")
.param("boardNumber", "22" )
.param("boardTitle", "수정된 게시글 제목")
.param("boardContent", "수정된 게시글 내용")
).andReturn().getModelAndView().getModelMap());
}
@Test
void delete() throws Exception{
mockMvc.perform(MockMvcRequestBuilders.get("/board/delete")
.param("boardNumber","22")
).andExpect(MockMvcResultMatchers.status().is3xxRedirection());
}
}
반응형