2019. 9. 30. 09:47ㆍProject B (SPMS)/Project B 파트2
게시판 라우팅 테이블 설계
작 업 | URL | 메소드 | 파라미터 | 입력화면 필요 | URL 이동 |
전체 목록 | /board/list | GET | × | × | × |
등록 처리 | /board/register | POST | 전체 항목 | 〇 | 〇 |
상세 조회 | /board/read | GET | 글번호 | × | × |
수정 처리 | /board/remove | POST | 전체 항목 | 〇 | 〇 |
삭제 처리 | /board/modify | POST | 글번호 | 〇 | 〇 |
게시판 구현을 하기에 앞서서 게시판 라우팅 설계 작성을 하는게 좋다.
게시판 컨트롤러 작성 : 등록
src/main/java
com.spms.controller
BoardController.java
register()
package com.spms.controller;
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 com.spms.domain.BoardVO;
import com.spms.service.BoardService;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j;
@Controller
@Log4j
@RequestMapping("/board/*")
@AllArgsConstructor
public class BoardController {
private BoardService boardService;
@GetMapping("/list")
public void list(Model model) {
log.info("list");
boardService.getList().forEach(board -> log.info(board));
model.addAttribute("list",boardService.getList());
}
@PostMapping("/register")
public String register(BoardVO board, RedirectAttributes rttr) {
log.info("register : " + board);
boardService.register(board);
rttr.addFlashAttribute("result", board.getBno());
return "redirect:/board/list";
}
}
@PostMapping
포스트 방식 처리
RedirectAttributes rttr
등록 작업이 끝난 후, 다시 목록 화면으로 이동하기 위한 것인데, 추가적으로 새로 등록된 게시물의 번호를 같이 전달하기 위해 사용한다.
게시물의 번호는 나중에 '게시물 번호 [ ? ]가 등록되었습니다.' 라는 메세지를 뿌리기위해 준비하는 것이다.
리턴 시에는 'redirect:' 를 사용하는데 이것으로 스프링 MVC가 내부적으로 response.sendRedirect() 를 처리해주기 때문에 편리하다.
게시판 서비스 인터페이스 작성 : 등록
src/main/java
com.spms.service
BoardService.java 인터페이스
register()
package com.spms.service;
import java.util.List;
import com.spms.domain.BoardVO;
public interface BoardService {
public List<BoardVO> getList();
public void register(BoardVO board);
}
게시판 서비스 인터페이스 구현 작성 : 등록
src/main/java
com.spms.service
BoardServiceImpl.java
register()
package com.spms.service;
import java.util.List;
import org.springframework.stereotype.Service;
import com.spms.domain.BoardVO;
import com.spms.mapper.BoardMapper;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j;
@Log4j
@Service
@AllArgsConstructor
public class BoardServiceImpl implements BoardService {
private BoardMapper boardMapper;
@Override
public List<BoardVO> getList() {
// TODO Auto-generated method stub
log.info("getList....");
return boardMapper.getList();
}
@Override
public void register(BoardVO board) {
// TODO Auto-generated method stub
log.info("register......" + board);
boardMapper.insertSelectKey(board);
}
}
게시판 매퍼 인터페이스 작성 : 등록
src/main/java
com.spms.mapper
BoardMapper.java 인터페이스
insertSelectKey()
package com.spms.mapper;
import java.util.List;
import com.spms.domain.BoardVO;
public interface BoardMapper {
public List<BoardVO> getList();
public Long insertSelectKey(BoardVO board);
}
게시판 매퍼 인터페이스 구현 작성 (SQL XML) : 등록
src/main/resources
com
spms
mapper
BoardMapper.xml
insertSelectKey
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.spms.mapper.BoardMapper">
<!-- 목록 조회 -->
<select id="getList" resultType="com.spms.domain.BoardVO">
<![CDATA[
select *
from TBL_BOARD
where BNO > 0
]]>
</select>
<!-- 등록 (선택키 활용) -->
<insert id="insertSelectKey">
<selectKey keyProperty="bno" order="BEFORE" resultType="long">
select SEQ_BOARD.nextval
from DUAL
</selectKey>
insert into TBL_BOARD (
BNO, TITLE, CONTENT, WRITER
)
values (
#{bno}, #{title}, #{content}, #{writer}
)
</insert>
</mapper>
<insertSelectKey>
@SelectKey 라는 마이바티스의 어노테이션을 이용하며, 주로 PK 값을 미리 SQL을 통해 처리해둔 후, 특정한 이름으로 결과를 보관하는 방식이다.
여기서는 게시글 번호 컬럼명인 bno를 사용하고 있으며, 시퀀스로서 다음 게시글 번호를 미리 준비하는 작업을 하고나서 다음의 insert 문을 실행한다.
(*) #{ ? } 에 들어가는 변수명들은 VO에 따른 대소문자까지 구별하니 작성 시 주의할 것.
게시판 등록 유닛테스트 작성
src/test/java
com.spms.controller
BoardControllerTests.java
testRegister()
package com.spms.controller;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import lombok.Setter;
import lombok.extern.log4j.Log4j;
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = {
com.spms.config.RootConfig.class,
com.spms.config.ServletConfig.class} )
@Log4j
public class BoardControllerTests {
@Setter(onMethod_ = { @Autowired })
private WebApplicationContext ctx;
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(ctx).build();
}
@Test
public void testRegister() throws Exception {
String resultPage = mockMvc
.perform(MockMvcRequestBuilders.post("/board/register")
.param("title", "테스트 새글 제목")
.param("content", "테스트 새글 내용")
.param("writer", "user00"))
.andReturn().getModelAndView().getViewName();
log.info(resultPage);
}
}
게시판 등록 유닛테스트 결과
|--------|
|nextval |
|--------|
|10 |
|--------|
INFO : jdbc.resultset - 1. ResultSet.next() returned false
INFO : jdbc.resultset - 1. ResultSet.close() returned void
INFO : jdbc.audit - 1. Connection.getMetaData() returned oracle.jdbc.driver.OracleDatabaseMetaData@42d236fb
INFO : jdbc.audit - 1. PreparedStatement.isClosed() returned false
INFO : jdbc.audit - 1. PreparedStatement.close() returned
INFO : jdbc.audit - 1. PreparedStatement.new PreparedStatement returned
INFO : jdbc.audit - 1. Connection.prepareStatement(insert into TBL_BOARD (
BNO, TITLE, CONTENT, WRITER
)
values (
?, ?, ?, ?
)) returned net.sf.log4jdbc.sql.jdbcapi.PreparedStatementSpy@1ce93c18
INFO : jdbc.audit - 1. PreparedStatement.setLong(1, 10) returned
INFO : jdbc.audit - 1. PreparedStatement.setString(2, "테스트 새글 제목") returned
INFO : jdbc.audit - 1. PreparedStatement.setString(3, "테스트 새글 내용") returned
INFO : jdbc.audit - 1. PreparedStatement.setString(4, "user00") returned
INFO : jdbc.sqlonly - insert into TBL_BOARD ( BNO, TITLE, CONTENT, WRITER ) values ( 10, '테스트 새글 제목', '테스트 새글 내용',
'user00' )
INFO : jdbc.sqltiming - insert into TBL_BOARD ( BNO, TITLE, CONTENT, WRITER ) values ( 10, '테스트 새글 제목', '테스트 새글 내용',
'user00' )
'Project B (SPMS) > Project B 파트2' 카테고리의 다른 글
[B -2-12] CRUD 게시판 삭제 구현 (0) | 2019.09.30 |
---|---|
[B -2-11] CRUD 게시판 수정 구현 (0) | 2019.09.30 |
[B -2-10] CRUD 게시판 조회 구현 (0) | 2019.09.30 |
[B -2-8] CRUD 게시판 목록 구현 (0) | 2019.09.29 |
[B -2-7] 스프링 MVC 프로젝트의 기본 구조 1 (0) | 2019.09.29 |