본문 바로가기
mybatis

mybatis를 이용해서 페이징 처리

by Dodledd 2024. 4. 14.

저번 공식에 이어서 진행되는 포스팅이다.

 

시작은 항상 이벤트로 시작한다.

<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