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());
    }
}

 

 

반응형