본문 바로가기
오답노트

게시판 페이징 처리하기 feat. ORACLE

by titlejjk 2023. 6. 9.

게시판 페이징 처리하기

강사님이 내주신 과제인데 손에도 안잡혀서 코드 받고 분석만 해보았다. 이해라도 잘해야지..

먼저 해당 게시판에 페이지 번호를 부여해주었다.

<%
   int pageNum = 1;
   if(request.getParameter("pageNum") != null){
      pageNum = Integer.parseInt(request.getParameter("pageNum"));
   }
   
   List<FileDto> listPage = FileDao.getInstance().getListPage(pageNum);
   //로그인된 아이디(로그인이 되어있지 않으면 null)
   String id = (String)session.getAttribute("id");
%>

int pageNum = 1;

아래 코드는 for문을 돌아 i가 1부터 10까지 출력되도록 해주었다.

pageNum을 1로 초기값으로 설정해주면 페이지로딩시 1페이지가 출력되도록 설정

<ul class="pagination justify-content-center">
         <%for(int i = 1; i < 10; i++) {%>
            <li class="page-item">
               <a class="page-link" href="list.jsp?pageNum=<%=i %>"><%=i %></a>
            </li>
         <%} %>
      </ul>

이렇게 하면 1번째 페이지가 출력이 된다.

그리고 2번을 누르면 페이지 전환이 되도록 하는코드는 위에 써있는 것처럼

 if(request.getParameter("pageNum") != null){
      pageNum = Integer.parseInt(request.getParameter("pageNum"));
   }

해석해보자면 pageNum이 null이 아닐경우 request.getParameter로 들어온 값의 페이지 번호가 pageNum에 담겨 해당 번호의 페이지가 출력이 된다.

 

다음으로 해당 페이지를 눌렀을 때 게시글 수를 출력하는 메소드(오라클DB를 통해 가져옴)

//파일 목록을 리턴하는 메소드
	   public List<FileDto> getListPage(int num){
	      //파일 목록을 담을 ArrayList 객체 생성
	      List<FileDto> list = new ArrayList<FileDto>();
	      
	      //필요한 객체의 참조값을 담을 지역변수 미리 생성
	      Connection conn = null;
	      PreparedStatement pstmt = null;
	      ResultSet rs = null;
	      try {
	         //DbcpBean 객체를 이용해서 Connection 객체를 Connection Pool에서 얻어오기
	         conn = new DbcpBean().getConn();
	         //실행할 sql문
	         String sql = "SELECT *"
	               + " FROM"
	               + "    (SELECT result1.*, ROWNUM AS rnum"
	               + "    FROM"
	               + "       (SELECT num, writer, title, orgFileName, saveFileName, fileSize, regdate"
	               + "       FROM board_file"
	               + "       ORDER BY num DESC) result1)"
	               + " WHERE rnum BETWEEN ? AND ?";
	         pstmt = conn.prepareStatement(sql);
	         pstmt.setInt(1, (num-1)*10+1);//페이지번호
	         pstmt.setInt(2, num*10);
	         rs = pstmt.executeQuery();
	         //반복문 돌면서 ResultSet에 담긴 내용 추출
	         while (rs.next()) {
	            FileDto dto = new FileDto();
	            dto.setNum(rs.getInt("num"));
	            dto.setWriter(rs.getString("writer"));
	            dto.setTitle(rs.getString("title"));
	            dto.setOrgFileName(rs.getString("orgFileName"));
	            dto.setSaveFileName(rs.getString("saveFileName"));
	            dto.setFileSize(rs.getLong("fileSize"));
	            dto.setRegdate(rs.getString("regdate"));
	            
	            list.add(dto);
	         }
	      } catch (SQLException se) {
	         se.printStackTrace();
	      } finally {
	         try {
	            if (rs != null) {
	               rs.close();
	            }
	            if (pstmt != null) {
	               pstmt.close();
	            }
	            if (conn != null) {
	               conn.close();
	            } //Connection이 Connection Pool에 반납됨
	         } catch (Exception e) {
	         }
	      }
	      
	      return list;
	   }
String sql = "SELECT *"
	               + " FROM"
	               + "    (SELECT result1.*, ROWNUM AS rnum"
	               + "    FROM"
	               + "       (SELECT num, writer, title, orgFileName, saveFileName, fileSize, regdate"
	               + "       FROM board_file"
	               + "       ORDER BY num DESC) result1)"
	               + " WHERE rnum BETWEEN ? AND ?";
	         pstmt = conn.prepareStatement(sql);
	         pstmt.setInt(1, (num-1)*10+1);//페이지번호
	         pstmt.setInt(2, num*10);

아래 SQL문을 해석해보자면

1. 조회할 데이터들을 나열하고 SELECT num, writer, title, orgFileName, saveFileName, fileSize, regdate

어느  테이블에서 FROM board_file

어떤 식으로 나열할건지 ORDER BY num DESC 이렇게 해주고

2. 1번은 result1으로 감싸서 다시 result1을 조회하고 SELECT result1의 전체를 *로 조회한다.

어느 방식으로 ? ROWNUM으로 이 ROWNUM AS를 통해 뒤에는 rnum이라 써주기로하고

3. 2번을 SELECT 해준다. SELECT * FROM 2번

어떤조건으로? rnum 이 BETWEEN ? AND ? 1번 물음표에서 2번 물음표 까지.

 

pstmt.setInt(1, (num-1)*10+1);

위 코드는 첫 번째 물음표를 설정해주는데 만약 2가 들어가면 (2-1)*10+1을 통해 11번째 db row부터 검색이 되고

pstmt.setInt(2, num*10);

위 코드는 두 번째 물음표를 설정해주는데 위처럼 2가 들어가게 되면 2*10번째 즉 20번째 db row가 검색이된다.

위 SQL 문에서 BETWEEN ? AND ? 이니 최종적으로 11번째 부터 20번의 db가 조회되는 메소드이다.

댓글