저번 공식에 이어서 진행되는 포스팅이다.
시작은 항상 이벤트로 시작한다.
<div class="menu"><a onclick="location.href='list.bo?cpage=1'">게시판</a></div>
우리가 jsp에서 짜놓은 코드에 게시판 을 클릭하면 시작이다.
처음 클릭했으니 cpage=1 우리가 요청한 페이지는 1인 것이 자명하다.
public class PageInfo {
private int listCount; //현재 총 게시글 수
private int currentPage; //현재 페이지(사용자가 요청한 페이지)
private int pageLimit; //페이지 하단에 보여질 페이징바의 개수
private int boardLimit; // 한 페이지내에 보여질 게시글 최대갯수
//위 4개의 값을 기준으로 아래 3개의 값을 구해야함
private int maxPage; // 가장 마지막페이지(총 페이지의 수)
private int startPage; // 페이징바의 시작수
private int endPage;//페이징바의 마지막 끝수
먼저 Page의 정보를 담아줄 객체 PageInfo를 만들고
(기본적인 getter, setter, toString, 생성자 등등 만들어줘야하는거 아시죠)
public class Pagination {
public static PageInfo getPageInfo(int listCount, int currentPage, int pageLimit, int boardLimit) {
int maxPage = (int)Math.ceil((double)listCount / boardLimit); //가장 마지막페이지(총 페이지 수)
int startPage = ((currentPage - 1) / pageLimit) * pageLimit + 1; // 페이징바의 시작
int endPage = startPage + pageLimit - 1;// 페이징바의 끝수
endPage = endPage > maxPage ? maxPage : endPage;
PageInfo pi = new PageInfo(listCount, currentPage, pageLimit, boardLimit, maxPage, startPage, endPage);
return pi;
}
}
우리가 저번에 사용했던 공식을 정리한 Pagination 클래스를 만들어준다.
int listCount = new BoardServiceImpl().selectListCount(); //현재 총 게시글 수
int currentPage = Integer.parseInt(request.getParameter("cpage"));
PageInfo pi = Pagination.getPageInfo(listCount, currentPage, 10, 5);
ArrayList<Board> list = new BoardServiceImpl().selectList(pi);
request.setAttribute("list", list);
request.setAttribute("pi", pi);
request.getRequestDispatcher("WEB-INF/views/board/boardListView.jsp").forward(request, response);
그리고 list.bo로 보냈으니 받아줄 서블렛을 만들고 객체에 잘 담아서 먼저 프론트쪽으로 pi 객체를 setAttribute에 잘 담아준다.
다음은 만들어진객체 list 를 들고 service로 넘어가야하는데
바로 service로 가는게 아니라 interface 하나 만들고 추상 클래스를 구현하는 식으로 한다.(그래야 유지보수할 때 매우 편함)
public interface BoardService {
//게시판리스트 조회
public int selectListCount();
public ArrayList<Board> selectList(PageInfo pi);
}
추상클래스에 추상 메소드 작성해주고
public class BoardServiceImpl implements BoardService{
private BoardDao bDao = new BoardDao();
@Override
public int selectListCount() {
SqlSession sqlSession = Template.getSqlSession();
int listCount = bDao.selectListCount(sqlSession);
sqlSession.close();
return listCount;
}
@Override
public ArrayList<Board> selectList(PageInfo pi) {
SqlSession sqlSession = Template.getSqlSession();
ArrayList<Board> list = bDao.selectList(sqlSession, pi);
sqlSession.close();
return list;
}
}
실제로 구현해준다. 위selectListCount는 총 게시글 수를 가져오는 controller 처음에 요청한 녀석이고
밑 selectList는 페이징 처리를 위해 구현한 메서드이다.
(mybatis에서는 우리가 JDBC에서 하던 Connection 과 트랜젝션 처리를 대신해준다.)
둘다 Dao로 이동하고
public class BoardDao {
public int selectListCount(SqlSession sqlSession) {
return sqlSession.selectOne("boardMapper.selectListCount");
}
public ArrayList<Board> selectList(SqlSession sqlSession, PageInfo pi){
//마이바티스에서는 페이징처리를 위해 rowBounds라는 클래스를 제공한다.
/* offset :몇개의 게스글을 건너뛰고 조회할건지에 대한 값
*
* currentPage : 1 1~5 0 5
* currentPage : 2 6~10 5 5
* currentPage : 3 11~15 10 5
*
*/
int offset = (pi.getCurrentPage() - 1) * pi.getBoardLimit();
int limit = pi.getBoardLimit();
RowBounds rowBounds = new RowBounds(offset, limit);
return (ArrayList)sqlSession.selectList("boardMapper.selectList", null, rowBounds);
}
}
mybatis에서 제공하는 rowBounds 클래스를 이용하여 객체를 만들어준다.
또 sqlSession에 우리가 작성한 메퍼와 현재 parameter은 없으니 null, rowBounds를 잘 가공해서 리턴한다.
여기서 메퍼를 잠시 보고오면
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="boardMapper"> //별칭 지정
<resultMap id="boardResultSet" type="Board"> //vo와 매핑
<result column="board_no" property="boardNo"/>
<result column="board_title" property="boardTitle"/>
<result column="USER_ID" property="boardWriter"/>
<result column="count" property="count"/>
<result column="CREATE_DATE" property="createDate"/>
<result column="board_content" property="boardContent"/>
</resultMap>
<select id="selectListCount" resultType="_int"> //실제 쿼리
SELECT COUNT(*)
FROM BOARD
WHERE STATUS = 'Y'
</select>
<select id="selectList" resultMap="boardResultSet">
SELECT BOARD_NO,
BOARD_TITLE,
USER_ID,
COUNT,
CREATE_DATE
FROM BOARD B
JOIN MEMBER ON (BOARD_WRITER = USER_NO)
WHERE B.STATUS = 'Y'
ORDER BY BOARD_NO DESC
</select>
</mapper>
이게 중요하다.
원래 우리는 Dao에서 PreparedStatements를 사용해서 쿼리를 일일히 작성해줬지만 mybatis에서는 xml파일로 mapper를 지정해놓고 별칭을 알려주면 계속해서 사용할 수 있다.
1. 별칭을 지정해서 위치를 알려주고
2. vo와 어떻게 값을 대치시켜서 넣을 건지 알려주고
3. 쿼리를 작성해주면 끝이다.
그럼 이걸 들고 service로 내려가고 controller로 내려가고
request.getRequestDispatcher("WEB-INF/views/board/boardListView.jsp").forward(request, response);
이런식으로 다시 jsp페이지를 뿌려주게 된다.
<table id="list-area">
<thead>
<tr>
<th>글번호</th>
<th width="400">제목</th>
<th>작성자</th>
<th>조회수</th>
<th>작성일</th>
</tr>
</thead>
<tbody>
<c:forEach var="b" items="${list}">
<tr>
<td>${b.boardNo }</td>
<td>${b.boardTitle }</td>
<td>${b.boardWriter }</td>
<td>${b.count }</td>
<td>${b.createDate }</td>
</tr>
</c:forEach>
</tbody>
</table>
그럼 taglib을 이용하여 forEach를 써서 우리가 list에 담아서 보내줬던걸 하나하나 꺼내게 된다.
그냥 JDBC할 때는 귀찮아서 하나하나 해줘야 했던 부분이였는데 확실히 프레임워크를 사용하니 편한점이 느껴졌다.
또 라이브러리와 프레임워크의 코드 주도권을 누가 쥐고있냐 도 피부로 확 와닿아서 재밌었다.
이것도 세미프로젝트에 써먹어봐야겠다.
'mybatis' 카테고리의 다른 글
mybatis로 페이징처리를 위한 공식 (0) | 2024.04.13 |
---|---|
myBatis에 대하여 (0) | 2024.04.11 |