Backend - Spring(2)

wlsdnboy·2022년 4월 19일
0

인터페이스에 메소드 추가. Xml 에 쿼리문 작성, test 코드 작성 순으로 반복하며 조회,삭제,수정, 읽기도 같은 방법으로 작성한다

BoardMapperTests.java에 메소드를 추가해준다


	@Test
	public void testInsertSelectKey() {
		BoardVO board = new BoardVO();
		board.setTitle("새로 작성하는글selectkey");
		board.setContent("새로 작성하는 내용SelectKey");
		board.setWriter("새로운 작성자SelectKey");
		
		mapper.insertSelectKey(board);
		log.info("1");
		
	}

board에 setTitle과 setContent,setWriter를 통해 추가한다
mapper는 BoardMapper.xml에 SQL을 호출하기 위한 인터페이스이다

BoardMapper.java 인터페이스에는

를 추가한다

BoardMapper.xml에 sql 쿼리문을 추가한다

<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>

selectkey는 bno의 값이 1씩 증가하게 한다

나머지 insert , read , delete ,update 메소드도 인터페이스에 추가해준다

BoardMapper.xml에도 sql쿼리문을 추가해준다


<insert id="insert">
		insert into tbl_board(bno,title,content,writer)
		values (seq_board.nextval, #{title},#{content},
		#{writer})
	</insert>
	<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>
	<select id="read" resultType="kr.icia.domain.BoardVO">
		select * from tbl_board where bno=#{bno}
	</select>
	<delete id="delete">
		delete tbl_board where bno=#{bno}
	</delete>
	<update id="update">
		update tbl_board
		set title=#{title},
		content=#{content},
		writer=#{writer},
		updateDate=sysdate
		where bno=#{bno}
	</update>


BoardService 인터페이스를 생성한다


public void register(BoardVO board);// 등록.

	public BoardVO get(Long bno);// 읽기

	public boolean modify(BoardVO board);// 수정

	public boolean remove(Long bno);// 삭제

	public List<BoardVO> getList();// 목록

위의 메소드들을 추가한다
crud에 해당하는 메소드들 이다

위 인터페이스를 implements 받는 BoardServiceImpl 클래스 생성한다


package kr.board.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import kr.board.domain.BoardVO;
import kr.board.mapper.BoardMapper;
import lombok.AllArgsConstructor;
import lombok.Setter;
import lombok.extern.log4j.Log4j;

@Log4j // lombok 로그 이용.
@Service // 이 클래스가 서비스 계층을 맡는다고 알림.
@AllArgsConstructor // 모든 매개변수에 대한 생성자 생성.(생성자 여러개 아님)
public class BoardServiceImp implements BoardService {

	@Setter(onMethod_ = @Autowired)
	private BoardMapper mapper;

	@Override
	public void register(BoardVO board) {
		log.info("register......" + board);
		mapper.insertSelectKey(board);
	}

	@Override
	public BoardVO get(Long bno) {
		log.info("get......" + bno);
		return mapper.read(bno);
	}

	@Override
	public boolean modify(BoardVO board) {
		log.info("modify......" + board);
		return mapper.update(board) == 1;
	}

	@Override
	public boolean remove(Long bno) {
		log.info("remove......" + bno);
		return (mapper.delete(bno)) == 1;
	}

	@Override
	public List<BoardVO> getList() {
		log.info("getList......");
		return mapper.getList();
	}

}

위의 메소드들을 추가한다

root-context.xml에가서 Mybatis-sping:scan 아래에 아래 코드 추가. (방금 생성한 서비스 클래스를 객체화)


<context:component-scan
base-package="kr.icia.service">
</context:component-scan>
<!-- 스프링 프레임워크에서 해당 패키지를 살펴보고, 컴포넌트와 관련
어노테이션을 만나면 그 부분을 자동 객체화 처리 -->


컨트롤러를 생성
package의 이름을 변경했다


package kr.board.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import kr.board.service.BoardService;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j;

/* @Controller : 스프링 컴파일러에 controller 라고 알림.
- 위 어노테이션이 있으면 자동으로 메모리에 등록.
- 생성, 초기화, 할당을 모두 자동으로 처리.
@RequestMapping : url 요청에 대한 처리를 명시.
- jsp 게시판에서 @WebServlet 역할과 비슷. */
@Log4j
@Controller
@RequestMapping("/board/*")
@AllArgsConstructor
public class BoardController {
	private BoardService service;

	/*
	 * @GetMapping : 페이지 요청 방식이 get일 경우.
	 * 
	 * @PostMapping : 페이지 요청 방식이 post일 경우.
	 */
	@GetMapping("/list")
	public void list(Model model) {
		log.info("list");
		model.addAttribute("list", service.getList());
//모델객체는 controller에서 생성된 데이터를 담아 view로 전달할 때 사용하는 객체이다 
//addAttribute("key","value") 메서드를 이용해 view에 전달할 데이터를 key,value 형식으로 전달한다
// 과거 jsp에서는 request.setAttribute로 ArrayList를 전달했지만
// , 같은 역할을 model이 대신.
// 컨트롤러 >> 서비스 >> 매퍼 >> mybatis
	}
}

BoardController.java에 위의 메소드를 입력한다

그리고 board/list.jsp을 만들고

실행하면

위와 같이 db에 있는 모든 내용이 출력된다

글쓰기 컨트롤러도 구현한다



	@PostMapping("/register")
	public String register(BoardVO board, RedirectAttributes rttr) {
	// @Controller 어노테이션이 붙고,
	// 컴포넌트 스캔에 패키지가 지정되어 있다면,
	// 매개변수 인자들은 스프링이 자동으로 생성 할당 함.
	log.info("register : " + board);
	service.register(board);
	rttr.addFlashAttribute("result", board.getBno());
	// 리다이렉트 시키면서 1회용 값을 전달.
	return "redirect:/board/list";
	}


// 제목 링크를 클릭하여 글 상세보기 - get 방식.
	@GetMapping("/get")
	public void get(@RequestParam("bno") Long bno, Model model) {
		// @RequestParam : 요청 전달값으로 글번호 이용.
		log.info("/get");
		model.addAttribute("board", service.get(bno));
		// jsp에서 request.setAttribute 하던 것과 비슷.
		// 전달값으로 명시만 하면 스프링이 자동 처리.
		// 사용하는 부분만 추가 구현.
	}

	// 글 수정 컨트롤러 구현.
	// post 요청으로 /modify 가 온다면, 아래 메소드 수행.
	@PostMapping("/modify")
	public String modify(BoardVO board, RedirectAttributes rttr) {
		log.info("modify:" + board);
		if (service.modify(board)) {
			rttr.addFlashAttribute("result", "success");
		}
		// 수정이 성공하면 success 메세지가 포함되어 이동.
		// 실패해도 메세지 빼고 이동.
		return "redirect:/board/list";
	}

	// 글 삭제 컨트롤러 구현
	@PostMapping("/remove")
	public String remove(@RequestParam("bno") Long bno, RedirectAttributes rttr) {
		log.info("remove..." + bno);
		if (service.remove(bno)) {
			rttr.addFlashAttribute("result", "success");
		}
		return "redirect:/board/list";
	}

@PostMapping은 페이지 요청방식이 post일 경우다.
RedirectAttributes 는 redirect에 데이터를 전달한다
addFlashAttribute는 데이터를 전달하는데 한번만 전달한다 일회용이다.
RequestParam은 요청을 통해서 전달 되는 변수값 OO이름으로 받은 변수를 OO로 할당한다

bootstrap을 통해서 css 파일부분을 받은후

리스트 부분을 3가지로 나눈다

헤더부분

코드가 너무 많아서 생략하겠다

풋터부분

리스트부분


<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!-- jstl core 쓸때 태그에 c 로 표시. -->
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!-- jstl fmt 쓸때 위와 같음. fmt : formatter 형식 맞춰서 표시 -->
<%@ include file="../includes/header.jsp"%>
<!-- DataTales Example -->

<h1 class="h3 mb-2 text-gray-800">Tables</h1>
<p class="mb-4">
	DataTables is a third party plugin that is used to generate the demo
	table below. For more information about DataTables, please visit the <a
		target="_blank" href="https://datatables.net">official DataTables
		documentation</a>.
</p>

<div class="card shadow mb-4">
	<div class="card-body">
		<div class="card-header py-3" align="right">
			<button id="regBtn" style="color: green;">write</button>
		</div>
		<div class="table-responsive">
			<table class="table table-bordered" id="dataTable" width="100%"
				cellspacing="0">
				<thead>
					<tr>
						<th>#번호</th>
						<th>제목</th>
						<th>작성자</th>
						<th>작성일</th>
						<th>수정일</th>
					</tr>
				</thead>
				<tbody>
					<c:forEach var="board" items="${list }">
						<tr>
							<td><c:out value="${board.bno }" /></td>
							<td><c:out value="${board.title }" /></td>
							<td><c:out value="${board.writer }" /></td>
							<td><fmt:formatDate pattern="yyyy-MM-dd"
									value="${board.regdate }" /></td>
							<td><fmt:formatDate pattern="yyyy-MM-dd"
									value="${board.updateDate }" /></td>
						</tr>
					</c:forEach>
				</tbody>
			</table>
		</div>
	</div>
</div>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog"
	aria-labelledby="exampleModalLabel" aria-hidden="true">
	<div class="modal-dialog" role="document">
		<div class="modal-content">
			<div class="modal-header"></div>
			<div class="modal-body"></div>
			<div class="modal-footer">
				<button class="btn btn-primary" type="button" datadismiss="modal">close</button>
			</div>
		</div>
	</div>
</div>
<script>
	$(document).ready(function() {
		$('#dataTable').DataTable({
			"order" : [ [ 0, "desc" ] ], //정렬 0컬럼의 내림차순으로
			"paging" : false, // 페이징 표시 안함.
			"bFilter" : false, // 검색창 표시 안함.
			"info" : false
		// 안내창 표시 안함.
		});
		$("#regBtn").on("click", function() {
			self.location = "/board/register";
			/* 아이디 regBtn 을 클릭한다면
			 현재창의 url를 쓰기로 변경 */
		});
		var result = '<c:out value="${result}"/>';
		// 자바스크립트는 형추론 이용.
		checkModal(result);
		// 게시물 번호를 매개변수로 전달하면서 checkModal 펑션 호출
		function checkModal(result) {
			if (result === '') {
				// == 는 값만 비교, === 은 값과 형식도 비교.
				return;
			}
			if (parseInt(result) > 0) {// 전달된 문자값을 숫자화, 자바의
				Integer.parseInt
				비슷함.$(".modal-body").html("게시글 " + parseInt(result) + "번이 등록");
				// 표시할 내용 만들기
			}
			$("#myModal").modal("show");// 모달창 표시
		}
	});
</script>
<%@ include file="../includes/footer.jsp"%>

리스트 부분을 위에서 부터 확인해보자면


<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>

jstl은 라이브러리이기 때문에 core를 header에 추가해줘야한다


<c:forEach var="board" items="${list }">
						<tr>
							<td><c:out value="${board.bno }" /></td>
							<td><c:out value="${board.title }" /></td>
							<td><c:out value="${board.writer }" /></td>
							<td><fmt:formatDate pattern="yyyy-MM-dd"
									value="${board.regdate }" /></td>
							<td><fmt:formatDate pattern="yyyy-MM-dd"
									value="${board.updateDate }" /></td>
						</tr>
					</c:forEach>

<c:forEach>는 loop문이고 아이템 속성에 배열을 할당할 수 있다

${}은 el이라고 한다
el을 사용하면 값이 없거나 형 변환 등에 신경 쓸 필요 없이 서버로 전송해서 형 변환 없이 사용 할 수 있다.

<c:out>은 값을 출력한다

profile
초보 개발자

0개의 댓글