73일 차 - 스프링, mybatis 활용 게시판 (23.04.12)

yvonne·2023년 4월 12일
0

📂Spring

목록 보기
5/18
post-thumbnail

1. mybatis 활용 게시판

📝 Controller 기능

✔ BoardController.java

package edu.example.ex.controller;

import org.springframework.beans.factory.annotation.Autowired;
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 edu.example.ex.service.BoardService;
import edu.example.ex.vo.BoardVO;
import lombok.extern.slf4j.Slf4j;

@Slf4j // 로그
@Controller
@RequestMapping("/jboard/*")

public class BoardController {
	@Autowired
	private BoardService boardService;

	@GetMapping("/list")
	public String view_list(Model model) {
		log.info("view_list() ..");

		model.addAttribute("boards", boardService.getList());

		return "/board/list";
	}

	@GetMapping("/content_view")
	public String content_view(BoardVO boardVO, Model model) {
		log.info("content_view() ..");
		int bid = boardVO.getBid();
		boardVO = boardService.get(bid);

		model.addAttribute("content_view", boardVO);

		return "/board/content_view";
	}
  
	@PostMapping("/modify")
	public String modify(BoardVO boardVO, Model model) {
		log.info("modify() ..");
		int rn = boardService.modify(boardVO);
		log.info("modify() .. result number::" + rn);

		return "redirect:list";
	}

	@GetMapping("/delete")
	public String delete(BoardVO boardVO, Model model) {
		log.info("delete() ..");
		int rn = boardService.delete(boardVO);
		return "redirect:list";
	}

	@GetMapping("/write_view")
	public String write_view() {
		return "/board/write_view";
	}

	@PostMapping("/write")
	public String write(BoardVO boardVO) {
		log.info("write() ..");
		int rn = boardService.write(boardVO);
		return "redirect:list";
	}

	@GetMapping("/reply_view")
	public String reply_view(BoardVO boardVO, Model model) {
		log.info("reply_view()..");
		model.addAttribute("reply_view", boardService.get(boardVO.getBid()));
		return "/board/reply_view";
	}

	@GetMapping("/reply")
	public String reply(BoardVO boardVO) {
		log.info("reply() ..");
		boardService.registerReply(boardVO);
		return "redirect:list"; // 로직 수행 후 list로 redirect 함
	}

}



📝 Model 기능

✔ BoardService.java

package edu.example.ex.service;

import java.util.List;

import edu.example.ex.vo.BoardVO;

public interface BoardService {
	public List<BoardVO> getList(); // 리스트

	public BoardVO get(int bno); // 글 보기

	int modify(BoardVO board); // 글 수정
	int delete(BoardVO board); // 글 삭제
	int write(BoardVO board); // 글 등록
	void registerReply(BoardVO board); // 댓글 등록
	
}

✔ BoardServiceImpl.java

package edu.example.ex.service;

import java.util.List;

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

import edu.example.ex.mapper.BoardMapper;
import edu.example.ex.vo.BoardVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
@RequiredArgsConstructor // +@Autowired 하면 생성자 주입 (없으면 필드 주입)

public class BoardServiceImpl implements BoardService {
	@Autowired
	private final BoardMapper mapper;

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

	@Override
	public BoardVO get(int bid) {
		log.info("get(int bid) ..");
		return mapper.read(bid);
	}

	@Override
	public int modify(BoardVO board) {
		log.info("modify() ..");
		return mapper.update(board);
	}

	@Override
	public int delete(BoardVO board) {
		log.info("delete() ..");
		return mapper.remove(board);
	}

	@Override
	public int write(BoardVO board) {
		log.info("write() ..");
		return mapper.insert(board);
	}

	@Transactional
	@Override
	public void registerReply(BoardVO board) {
		log.info("registerReply() ..");
		mapper.updateShape(board);
		mapper.insertReply(board);

	}

}

✔ BoardMapper.java

package edu.example.ex.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;

import edu.example.ex.vo.BoardVO;

@Mapper // mybatis에 사용할 거라는 것을 알려주는 애너테이션
public interface BoardMapper {
	public List<BoardVO> getList();

	public BoardVO read(int bid); // 파라미터는 url로 넘어오는 bid값을 의미

	public int update(BoardVO board); // ServiceImpl.java에서의 update 정의해주기 (글 수정)
	public int remove(BoardVO board);
	public int insert(BoardVO board);
	void updateShape(BoardVO board); // 답글 위치
	void insertReply(BoardVO board); // 답글 등록
}

