[B -2-9] CRUD 게시판 등록 구현

2019. 9. 30. 09:47Project 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' ) 

 

반응형