실습
- [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 |