✔ 🔎BoardMapper.xml

<?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="edu.example.ex.mapper.BoardMapper">
	<select id="getList" resultType="edu.example.ex.vo.BoardVO"> <!-- id는 함수이름 resultType은 BoardVO -->
	     <![CDATA[
    select * from mvc_board order by bGroup desc, bStep asc
 ]]>
	</select>

	<select id="read" resultType="edu.example.ex.vo.BoardVO"> 
	     <![CDATA[
	 select * from mvc_board where bid = #{bid}   
 ]]> <!-- content_view 부분 / #{bid}는 파라미터를 넘기는 과정 -->
	</select>

	<update id="update"> 
	     <![CDATA[
	update mvc_board set bname=#{bname}, btitle=#{btitle}, bcontent=#{bcontent} 
           where bid =#{bid}
 ]]> <!-- modify 부분 / bname=#{getBname()}과 같은 의미 -->
	</update>

	<delete id="remove"> 
	     <![CDATA[
	delete from mvc_board where bid = #{bid}
 ]]>
	</delete>

	<insert id="insert">
	 	     <![CDATA[
   insert into mvc_board (bid, bname, btitle, bcontent, bhit, bgroup, bstep, bindent) 
   values (mvc_board_seq.nextval, #{bname}, #{btitle}, #{bcontent}, 0, mvc_board_seq.currval, 0, 0) 

 ]]>
	</insert>
	
	  <!--댓글을 하나씩 미뤄서 정렬을 해줘야 하기 때문에 
  세로 정렬을 bstep에 +1로 한칸씩 미뤄내줘야한다. -->
 <update id="updateShape">
    <![CDATA[
        update mvc_board set bstep = bstep + 1 where bgroup =#{bgroup} and bstep > #{bstep}
    ]]>
 </update>

 <insert id="insertReply" >
 <![CDATA[
    insert into mvc_board (bid, bname, btitle, bcontent, bgroup, bstep, bindent) 
    values (mvc_board_seq.nextval, #{bname}, #{btitle},#{bcontent}, 
              #{bgroup}, #{bstep}+1, #{bindent}+1)
 ]]>
 </insert>
</mapper>



📝 view 기능

✔ list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<table width="500" cellpadding="0" cellspacing="0" border="1">
		<tr>
			<td>번호</td>
			<td>이름</td>
			<td>제목</td>
			<td>날짜</td>
			<td>히트</td>
		</tr>
		<c:forEach var="board" items="${boards}">
			<tr>
				<td>${board.bid}</td>
				<td>${board.bname}</td>
				<td><c:forEach begin="1" end="${board.bindent}">-</c:forEach> <a
					href="${pageContext.request.contextPath}/jboard/content_view?bid=${board.bid}">${board.btitle}</a></td>
				<td>${board.bdate}</td>
				<td>${board.bhit}</td>
			</tr>
		</c:forEach>
		<tr>
			<td colspan="5"><a href="write_view">글작성</a></td>
		</tr>
	</table>
</body>
</html>
  • 결과

✔ content_view.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
 $(document).ready(function (){
    $('#a-delete').click(function(event){
       //prevendDefault()는 href로 연결해 주지 않고 단순히 click에 대한 처리를 하도록 해준다.
       event.preventDefault();
       console.log("ajax 호출전"); 
       
       $.ajax({
           type : "DELETE",
           url : "${pageContext.request.contextPath}/restful/board/" + "${content_view.bid}",
           data:{"bid":"${content_view.bid}"},
           success: function (result) {       
               console.log(result); 
             if(result == "SUCCESS"){
                  //getList();
                       
             }
                    
           },
           error: function (e) {
               console.log(e);
           }
       })
       
    });
 });   
</script>
</head>
<body>

 <table id="list-table" width="500" cellpadding="0" cellspacing="0" border="1">
    <form action="modify" method="post">
       <input type="hidden" name="bid" value="${content_view.bid}">
       <tr>
          <td> 번호 </td>
          <td> ${content_view.bid} </td>
       </tr>
       <tr>
          <td> 히트 </td>
          <td> ${content_view.bhit} </td>
       </tr>
       <tr>
          <td> 이름 </td>
          <td> <input type="text" name="bname" value="${content_view.bname}"></td>
       </tr>
       <tr>
          <td> 제목 </td>
          <td> <input type="text" name="btitle" value="${content_view.btitle}"></td>
       </tr>
       <tr>
          <td> 내용 </td>
          <td> <textarea rows="10" name="bcontent" >${content_view.bcontent}</textarea></td>
       </tr>
       <tr >
          <td colspan="2"> <input type="submit" value="수정"> &nbsp;&nbsp; <a href="list">목록보기</a> &nbsp;&nbsp; <a href="delete?bid=${content_view.bid}">삭제</a> &nbsp;&nbsp; <a href="reply_view?bid=${content_view.bid}">답변</a></td>
       </tr>
    </form>
 </table>

</body>
</html>
  • 결과

✔ write_view.jsp

<%@ page language="java" contentType="text/html;charset=utf-8"
	pageEncoding="utf-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>

<html>
<head>
<title>write_view</title>
<script
	src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
	$(document).ready(function() {

		$("#updateForm").submit(function(event) {
			//prevendDefault()는 href로 연결해 주지 않고 
			//단순히 click에 대한 처리를 하도록 해준다.
			event.preventDefault();

			let bname = $("#input_bname").val();
			let btitle = $("#input_btitle").val();
			let bcontent = $("#input_bcontent").val();
			let form = {
				bname : bname,
				btitle : btitle,
				bcontent : bcontent
			};

			/*
			$.ajax({
			     type : `http method type`,
			     url : `url`,
			     data : `서버에 전송할 데이터`,
			     contentType : "전송할 데이터 타입",
			     //기본 값 : "application / x-www-form-urlencoded; charset = UTF-8"  
			     dataType : '서버로 부터 수신할 데이터 타입',
			     //아무것도 지정하지 않으면 jQuery는 응답의 MIME 유형을 기반으로 해석을 시도
			     error : `에러 발생시 수행할 함수`,
			     success : `성공시 수행할 함수`
			   });
			 */
			console.log(JSON.stringify(form));

			$.ajax({
				type : "POST",
				url : "/boards/",
				cashe : false,
				contentType : 'application/json; charset=utf-8',
				data : JSON.stringify(form),
				success : function(result) {
					console.log(result);
					//location.href = "/list";
					//$(location).attr('href', '/rest_board.html');
					$(location).attr('href', '/list2');
				},
				error : function(e) {
					console.log(e);
				}
			});

		});
	});
</script>
</head>
<body>
	<table width="500" cellpadding="0" cellspacing="0" border="1">
		<form action="write" method="post">
			<tr>
				<td>이름</td>
				<td><input id="input_bname" type="text" name="bname" size="50">
				</td>
			</tr>
			<tr>
				<td>제목</td>
				<td><input id="input_btitle" type="text" name="btitle"
					size="50"></td>
			</tr>
			<tr>
				<td>내용</td>
				<td><textarea id="input_bcontent" name="bcontent" rows="10"></textarea>
				</td>
			</tr>
			<tr>
				<td colspan="2"><input type="submit" value="입력">
					&nbsp;&nbsp; <a href="list">목록보기</a></td>
			</tr>
		</form>
	</table>
</body>
</html>
  • 결과

✔ reply_view.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>

	<table width="500" cellpadding="0" cellspacing="0" border="1">
		<form action="reply" method="get">
			<input type="hidden" name="bid" value="${reply_view.bid}"> <input
				type="hidden" name="bgroup" value="${reply_view.bgroup}"> <input
				type="hidden" name="bstep" value="${reply_view.bstep}"> <input
				type="hidden" name="bindent" value="${reply_view.bindent}">
			<tr>
				<td>번호</td>
				<td>${reply_view.bid}</td>
			</tr>
			<tr>
				<td>히트</td>
				<td>${reply_view.bhit}</td>
			</tr>
			<tr>
				<td>이름</td>
				<td><input type="text" name="bname" value="${reply_view.bname}"></td>
			</tr>
			<tr>
				<td>제목</td>
				<td><input type="text" name="btitle"
					value="${reply_view.btitle}"></td>
			</tr>
			<tr>
				<td>내용</td>
				<td><textarea rows="10" name="bcontent">${reply_view.bcontent}</textarea></td>
			</tr>
			<tr>
				<td colspan="2"><input type="submit" value="답변"> <a
					href="list">목록</a></td>
			</tr>
		</form>
	</table>

</body>
</html>
  • 결과
profile
개발 연습장

0개의 댓글