CDATA : sql구문과 xml구문을 구분하기 위해 사용
Controller | Service |
---|---|
뷰 결정(lsit_view등) : 뷰에 들어갈 데이터 정도만 끌고오는 역할 | 비지니스 로직 : 기능 인터페이스 구현 |
[계산 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.global.ex.mapper.BoardMapper"> <!-- BoardMapper.java의 interface를 구현하겠다. --> <select id="getList" resultType="edu.global.ex.vo.BoardVO"> <!-- BoardMapper.java의 getList함수를 끌고 온다. --> <!-- BoardMapper.java의 List<BoardVO>를 끌고 온다.(DAO를 만들지 않아도 됨) --> <!-- resultType : BoardService.java의 타입(int등)을 지정함 --> <![CDATA[select * from mvc_board order by bGroup desc, bStep asc]]> <!-- CDATA를 사용하지 않으면 sql구문을 xml구문으로 인식하여 에러남 --> </select> <select id="read" resultType="edu.global.ex.vo.BoardVO" parameterType="edu.global.ex.vo.BoardVO"> <![CDATA[select * from mvc_board where bid = #{bid}]]> <!-- #{bid} : BoardVO get(BoardVO vo) 안에 있는 필드 이름 사용 가능 --> </select> <update id="update"> <![CDATA[update mvc_board set bname=#{bname}, btitle=#{btitle}, bcontent=#{bcontent} where bid =#{bid}]]> <!-- #{bid} : BoardService.java의 int modify(BoardVO vo) 안에 있는 필드 이름 사용 가능 --> </update> <delete id="delete"> <![CDATA[delete 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> --------------------------------------------------------------------- [계산 BoardController.java] package edu.global.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.global.ex.BoardService; import edu.global.ex.vo.BoardVO; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @Slf4j // 로그를 사용하기 위한 어노테이션 : log.info("view_list().."); @Controller // (@Component + 의미) BoardController board = new BoardController(); @RequestMapping("/jboard/*") // jboard로 들어오는 모든 것들은 BoardController를 생성해라 @RequiredArgsConstructor public class BoardController { @Autowired // (주입)객체에 주소를 줌 private BoardService boardService; // BoardService boardService = new BoardServiceImpl(); @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"; // 유저로 하여금 list로 다시 치고 들어오라 } @GetMapping("/delete") public String delete(BoardVO boardVO, Model model) { log.info("delete().."); // 디버그 int rn = boardService.remove(boardVO); log.info("delete();..result number::" + rn); return "redirect:list"; } @GetMapping("/write_view") public String write_view() { return "/board/write_view"; // /board/write_view.jsp로 가라는 뜻 } @PostMapping("/write") public String write(BoardVO boardVO) { log.info("write().."); // 디버그 int rn = boardService.register(boardVO); return "redirect:list"; // 유저로 하여금 list로 다시 치고 들어오라 } @GetMapping("/reply_view") // http://localhost:8282/jboard/reply_view?bid=65 public String reply_view(BoardVO boardVO, Model model) { log.info("reply_view().."); // 디버그 model.addAttribute("reply_view", boardService.get(boardVO.getBid())); return "/board/reply_view"; // 유저로 하여금 list로 다시 치고 들어오라 } @PostMapping("/reply") // http://localhost:8282/jboard/reply public String reply(BoardVO boardVO) { log.info("reply().."); // 디버그 boardService.registerReply(boardVO); return "redirect:list"; // 유저로 하여금 list로 다시 치고 들어오라 } } --------------------------------------------------------------------- [계산 BoardMapper.java] package edu.global.ex.mapper; import java.util.List; import org.apache.ibatis.annotations.Mapper; import edu.global.ex.vo.BoardVO; @Mapper // MyBatis 연결을 알려주는 것 public interface BoardMapper { // interface를 BoardMapper.xml에서 구현한다. >> Mybatis public List<BoardVO> getList(); public BoardVO read(int bid); // 파라미터는 url로 넘어오는 bid값을 의미 public int update(BoardVO board); // 글수정 public int delete(BoardVO board); // 글삭제 public int insert(BoardVO board); // 글작성 //답글관리 public void updateShape(BoardVO board); // 답글위치 public void insertReply(BoardVO board); // 답글등록 } --------------------------------------------------------------------- [계산 BoardService.java] package edu.global.ex; import java.util.List; import edu.global.ex.vo.BoardVO; public interface BoardService { public List<BoardVO> getList(); // 리스트 메소드 public BoardVO get(int bid); // 글보기 메소드 public int modify(BoardVO board); // 글수정 java:modify>>sql:update public int remove(BoardVO board); // 글삭제 public int register(BoardVO board); // 글작성 public void registerReply(BoardVO board); // 댓글작성 } --------------------------------------------------------------------- [계산 BoardServiceImpl.java] package edu.global.ex; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import edu.global.ex.mapper.BoardMapper; import edu.global.ex.repository.BoardDAO; import edu.global.ex.vo.*; import lombok.*; import lombok.extern.slf4j.Slf4j; @Slf4j // 로그를 사용하기 위한 어노테이션 : log.info("view_list().."); @Service @RequiredArgsConstructor // Autowired에 생성자 주입해 줌 public class BoardServiceImpl implements BoardService { @Autowired private 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 remove(BoardVO board) { log.info("delete().."); return mapper.delete(board); } @Override public int register(BoardVO board) { log.info("register().."); return mapper.insert(board); } @Transactional // 일련의 작업단위(CRUD중 2개 이상의 조합으로 들어가면 기재) @Override public void registerReply(BoardVO board) { log.info("registerReply().."); mapper.updateShape(board); // 답글의 위치를 먼저 잡아준 후 mapper.insertReply(board); // 답글을 등록한다. } } --------------------------------------------------------------------- [계산 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="수정"> <a href="list">목록보기</a> <a href="delete?bid=${content_view.bid}">삭제</a> <a href="reply_view?bid=${content_view.bid}">답변</a></td> </tr> </form> </table> </body> </html> --------------------------------------------------------------------- [계산 write.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 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="write" method="post"> <tr> <td> 이름 </td> <td> <input type="text" name="bname" size = "50"> </td> </tr> <tr> <td> 제목 </td> <td> <input type="text" name="btitle" size = "50"> </td> </tr> <tr> <td> 내용 </td> <td> <textarea name="bcontent" rows="10" ></textarea> </td> </tr> <tr > <td colspan="2"> <input type="submit" value="입력"> <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 > <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="post"> <!-- hidden : 개발자에게 필요한 정보 유저한테 보이지 않게 숨김 BReplyViewcommand로 보냄 --> <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>
[결과값]
[application.properties 설정 추가]
spring.datasource.driver-class-name=net.sf.log4jdbc.sql.jdbcapi.DriverSpy
spring.datasource.url=jdbc:log4jdbc:oracle:thin:@localhost:1521/xe
---------------------------------------------------------------------[log4jdbc.log4j2.properties 파일 추가]
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
log4jdbc.dump.sql.maxlinelength=0
---------------------------------------------------------------------
[logback-spring.xml 파일 추가]
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<withJansi>true</withJansi>
<encoder>
<pattern>%d{yyyyMMdd HH:mm:ss.SSS} [%thread] %highlight(%-5level)
%cyan(%logger{15}) - %msg %n</pattern>
</encoder>
</appender>
<logger name="jdbc" level="OFF" />
<logger name="jdbc.sqlonly" level="OFF" />
<logger name="jdbc.sqltiming" level="DEBUG" />
<logger name="jdbc.audit" level="OFF" />
<logger name="jdbc.resultset" level="OFF" />
<logger name="jdbc.resultsettable" level="DEBUG" />
<logger name="jdbc.connection" level="OFF" />
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>