getter/setter를 만들어주기 위해
변수에 private를 붙여주었다.
<code />
package com.fastcampus.ch4.domain;
public class PageHandler {
private int totalCnt; //총 게시물 개수
private int pageSize; //한 페이지의 크기
private int naviSize=10; //페이지 네비게이션의 크기
private int totalPage; //전체 페이지의 갯수
private int page; //현재 페이지
private int beginPage; //네비게이션의 첫번째 페이지
private int endPage; // 네비게이션의 마지막 페이지
private boolean showPrev; //이전 페이지로 이동하는 링크를 보여줄 것인지의 여부
private boolean showNext; //다음 페이지로 이동하는 링크를 보여줄 것인지의 여부
public PageHandler(int totalCnt,int page){ //2개의 변수만 줬을 때에는, pageSize를 10으로 준다
this(totalCnt,page,10);
}
public PageHandler(int totalCnt,int page, int pageSize){ //페이징 계산하는데 필요한 변수3개로 생성자 만들기
this.totalCnt=totalCnt;
this.page=page;
this.pageSize=pageSize;
totalPage = (int)Math.ceil(totalCnt/(double)pageSize); //Math.ceil=올림, double로 나오므로 int화
beginPage = page/naviSize*naviSize+1; //일의 자릿수를 버리기
endPage = Math.min(beginPage + naviSize -1 ,totalPage);
showPrev=beginPage!=1; //beginPage가 1만 아니면 된다.(1만 아니면 이전으로 가는 버튼을 보여준다)
showNext=endPage!=totalPage;
}
public int getTotalCnt() {
return totalCnt;
}
public void setTotalCnt(int totalCnt) {
this.totalCnt = totalCnt;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getNaviSize() {
return naviSize;
}
public void setNaviSize(int naviSize) {
this.naviSize = naviSize;
}
public int getTotalPage() {
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getBeginPage() {
return beginPage;
}
public void setBeginPage(int beginPage) {
this.beginPage = beginPage;
}
public int getEndPage() {
return endPage;
}
public void setEndPage(int endPage) {
this.endPage = endPage;
}
public boolean isShowPrev() {
return showPrev;
}
public void setShowPrev(boolean showPrev) {
this.showPrev = showPrev;
}
public boolean isShowNext() {
return showNext;
}
public void setShowNext(boolean showNext) {
this.showNext = showNext;
}
void print(){
System.out.println("page = "+page);
System.out.print(showPrev ? "[PREV]" : "");
for (int i = beginPage; i <= endPage; i++) {
System.out.print(i+" ");
}
System.out.println(showNext? "[NEXT]" : "");
}
@Override
public String toString() {
return "PageHandler{" +
"totalCnt=" + totalCnt +
", pageSize=" + pageSize +
", naviSize=" + naviSize +
", totalPage=" + totalPage +
", page=" + page +
", beginPage=" + beginPage +
", endPage=" + endPage +
", showPrev=" + showPrev +
", showNext=" + showNext +
'}';
}
}
private로 바꿔줘서 테스트 코드에 문제가 생겼는데
getter 코드로 바꿔주었다.
<code />
package com.fastcampus.ch4.domain;
import org.junit.Test;
import static org.junit.Assert.*;
public class PageHandlerTest {
@Test
public void test(){
PageHandler ph = new PageHandler(250,1);
ph.print();
System.out.println("ph = "+ph);
assertTrue(ph.getBeginPage() ==1);
assertTrue(ph.getEndPage() ==10);
}
@Test
public void test2(){
PageHandler ph = new PageHandler(250,11);
ph.print();
System.out.println("ph = "+ph);
assertTrue(ph.getBeginPage() ==11);
assertTrue(ph.getEndPage() ==20);
}
@Test
public void test3(){
PageHandler ph = new PageHandler(255,25);
ph.print();
System.out.println("ph = "+ph);
assertTrue(ph.getBeginPage() ==21);
assertTrue(ph.getEndPage() ==26);
}
}
테스트 성공
저번 시간에 한 내용 복습하면서
boardMapper.xml을 확인,
xml에 sql을 작성한 뒤에
boardDaoImpl에
dao를 작성하고 session을 주입받고, namespace를 적는다.
( boardDaoImpl의 메소드로 호출을 하면 boardMapper.xml에서 sql문으로 실행되고,
다시 메소드로 반환을 해준다. )
메소드들을 전부 다 작성해주면 (우리는 강사님 깃허브에서 긁어왔다)
BoardDaoImpl에서 Implement를 해주던 BoardDao를 삭제하고 다시 만들어준다.
<code />
package com.fastcampus.ch4.dao;
import com.fastcampus.ch4.domain.BoardDto;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Repository
public class BoardDaoImpl implements BoardDao {
@Autowired
SqlSession session;
String namespace="com.fastcampus.ch4.dao.BoardMapper.";
@Override
public int count() throws Exception {
return session.selectOne(namespace+"count");
} // T selectOne(String statement)
@Override
public int deleteAll() {
return session.delete(namespace+"deleteAll");
} // int delete(String statement)
@Override
public int delete(Integer bno, String writer) throws Exception {
Map map = new HashMap();
map.put("bno", bno);
map.put("writer", writer);
return session.delete(namespace+"delete", map);
} // int delete(String statement, Object parameter)
@Override
public int insert(BoardDto dto) throws Exception {
return session.insert(namespace+"insert", dto);
} // int insert(String statement, Object parameter)
@Override
public List<BoardDto> selectAll() throws Exception {
return session.selectList(namespace+"selectAll");
} // List<E> selectList(String statement)
@Override
public BoardDto select(Integer bno) throws Exception {
return session.selectOne(namespace + "select", bno);
} // T selectOne(String statement, Object parameter)
@Override
public List<BoardDto> selectPage(Map map) throws Exception {
return session.selectList(namespace+"selectPage", map);
} // List<E> selectList(String statement, Object parameter)
@Override
public int update(BoardDto dto) throws Exception {
return session.update(namespace+"update", dto);
} // int update(String statement, Object parameter)
@Override
public int increaseViewCnt(Integer bno) throws Exception {
return session.update(namespace+"increaseViewCnt", bno);
} // int update(String statement, Object parameter)
}
오른쪽 클릭 후 refactor > Extract Interface

<java />
package com.fastcampus.ch4.dao;
import com.fastcampus.ch4.domain.BoardDto;
import java.util.List;
import java.util.Map;
public interface BoardDao {
int count() throws Exception // T selectOne(String statement)
;
int deleteAll() // int delete(String statement)
;
int delete(Integer bno, String writer) throws Exception // int delete(String statement, Object parameter)
;
int insert(BoardDto dto) throws Exception // int insert(String statement, Object parameter)
;
List<BoardDto> selectAll() throws Exception // List<E> selectList(String statement)
;
BoardDto select(Integer bno) throws Exception // T selectOne(String statement, Object parameter)
;
List<BoardDto> selectPage(Map map) throws Exception // List<E> selectList(String statement, Object parameter)
;
int update(BoardDto dto) throws Exception // int update(String statement, Object parameter)
;
int increaseViewCnt(Integer bno) throws Exception // int update(String statement, Object parameter)
;
}
DB에 테이블을 만들고,
xml에 sql을 작성한 다음에, 이것을 토대로 DAO를 하나씩 만들면 된다.
SQLsession을 주입받고, sql실행하는 데 뭐가 필요하고 결과가 뭐가 오는지에 대해 하나씩 만들면 된다.
BoardDaoImpl도 만들었으니 테스트를 해본다.
<java />
package com.fastcampus.ch4.dao;
import com.fastcampus.ch4.domain.*;
import org.junit.*;
import org.junit.runner.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.test.context.*;
import org.springframework.test.context.junit4.*;
import java.util.*;
import static org.junit.Assert.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"file:src/main/webapp/WEB-INF/spring/root-context.xml"})
public class BoardDaoImplTest {
@Autowired
private BoardDao boardDao;
@Test
public void countTest() throws Exception {
boardDao.deleteAll();
assertTrue(boardDao.count()==0);
BoardDto boardDto = new BoardDto("no title", "no content", "asdf");
assertTrue(boardDao.insert(boardDto)==1);
assertTrue(boardDao.count()==1);
assertTrue(boardDao.insert(boardDto)==1);
assertTrue(boardDao.count()==2);
}
@Test
public void deleteAllTest() throws Exception {
boardDao.deleteAll();
assertTrue(boardDao.count()==0);
BoardDto boardDto = new BoardDto("no title", "no content", "asdf");
assertTrue(boardDao.insert(boardDto)==1);
assertTrue(boardDao.deleteAll()==1);
assertTrue(boardDao.count()==0);
boardDto = new BoardDto("no title", "no content", "asdf");
assertTrue(boardDao.insert(boardDto)==1);
assertTrue(boardDao.insert(boardDto)==1);
assertTrue(boardDao.deleteAll()==2);
assertTrue(boardDao.count()==0);
}
@Test
public void deleteTest() throws Exception {
boardDao.deleteAll();
assertTrue(boardDao.count()==0);
BoardDto boardDto = new BoardDto("no title", "no content", "asdf");
assertTrue(boardDao.insert(boardDto)==1);
Integer bno = boardDao.selectAll().get(0).getBno();
assertTrue(boardDao.delete(bno, boardDto.getWriter())==1);
assertTrue(boardDao.count()==0);
assertTrue(boardDao.insert(boardDto)==1);
bno = boardDao.selectAll().get(0).getBno();
assertTrue(boardDao.delete(bno, boardDto.getWriter()+"222")==0);
assertTrue(boardDao.count()==1);
assertTrue(boardDao.delete(bno, boardDto.getWriter())==1);
assertTrue(boardDao.count()==0);
assertTrue(boardDao.insert(boardDto)==1);
bno = boardDao.selectAll().get(0).getBno();
assertTrue(boardDao.delete(bno+1, boardDto.getWriter())==0);
assertTrue(boardDao.count()==1);
}
@Test
public void insertTest() throws Exception {
boardDao.deleteAll();
BoardDto boardDto = new BoardDto("no title", "no content", "asdf");
assertTrue(boardDao.insert(boardDto)==1);
boardDto = new BoardDto("no title", "no content", "asdf");
assertTrue(boardDao.insert(boardDto)==1);
assertTrue(boardDao.count()==2);
boardDao.deleteAll();
boardDto = new BoardDto("no title", "no content", "asdf");
assertTrue(boardDao.insert(boardDto)==1);
assertTrue(boardDao.count()==1);
}
@Test
public void selectAllTest() throws Exception {
boardDao.deleteAll();
assertTrue(boardDao.count()==0);
List<BoardDto> list = boardDao.selectAll();
assertTrue(list.size() == 0);
BoardDto boardDto = new BoardDto("no title", "no content", "asdf");
assertTrue(boardDao.insert(boardDto)==1);
list = boardDao.selectAll();
assertTrue(list.size() == 1);
assertTrue(boardDao.insert(boardDto)==1);
list = boardDao.selectAll();
assertTrue(list.size() == 2);
}
@Test
public void selectTest() throws Exception {
boardDao.deleteAll();
assertTrue(boardDao.count()==0);
BoardDto boardDto = new BoardDto("no title", "no content", "asdf");
assertTrue(boardDao.insert(boardDto)==1);
Integer bno = boardDao.selectAll().get(0).getBno();
boardDto.setBno(bno);
BoardDto boardDto2 = boardDao.select(bno);
assertTrue(boardDto.equals(boardDto2));
}
@Test
public void selectPageTest() throws Exception {
boardDao.deleteAll();
for (int i = 1; i <= 10; i++) {
BoardDto boardDto = new BoardDto(""+i, "no content"+i, "asdf");
boardDao.insert(boardDto);
}
Map map = new HashMap();
map.put("offset", 0);
map.put("pageSize", 3);
List<BoardDto> list = boardDao.selectPage(map);
assertTrue(list.get(0).getTitle().equals("10"));
assertTrue(list.get(1).getTitle().equals("9"));
assertTrue(list.get(2).getTitle().equals("8"));
map = new HashMap();
map.put("offset", 0);
map.put("pageSize", 1);
list = boardDao.selectPage(map);
assertTrue(list.get(0).getTitle().equals("10"));
map = new HashMap();
map.put("offset", 7);
map.put("pageSize", 3);
list = boardDao.selectPage(map);
assertTrue(list.get(0).getTitle().equals("3"));
assertTrue(list.get(1).getTitle().equals("2"));
assertTrue(list.get(2).getTitle().equals("1"));
}
@Test
public void updateTest() throws Exception {
boardDao.deleteAll();
BoardDto boardDto = new BoardDto("no title", "no content", "asdf");
assertTrue(boardDao.insert(boardDto)==1);
Integer bno = boardDao.selectAll().get(0).getBno();
System.out.println("bno = " + bno);
boardDto.setBno(bno);
boardDto.setTitle("yes title");
assertTrue(boardDao.update(boardDto)==1);
BoardDto boardDto2 = boardDao.select(bno);
assertTrue(boardDto.equals(boardDto2));
}
@Test
public void increaseViewCntTest() throws Exception {
boardDao.deleteAll();
assertTrue(boardDao.count()==0);
BoardDto boardDto = new BoardDto("no title", "no content", "asdf");
assertTrue(boardDao.insert(boardDto)==1);
assertTrue(boardDao.count()==1);
Integer bno = boardDao.selectAll().get(0).getBno();
assertTrue(boardDao.increaseViewCnt(bno)==1);
boardDto = boardDao.select(bno);
assertTrue(boardDto!=null);
assertTrue(boardDto.getView_cnt() == 1);
assertTrue(boardDao.increaseViewCnt(bno)==1);
boardDto = boardDao.select(bno);
assertTrue(boardDto!=null);
assertTrue(boardDto.getView_cnt() == 2);
}
}
테스트 통과
이제는 서비스를 만든다.
boardService.java를 만든 뒤에
boardDao를 주입받았다.
코드를 작성하는데 시간이 오래 걸려 강사님 깃허브에서 긁어오기로 했다...
boardServiceImpl.java를 다 긁어온 뒤
boardService.java에 붙여주었다.
boardService.java의 이름을 boardServiceImpl로 바꿔준 다음에 아까와 같은 방식으로 BoardService를 implements로 따로 빼주었다.
<code />
package com.fastcampus.ch4.service;
import com.fastcampus.ch4.dao.BoardDao;
import com.fastcampus.ch4.domain.BoardDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
@Service
public class BoardServiceImpl implements BoardService {
@Autowired
BoardDao boardDao;
@Override
public int getCount() throws Exception {
return boardDao.count();
}
@Override
public int remove(Integer bno, String writer) throws Exception {
return boardDao.delete(bno, writer);
}
@Override
public int write(BoardDto boardDto) throws Exception {
return boardDao.insert(boardDto);
}
@Override
public List<BoardDto> getList() throws Exception {
return boardDao.selectAll();
}
@Override
public BoardDto read(Integer bno) throws Exception {
BoardDto boardDto = boardDao.select(bno);
boardDao.increaseViewCnt(bno);
return boardDto;
}
@Override
public List<BoardDto> getPage(Map map) throws Exception {
return boardDao.selectPage(map);
}
@Override
public int modify(BoardDto boardDto) throws Exception {
return boardDao.update(boardDto);
}
}
controller를 만들어준다.
BoardController는 기본적으로 로그인 체크가 중요하기 때문에
ch2에 있는 코드를 가져와서 쓴다.
<java />
package com.fastcampus.ch4.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/board")
public class BoardController {
@GetMapping("/list")
public String list(HttpServletRequest request) {
if(!loginCheck(request))
return "redirect:/login/login?toURL="+request.getRequestURL(); // 로그인을 안했으면 로그인 화면으로 이동
return "boardList"; // 로그인을 한 상태이면, 게시판 화면으로 이동
}
private boolean loginCheck(HttpServletRequest request) {
// 1. 세션을 얻어서
HttpSession session = request.getSession();
// 2. 세션에 id가 있는지 확인, 있으면 true를 반환
return session.getAttribute("id")!=null;
}
}
boardList.jsp도 가져온다.
<java />
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>fastcampus</title>
<link rel="stylesheet" href="<c:url value='/css/menu.css'/>">
</head>
<body>
<div id="menu">
<ul>
<li id="logo">fastcampus</li>
<li><a href="<c:url value='/'/>">Home</a></li>
<li><a href="<c:url value='/board/list'/>">Board</a></li>
<li><a href="<c:url value='/login/login'/>">login</a></li>
<li><a href="<c:url value='/register/add'/>">Sign in</a></li>
<li><a href=""><i class="fas fa-search small"></i></a></li>
</ul>
</div><div style="text-align:center">
<h1>This is BOARD</h1>
<h1>This is BOARD</h1>
<h1>This is BOARD</h1>
<h1>This is BOARD</h1>
<h1>This is BOARD</h1>
</div>
</body>
</html>
page와 pageSize를 받아온 뒤,
<code />
public String list(int page, int pageSize, HttpServletRequest request)
Map을 만들어서 Map에 넣어준다.
<code />
Map map = new HashMap();
map.put("offset",(page-1)*pageSize);
map.put("pageSize",pageSize);
그 다음 boardSevice를 호출해준다.
<code />
boardService.getPage(map);
그리고 예외처리를 해준다.
<code />
try {
Map map = new HashMap();
map.put("offset",(page-1)*pageSize);
map.put("pageSize",pageSize);
boardService.getPage(map);
} catch (Exception e) {
throw new RuntimeException(e);
}
list로 받아준 뒤
<code />
try {
Map map = new HashMap();
map.put("offset",(page-1)*pageSize);
map.put("pageSize",pageSize);
List<BoardDto> list = boardService.getPage(map);
모델에 넣어준다.
<code />
m.addAttribute("List",list);
<code />
public String list(int page, int pageSize, Model m, HttpServletRequest request) {
최종 코드
<code />
package com.fastcampus.ch4.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import com.fastcampus.ch4.domain.BoardDto;
import com.fastcampus.ch4.service.BoardService;
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.RequestMapping;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Controller
@RequestMapping("/board")
public class BoardController {
@Autowired
BoardService boardService;
@GetMapping("/list")
public String list(int page, int pageSize, Model m, HttpServletRequest request) {
if(!loginCheck(request))
return "redirect:/login/login?toURL="+request.getRequestURL(); // 로그인을 안했으면 로그인 화면으로 이동
try {
Map map = new HashMap();
map.put("offset",(page-1)*pageSize);
map.put("pageSize",pageSize);
List<BoardDto> list = boardService.getPage(map);
m.addAttribute("List",list);
} catch (Exception e) {
throw new RuntimeException(e);
}
return "boardList"; // 로그인을 한 상태이면, 게시판 화면으로 이동
}
private boolean loginCheck(HttpServletRequest request) {
// 1. 세션을 얻어서
HttpSession session = request.getSession();
// 2. 세션에 id가 있는지 확인, 있으면 true를 반환
return session.getAttribute("id")!=null;
}
}
boardlist.jsp를 만져본다
<code />
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>fastcampus</title>
<link rel="stylesheet" href="<c:url value='/css/menu.css'/>">
</head>
<body>
<div id="menu">
<ul>
<li id="logo">fastcampus</li>
<li><a href="<c:url value='/'/>">Home</a></li>
<li><a href="<c:url value='/board/list'/>">Board</a></li>
<li><a href="<c:url value='/login/login'/>">login</a></li>
<li><a href="<c:url value='/register/add'/>">Sign in</a></li>
<li><a href=""><i class="fas fa-search small"></i></a></li>
</ul>
</div><div style="text-align:center">
<table border="1">
<tr>
<th>번호</th>
<th>제목</th>
<th>이름</th>
<th>등록일</th>
<th>조회수</th>
</tr>
<c:forEach var="board" items="$(list)">
<tr>
<td>${board.bno}</td>
<td>${board.title}</td>
<td>${board.writer}</td>
<td>${board.reg_date}</td>
<td>${board.view_cnt}</td>
</tr>
</c:forEach>
</table>
</div>
</body>
</html>
작성 후 서버를 돌렸더니 아래와 같은 오류 발생

boardController.java의
int page, int pageSize 값이 안들어왔는데
null값이 int로 변환되어야 하니 에러가 난 것이다.
그래서 주소창에 직접 page와 pageSize 값을 쳐주면 에러가 나지 않는다.

로그인에서 에러->

try에 있던 구문을 아래로 내려주니 해결되었다
setString이 된 후 pstmt.executeQuery를 실행해주어야 한다고 한다

잘 나온당
테이블 아래에 네비게이션을 만들어본다.
BoardController.java
<code />
@Controller
@RequestMapping("/board")
public class BoardController {
@Autowired
BoardService boardService;
@GetMapping("/list")
public String list(Integer page, Integer pageSize, Model m, HttpServletRequest request) {
if(!loginCheck(request))
return "redirect:/login/login?toURL="+request.getRequestURL(); // 로그인을 안했으면 로그인 화면으로 이동
if(page==null) page=1;
if(pageSize==null) pageSize=10;
try {
int totalCnt = boardService.getCount();
PageHandler pageHandler = new PageHandler(totalCnt,page,pageSize); //페이지 네비게이션 1
Map map = new HashMap();
map.put("offset", (page-1)*pageSize);
map.put("pageSize", pageSize);
List<BoardDto> list = boardService.getPage(map);
m.addAttribute("list", list);
m.addAttribute("ph",pageHandler); //페이지 네비게이션 2
} catch (Exception e) {
throw new RuntimeException(e);
}
페이지핸들러가 값을 계산해서 다 가지고 있기 때문에
페이지핸들러를 jsp로 넘겨주면 jsp에서 페이지핸들러에 있는 값을 가지고 페이징을 해주면 된다.
jsp쪽으로 가서
<code />
<div>
<c:if test="${ph.showPrev}">
<a href="<c:url value='/board/list?page=${ph.beginPage-1}&pageSize=${ph.pageSize}'/>"><</a>
</c:if>
<c:forEach var="i" begin="${ph.beginPage}" end="${ph.endPage}">
<a href="<c:url value='/board/list?page=${i}&pageSize=${ph.pageSize}'/>">${i}</a>
</c:forEach>
<c:if test="${ph.showNext}">
<a href="<c:url value='/board/list?page=${ph.endPage+1}&pageSize=${ph.pageSize}'/>">></a>
</c:if>
</div>
10페이지를 눌렀을 때 10페이지가 나오지 않아
pageHangdler.java의 beginPage계산을 수정해주었다.
<code />
beginPage = (page-1)/naviSize*naviSize+1; //일의 자릿수를 버리기

'패캠 챌린지' 카테고리의 다른 글
게시판 검색 기능 만들기 (0) | 2023.06.12 |
---|---|
게시판 CRUD 기능 구현_읽기, 삭제 (0) | 2023.06.05 |
게시판 목록 만들기와 페이징 - TDD(1) (1) | 2023.05.12 |
MaBatis로 DAO작성하기 (0) | 2023.05.11 |
MyBatis (0) | 2023.04.28 |