12월 12일 - 수업 37일차 (SPRING, SQL)

수아레스·2022년 12월 12일
post-thumbnail

1. 마이바티스를 활용하여, 게시판을 완성하시오.

BoardVO.java

package edu.global.ex.vo;

import java.sql.Timestamp;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;

@Setter
@Getter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class BoardVO {
	private int bid;
	private String bname;
	private String btitle;
	private String bcontent;
	private Timestamp bdate;
	private int bhit;
	private int bgroup;
	private int bstep;
	private int bindent;
}

BoardMapper.java

package edu.global.ex.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;

import edu.global.ex.page.Criteria;
import edu.global.ex.vo.BoardVO;

@Mapper
public interface BoardMapper{
	public List<BoardVO> getList();
	BoardVO read(int bid);	// 파라미터는 url로 넘어오는 bid값
	void insert(BoardVO board); // 글쓰기
	int delete(BoardVO board); // 글 삭제
	int modify(BoardVO board); // 수정
	public void hit(int bid);
	
	// 답글 관련
	void updateShape(BoardVO boardVO); // 답글 위치
	void insertReply(BoardVO boardVO); // 답글 등록
	
	// paging 관련
	int getTotalCount();
	public List<BoardVO> getListWithPaging(Criteria cri);
}

// 자식: BoardMapper.xml
// Mapper가 DAO, Service가 Command랑 비슷한 거

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">
	<select id="getList" resultType="edu.global.ex.vo.BoardVO">

		<!-- 여기 들어가는 문구는 xml이 아니라는걸 표현해주는거임. -->
    <![CDATA[	
      select * from mvc_board order by bgroup desc, bstep asc
    ]]>
	</select>

	<select id="read" resultType="BoardVO">
    <![CDATA[   
      select * from mvc_board where bid = #{bid}
    ]]>
   </select>

	<insert id="insert">		<!-- id에는 함수명이 들어가야함. -->
    <![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>
	
	<delete id="delete">
	<![CDATA[
	  delete from mvc_board where bid = #{bid}
	]]>
	</delete>
	
	<update id="modify">
	<![CDATA[
	  update mvc_board set btitle = #{btitle}, bcontent = #{bcontent} where bid = #{bid}
	]]>
	</update>
	
	<update id="hit">
	<![CDATA[
	  update mvc_board set bhit = bhit+1 where bid = #{bid}
	]]>
	</update>
	
	 <!--댓글을 하나씩 미뤄서 정렬을 해줘야 하기 때문에 
       세로 정렬을 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>
	
	<select id="getTotalCount" resultType="int">
    <![CDATA[   
      	select count(*) from mvc_board
    ]]>
   	</select>
	
	<select id="getListWithPaging" resultType="BoardVO">
      <![CDATA[
        SELECT * FROM (
              SELECT ROWNUM AS RNUM, A.* FROM (
                       SELECT
                             *
                         FROM
                             mvc_board 
                         order by bGroup desc, bStep asc   
             ) A WHERE ROWNUM <= #{pageNum} * #{amount}
         ) WHERE RNUM > (#{pageNum}-1) * #{amount}
      ]]>
   </select>
   
   
	
</mapper>

BoardService.java

package edu.global.ex.service;

import java.util.List;

import edu.global.ex.page.Criteria;
import edu.global.ex.vo.BoardVO;

public interface BoardService {
	public List<BoardVO> getList();
	BoardVO read(int bid);
	public void register(BoardVO boardVO);
	int remove(BoardVO board);
	int modify(BoardVO board);
	void registerReply(BoardVO board);
	
	// paging
	int getTotal();
	List<BoardVO> getList(Criteria criteria); // 리스트 메소드
}

//Mapper가 DAO, Service가 Command랑 비슷한 거

BoardServiceImpl.java

package edu.global.ex.serviceImpl;

import java.util.List;

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

import edu.global.ex.mapper.BoardMapper;
import edu.global.ex.page.Criteria;
import edu.global.ex.service.BoardService;
import edu.global.ex.vo.BoardVO;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class BoardServiceImpl implements BoardService{

	@Autowired
	BoardMapper boardmapper;
	@Override
	public List<BoardVO> getList() {
		List<BoardVO> list = boardmapper.getList();
		return list;
	}

	@Override
	public void register(BoardVO boardVO) {
		log.info("register()..");
		boardmapper.insert(boardVO);
	}

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

	@Override
	public int remove(BoardVO board) {
		log.info("remove()..");
		return boardmapper.delete(board);
	}
	
	@Override
	public int modify(BoardVO board) {
		log.info("modify()..");
		return boardmapper.modify(board);
	}
	
	@Transactional
	@Override
	public void registerReply(BoardVO board) {
		log.info("registerReply()..");
		boardmapper.updateShape(board);
		boardmapper.insertReply(board);
	}
	
	@Override
	   public int getTotal() {
	      log.info("getTotal() ..");
	      
	      return boardmapper.getTotalCount();
	   }

	   @Override
	   public List<BoardVO> getList(Criteria criteria) {
	      log.info("getList(Criteria criteria) ..");
	      
	      return boardmapper.getListWithPaging(criteria);
	   }
}

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 edu.global.ex.page.Criteria;
import edu.global.ex.page.PageVO;
import edu.global.ex.service.BoardService;
import edu.global.ex.vo.BoardVO;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Controller
public class BoardController {
	
	@Autowired
	private BoardService boardService;
	
	 //http://localhost:8282/list2?pageNum=5&amount=10">1</a>
	   @GetMapping("/list2")
	   public String list2(Criteria cri, Model model) {
	      log.info("list2() ..");
	      log.info("list2() Criteria " + cri);      
	      
	      model.addAttribute("boards", boardService.getList(cri));
	      
	      int total = boardService.getTotal();
	      log.info("total" + total);         
	      
	      model.addAttribute("pageMaker", new PageVO(cri, total));   
	      
	      return "list2";
	   }
	
	@GetMapping("/list")
	public String list(Model model) {
		log.info("list()..");
		model.addAttribute("boards", boardService.getList());
		
		return "list";
	}
	
	@GetMapping("/write_view")
	public String write_view() {
		log.info("write_view()..");
		
		return "write_view";
	}
	
	@GetMapping("/content_view")
	public String content_view(int bid, Model model) {
		log.info("content_view()..");
		
		model.addAttribute("result", boardService.read(bid));
		
		return "content_view";
	}
	
	@PostMapping("/write")
	public String write(BoardVO boardVO) {
		log.info("write()..");
		
		boardService.register(boardVO);
		
		return "redirect:list";
	}
	
	@GetMapping("/delete")
	public String delete(BoardVO boardVO) {
		log.info("delete()..");
		
		int rn = boardService.remove(boardVO);
		log.info("delete().. result number::" + rn);
		return "redirect:list";
	}
	
	@PostMapping("/modify")
	public String modify(BoardVO boardVO) {
		log.info("modify()..");
		
		boardService.modify(boardVO);
		
		return "redirect:list";
	}
	
	@GetMapping("/reply_view")
	public String reply_view(BoardVO boardVO, Model model) {
		log.info("reply_view()..");
		
		model.addAttribute("reply_view", boardService.read(boardVO.getBid()));
		
		return "reply_view";
	}
	
	@PostMapping("/reply")
	public String reply(BoardVO boardVO, Model model) {
		log.info("reply_view()..");
		
		boardService.registerReply(boardVO);
		
		return "redirect:list";
	}
	
	@GetMapping("/board/table")
	public String table(BoardVO boardVO, Model model) {
		log.info("table()..");
						// EL {}
		model.addAttribute("table", boardService.getList());
		
		return "table";
	}
}

list2.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- C태그 쓰기 위해 넣은 taglib므로 반드시 확인 --> 
    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
   <table width="500" border="1">
      <tr>
         <td>번호</td>
         <td>이름</td>
         <td>제목</td>
         <td>날짜</td>
         <td>히트</td>
      </tr>
   
        <!--이때 list는 BListCommand에서 메모리에 올린 list를 뜻함. 포워딩시까지 살아있으므로-->
        <!--forEach문을 이용해 데이터를 꺼낼 수 있다.-->
      <c:forEach var="board" items="${boards}">
         <tr>
            <td>${board.bid}</td>
            <td>${board.bname}</td>
            <td>
               <c:forEach begin="1" end="${board.bindent}">[Re]</c:forEach>
               <a href="content_view?bid=${board.bid}">${board.btitle}</a>
                    <!--bindent : 가로 (댓글이 보이는 순서 때문에 들어간 것)-->
            </td>
            <td>${board.bdate}</td>
            <td>${board.bhit}</td>            
         </tr>
      </c:forEach>
     
      <tr>
         <td colspan="5"> <a href="write_view">글 작성</a></td>
      </tr>
   </table>
   
        <c:if test="${pageMaker.prev}">
         <a href="list2${pageMaker.makeQuery(pageMaker.startPage - 1) }">«</a>
      </c:if>

      <c:forEach begin="${pageMaker.startPage }" end="${pageMaker.endPage }" var="idx">
         <c:out value="${pageMaker.cri.pageNum == idx?'':''}" />
         <a href="list2${pageMaker.makeQuery(idx)}">${idx}</a>
      </c:forEach>
      
      <c:if test="${pageMaker.next && pageMaker.endPage > 0}">
         <a href="list2${pageMaker.makeQuery(pageMaker.endPage +1) }"> » </a>
      </c:if> <br>

</body>
</html>

2. 아래의 @를 설명하시오.

@Component

개발자가 직접 작성한 Class를 Bean으로 등록하고, DI를 위한 가장 기본적인 어노테이션
Spring에서 관리되는 객체임을 표시하기 위해 사용하는 가장 기본적인 annotation

@Controller

Web MVC에 사용되는 어노테이션이다. (해당 클래스를 MVC 모듈의 컨트롤러로 인식하게 해준다.)
@RequestMapping, @GetMapping과 같은 URI 요청 어노테이션은 @Controller가 붙은 클래스에서만 동작한다.

@Service

@Component와 다른 기능은 없지만 비즈니스 로직에 해당 어노테이션을 사용하여 명시적으로 비즈니스 로직을 가지고 있는 클래스임을 나타내게 해준다.

@Repository

해당 클래스를 데이터 접근 계층으로 인식하며, 데이터 계층의 예외를 추상화하여 스프링 예외로 변환하여 던져준다.

@Component, @Service, @Repository는 Bean객체를 만드는 역할을 한다. @Component가 가장 큰 단위고 @Service, @Repository 등을 구체적으로 사용하면 어떤 부분에 쓰이는지 시각적으로 판단하기 편하다.

@Mapper

Interface를 매퍼로 등록하기 위해 사용한다.

@SpringBootApplication

Spring Boot에서 어플리케이션을 실행한다.

@SpringBootTest

@SpringBootApplication을 찾아서 테스트를 위한 빈들을 생성한다.

3. 다음 SQL문을 작성하시오.

-- 이름에 A가 들어가는 모든 사원의 이름과 부서 이름을 출력하라.
SELECT E.ENAME, D.DNAME FROM EMP E, DEPT D WHERE E.DEPTNO = D.DEPTNO 
AND E.ENAME LIKE '%A%';

-- 커미션이 책정되어 있는 모든 사원의 이름, 부서이름 및 위치를 출력하라.
SELECT E.ENAME, D.DNAME FROM EMP E, DEPT D WHERE E.DEPTNO = D.DEPTNO 
AND E.COMM IS NOT NULL;

-- DALLAS에서 근무하는 모든 사원의 이름, 직업, 부서번호 및 부서이름을 출력하라.
SELECT E.ENAME, E.JOB, D.DNAME, E.DEPTNO FROM EMP E, DEPT D 
WHERE E.DEPTNO = D.DEPTNO AND D.LOC = 'DALLAS';

-- 모든 사원의 이름, 직업, 부서이름, 급여 및 등급을 출력하라.
SELECT E.ENAME, E.JOB, D.DNAME, S.GRADE FROM EMP E, DEPT D, SALGRADE S 
WHERE E.DEPTNO = D.DEPTNO AND E.SAL BETWEEN S.LOSAL AND S.HISAL;

-- Smith보다 늦게 입사한 사원의 이름 및 입사일을 출력하라.
SELECT ENAME, HIREDATE FROM EMP WHERE HIREDATE > 
(SELECT HIREDATE FROM EMP WHERE ENAME = 'SMITH');

-- 모든 사원의 급여 최고액, 최저액, 총액 및 평균액을 출력하라.
SELECT MAX(SAL) AS Maximum, MIN(SAL) AS Minimum, SUM(SAL) AS Sum, 
AVG(SAL) AS Average FROM EMP;

-- 각 직업별로 급여 최저액, 최고액, 총액 및 평균액을 출력하라.
SELECT JOB, MIN(SAL), MAX(SAL), SUM(SAL), AVG(SAL) FROM EMP GROUP BY JOB;

-- 직업이 동일한 사람 수를 직업과 같이 출력하라.
SELECT JOB, COUNT(*) FROM EMP GROUP BY JOB;
profile
띵호와

0개의 댓글