본문 바로가기

웹 개발/Spring

[Web_Spring] 13

실습

- [Web_Spring] 12 이어서

 

 

 

1. src/main/resource/mapper/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="com.example.board.mapper.BoardMapper">
    <select id="getList" resultType="boardVO">
        <![CDATA[
            SELECT BOARD_NUMBER, BOARD_TITLE, BOARD_CONTENT, BOARD_WRITER, BOARD_REGISTER_DATE, BOARD_UPDATE_DATE
            FROM
            (
                SELECT /*+ INDEX_DESC(TBL_BOARD PK_BOARD) */
                ROWNUM RN, BOARD_NUMBER, BOARD_TITLE, BOARD_CONTENT, BOARD_WRITER, BOARD_REGISTER_DATE, BOARD_UPDATE_DATE
                FROM TBL_BOARD
                WHERE ROWNUM <= #{pageNum} * #{amount}
            )
            WHERE RN > (#{pageNum} - 1) * #{amount}
        ]]>
    </select> 

    <insert id="insert">
        <selectKey keyProperty="boardNumber" order="BEFORE" resultType="long">
            SELECT SEQ_BOARD.NEXTVAL FROM DUAL
        </selectKey>
        INSERT INTO TBL_BOARD (BOARD_NUMBER, BOARD_TITLE, BOARD_CONTENT, BOARD_WRITER)
        VALUES (#{boardNumber}, #{boardTitle}, #{boardContent}, #{boardWriter})
    </insert>

    <select id="select" resultType="boardVO">
        SELECT BOARD_NUMBER, BOARD_TITLE, BOARD_CONTENT, BOARD_WRITER, BOARD_REGISTER_DATE, BOARD_UPDATE_DATE
        FROM TBL_BOARD
        WHERE BOARD_NUMBER = #{boardNumber}
    </select>

    <update id="update">
        UPDATE TBL_BOARD
        SET BOARD_TITLE = #{boardTitle}, BOARD_CONTENT = #{boardContent}, BOARD_UPDATE_DATE = SYSDATE
        WHERE BOARD_NUMBER = #{boardNumber}
    </update>

    <delete id="delete">
        DELETE FROM TBL_BOARD
        WHERE BOARD_NUMBER = #{boardNumber}
    </delete>

    <select id="getTotal" resultType="_int">
        SELECT COUNT(BOARD_NUMBER) FROM TBL_BOARD
    </select>

</mapper>

 

 

 

2. src/main/java/com.example.board/mapper/BoardMapper.java

package com.example.board.mapper;

import com.example.board.domain.vo.BoardVO;
import com.example.board.domain.vo.Criteria;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface BoardMapper {
    //    게시글 목록
    public List<BoardVO> getList(Criteria criteria);
    //    게시글 추가
    public void insert(BoardVO boardVO);
    //    게시글 한 개 가져오기
    public BoardVO select(Long boardNumber);
    //    게시글 수정
    public int update(BoardVO boardVO);
    //    게시글 삭제
    public int delete(Long boardNumber);
    //    게시글 전체 개수
    public int getTotal();
}

 

 

 

3. src/main/java/com.example.board/domain/dao/BoardDAO.java​

package com.example.board.domain.dao;

import com.example.board.domain.vo.BoardVO;
import com.example.board.domain.vo.Criteria;
import com.example.board.mapper.BoardMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
// RDB에 가깝던 mapper 인터페이스를
// 객체에 가깝게 변경시켜주는 역할
@RequiredArgsConstructor
public class BoardDAO {
    private final BoardMapper boardMapper;

    //    게시글 목록
    public List<BoardVO> getList(Criteria criteria){
        return boardMapper.getList(criteria);
    }
    //    게시글 추가 
    public void register(BoardVO boardVO){
        boardMapper.insert(boardVO);
    }
    //    게시글 한 개 가져오기
    public BoardVO findByBoardNumber(Long boardNumber){
        return boardMapper.select(boardNumber);
    }
    //    게시글 수정
    public boolean modify(BoardVO boardVO){
        return boardMapper.update(boardVO) == 1;
    }
    //    게시글 삭제
    public boolean remove(Long boardNumber){
        return boardMapper.delete(boardNumber) == 1;
    }
    //    게시글 전체 개수
    public int getTotal(){
        return boardMapper.getTotal();
    }

}

 

 

 

4. src/main/java/com.example.board/domain/vo/Criteria.java​

package com.example.board.domain.vo;

import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.stereotype.Component;

@Component
@Data
@AllArgsConstructor
public class Criteria {
    private Integer pageNum;
    private Integer amount;

    public Criteria() {
        this(1, 10);
    }
}

 

 

 

5. src/main/java/com.example.board/domain/vo/PageDTO.java​

package com.example.board.domain.vo;

import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestParam;

@Component
@Data
@NoArgsConstructor
public class PageDTO {
    private Integer startPage;
    private Integer endPage;
    private Integer realEnd;
    private boolean next, prev;
    private Integer total;
    private Criteria criteria; 

    public PageDTO(Criteria criteria, Integer total){
        this.criteria = criteria;
        this.total = total;

        this.endPage = (int)(Math.ceil(criteria.getPageNum() / (double)criteria.getAmount())) * criteria.getAmount();
        this.startPage = this.endPage - 9;
        this.realEnd = (int)Math.ceil(total / (double)criteria.getAmount());

        if(realEnd < this.endPage){
            this.endPage = realEnd;
        }

        this.prev = this.startPage > 1;
        this.next = this.endPage < realEnd;
    }

}

 

 

 

6. src/main/java/com.example.board/controller/BoardController.java​

package com.example.board.controller;

import com.example.board.domain.vo.BoardVO;
import com.example.board.domain.vo.Criteria;
import com.example.board.domain.vo.PageDTO;
import com.example.board.service.BoardService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
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 org.springframework.web.servlet.view.RedirectView;

import javax.servlet.http.HttpServletRequest; 

/*
 *   TASK        URL                 METHOD      PARAMETER       FORM        URL이동
 *
 *   전체목록    /board/list          GET         없음             없음
 *   등록       /board/register      POST         모든 항목        필요          /board/list
 *   조회       /board/read          GET          boardNumber     없음
 *   삭제       /board/remove        POST         boardNumber     없음          /board/list
 *   수정       /board/modify        POST         모든 항목        필요          /board/read
 *
 * */
@Controller
@Slf4j
@RequiredArgsConstructor
@RequestMapping("/board/*")
public class BoardController {
    private final BoardService boardService;

    @GetMapping("register")
    public void register(){}

    @GetMapping("list")
    public String getList(Criteria criteria, Model model){
        log.info("----------------------------");
        log.info("list.............");
        log.info("----------------------------");

        model.addAttribute("boardList", boardService.getList(criteria));
        model.addAttribute("pageDTO", new PageDTO(criteria, boardService.getTotal()));
        return "/board/list";
    }

    @PostMapping("register")
//    매개변수에 선언된 객체는 자동으로 화면에 전달되므로,
//    이를 막기 위해서는 redirect 방식의 전송이 필요하다.
    public RedirectView register(BoardVO boardVO, RedirectAttributes rttr){
        log.info("----------------------------");
        log.info("register............. : " + boardVO);
        log.info("----------------------------");

        boardService.register(boardVO);
//        1. Flash 사용
//         세션에 파라미터를 저장하고, request 객체가 초기화된 후 다시 request에 담아준다.
        rttr.addFlashAttribute("boardNumber", boardVO.getBoardNumber());

//        2. 쿼리 스트링
//        rttr.addAttribute("boardNumber", boardVO.getBoardNumber());
        return new RedirectView("/board/list");
    }

    //    게시글 상세보기
    @GetMapping({"read", "modify"})
    public void read(Long boardNumber, HttpServletRequest req, Model model){
        log.info("----------------------------");
        log.info(req.getRequestURI() + "............. : " + boardNumber);
        log.info("----------------------------");
        model.addAttribute("board", boardService.get(boardNumber));
    }

    //    수정
    @PostMapping("modify")
    public RedirectView modify(BoardVO boardVO, RedirectAttributes rttr){
        log.info("----------------------------");
        log.info("modify............. : " + boardVO);
        log.info("----------------------------");
        boardService.modify(boardVO);
//        컨트롤러에서 다른 컨트롤러의 매개변수로 파라미터를 전달할 때에는
//        addAttribute(), 쿼리스트링 방식으로 전달해야 받을 수 있다.
//        Flash방식은 최종 응답 화면에서 사용될 파라미터를 전달할 때에만 사용하도록 한다.
        rttr.addAttribute("boardNumber", boardVO.getBoardNumber());
        return new RedirectView("/board/read");
    }

    //    삭제
    @PostMapping("remove")
    public String remove(Long boardNumber, Criteria criteria, Model model){
        log.info("----------------------------");
        log.info("remove............. : " + boardNumber);
        log.info("----------------------------");

        boardService.remove(boardNumber);
        return getList(criteria, model);
    }
}

 

 

 

7. src/test/java/com.example.board/mapper/BoardMapperTests.java​

package com.example.board.mapper;

import com.example.board.domain.vo.BoardVO;
import com.example.board.domain.vo.Criteria;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
@Slf4j
public class BoardMapperTests {
    @Autowired
    private BoardMapper boardMapper;

    @Test 
    public void getListTest(){
        boardMapper.getList(new Criteria()).stream().map(BoardVO::toString).forEach(log::info);
    }

//    @Test
//    public void insertTest(){
//        BoardVO boardVO = new BoardVO();
//        boardVO.setBoardTitle("새롭게 추가된 게시글 제목1");
//        boardVO.setBoardContent("새롭게 추가된 게시글 내용1");
//        boardVO.setBoardWriter("new1");
//        boardMapper.insert(boardVO);
//        log.info("추가된 게시글 번호 : " + boardVO.getBoardNumber());
//    }

//    @Test
//    public void selectTest(){
//        log.info(boardMapper.select(2561L).toString());
//    }

//    @Test
//    public void updateTest(){
//        BoardVO boardVO = boardMapper.select(2581L);
//        boardVO.setBoardTitle("수정된 게시글 제목");
//        boardVO.setBoardContent("수정된 게시글 내용");
//
//        log.info("UPDATE COUNT : " + boardMapper.update(boardVO));
//    }

//    @Test
//    public void deleteTest(){
//        log.info("DELETE COUNT : " + boardMapper.delete(2581L));
//    }

//    @Test
//    public void getTotalTest(){
//        log.info("총 게시글 : " + boardMapper.getTotal());
//    }

}

 

 

 

8. src/main/java/com.example.board/service/BoardService.java​

package com.example.board.service;

import com.example.board.domain.vo.BoardVO;
import com.example.board.domain.vo.Criteria;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public interface BoardService {
    public List<BoardVO> getList(Criteria criteria);
    public void register(BoardVO boardVO);
    public BoardVO get(Long boardNumber);
    public boolean modify(BoardVO boardVO);
    public boolean remove(Long boardNumber);
    public int getTotal();
}

 

 

 

9. src/main/java/com.example.board/service/BoardServiceImpl.java​

package com.example.board.service;

import com.example.board.domain.dao.BoardDAO;
import com.example.board.domain.vo.BoardVO;
import com.example.board.domain.vo.Criteria;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.util.List;
 
//    Service
//    여러 개의 DML을 하나의 서비스로 묶어준다.
@Service
@RequiredArgsConstructor
@Qualifier("board") @Primary
public class BoardServiceImpl implements BoardService{
    private final BoardDAO boardDAO;

    @Override
    public List<BoardVO> getList(Criteria criteria) {return boardDAO.getList(criteria);}

    @Override
    public void register(BoardVO boardVO) {boardDAO.register(boardVO);}

    @Override
    public BoardVO get(Long boardNumber) {
        return boardDAO.findByBoardNumber(boardNumber);
    }

    @Override
    public boolean modify(BoardVO boardVO) {
        return boardDAO.modify(boardVO);
    }

    @Override
    public boolean remove(Long boardNumber) {
        return boardDAO.remove(boardNumber);
    }

    @Override
    public int getTotal() {
        return boardDAO.getTotal();
    }
}

 

 

 

 

'웹 개발 > Spring' 카테고리의 다른 글

[Web_Spring] 15  (0) 2022.06.27
[Web_Spring] 14  (0) 2022.06.26
[Web_Spring] 12  (0) 2022.06.24
[Web_Spring] 11  (0) 2022.06.23
[Web_Spring] 10  (0) 2022.06.22