JSP
[JSP] 페이지 나누기 (Oracle fetch 구문 활용 상위 레코드 출력)
colin2
2024. 4. 26. 11:43
이번에는 레코드가 많을 때 보기 편하게 하기 위해 페이지를 나누어 볼 것이다.
이번에는 처음으로 오라클 21을 사용하면서 상위 레코드만 출력할 수 있는 쿼리를 사용해 보았다.
페이지 나누기를 위해 총 8개의 값을 찾을 것이다.
1. 페이지 사이즈 : <%=pagesize %> - 한 페이지에 나타낼 레코드
2. 페이지 List사이즈 : <%=pageListSize %> - 나타낼 페이지 수의 개수
3. 전체 레코드 수 : <%=totalCount %> - 전체 레코드의 수
4. 총 페이지 수 : <%=totalPage %> - 전체 페이지의 수
5. 현재 레코드 : <%=start +1 %> - 현재 위치한 레코드
6. 현재 페이지 : <%=nowPage %> - 현재 위치한 페이지
7. 가로 하단 시작 :<%=listStartPage %> - 페이지 수의 시작
8. 가로 하단 마지막 : <%=listEndPage %> - 페이지 수의 마지막
그럼 처음부터 시작을 해보자.
list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%
int start = 0;
int pagesize = 10;
int pageListSize = 10;
String ch1 = request.getParameter("ch1");
String ch2 = request.getParameter("ch2");
if (ch2 == null) {
ch2 = "";
} else {
ch2 = request.getParameter("ch2");
}
if (request.getParameter("start") == null) {
start = 0;
} else {
start = Integer.parseInt(request.getParameter("start"));
}
%>
우선 start와 pagesize, pageListSize는 가장 상단에 적어주고, 검색을 위한 ch1, ch2도 상단에 두었다.

<%
String URL="jdbc:oracle:thin:@//localhost:1521/xe";
String UID = "system";
String PWD = "1234";
String SQL = "";
String SQL_TC = "";
PreparedStatement pstmt = null;
PreparedStatement pstmt_tc = null;
ResultSet rs = null;
ResultSet rs_tc = null;
Class.forName("oracle.jdbc.OracleDriver");
Connection conn = DriverManager.getConnection(URL, UID , PWD);
%>
다음으로 오라클 DB를 연동하고, 기본 쿼리와 전체 레코드 결과를 위한 SQL, SQL_TC와 그에 따른 준비를 미리 해주었다.

<%
if (ch1 == null || ch1.equals("null")) {
SQL = "select idx, name, address, phone_number from pythondata ";
SQL += " order by idx offset ? row ";
SQL += " fetch next ? rows only";
pstmt = conn.prepareStatement(SQL);
pstmt.setInt(1, start);
pstmt.setInt(2, pagesize);
SQL_TC = "select count(*) tc from pythondata";
pstmt_tc = conn.prepareStatement(SQL_TC);
} else if (ch1.equals("name")) {
SQL = "select idx, name, address, phone_number from pythondata ";
SQL += " where name like ? " ;
SQL += " order by idx offset ? row ";
SQL += " fetch next ? rows only";
pstmt = conn.prepareStatement(SQL);
pstmt.setString(1, "%" + ch2 + "%");
pstmt.setInt(2, start);
pstmt.setInt(3, pagesize);
SQL_TC = "select count(*) tc from pythondata where name like ?";
pstmt_tc = conn.prepareStatement(SQL_TC);
pstmt_tc.setString(1, "%" + ch2 + "%");
} else if (ch1.equals("address")) {
SQL = "select idx, name, address, phone_number from pythondata ";
SQL += " where address like ? " ;
SQL += " order by idx offset ? row ";
SQL += " fetch next ? rows only";
pstmt = conn.prepareStatement(SQL);
pstmt.setString(1, "%" + ch2 + "%");
pstmt.setInt(2, start);
pstmt.setInt(3, pagesize);
SQL_TC = "select count(*) tc from pythondata where address like ?";
pstmt_tc = conn.prepareStatement(SQL_TC);
pstmt_tc.setString(1, "%" + ch2 + "%");
}
rs = pstmt.executeQuery();
rs_tc = pstmt_tc.executeQuery();
rs_tc.next();
%>
if문을 사용하여 각 상황에 따라 SQL, SQL_TC의 결과가 달라지게 만들어 준다.

<%
int totalCount = rs_tc.getInt("tc");
int totalPage = (totalCount / pagesize) + 1;
int nowPage = (start / pagesize) + 1;
int lastPage = (totalPage - 1) * pagesize;
int listStartPage = (nowPage - 1) / pageListSize * pageListSize + 1;
int listEndPage = listStartPage + pageListSize - 1;
%>
마지막으로 나머지 필요한 값들을 계산하여 변수에 담아주면 페이지 나누기 준비 끝.
이제 남은 건 UI 작업.

<div>1. 페이지 사이즈 : <%=pagesize %></div>
<div>2. 페이지 List사이즈 : <%=pageListSize %></div>
<div>3. 전체 레코드 수 : <%=totalCount %></div>
<div>4. 총 페이지 수 : <%=totalPage %></div>
<div>5. 현재 레코드 : <%=start + 1 %></div>
<div>6. 현재 페이지 : <%=nowPage %></div>
<div>7. 가로 하단 시작 :<%=listStartPage %></div>
<div>8. 가로 하단 마지막 : <%=listEndPage %></div>
우선 원하는대로 표시가 되는지 확인하기 위해 값을 찍어보자.

<table>
<tr>
<td>idx</td>
<td>name</td>
<td>address</td>
<td>phone_number</td>
<td>삭제</td>
</tr>
<%
while(rs.next()) {
%>
<tr>
<td><%=rs.getString("idx") %></td>
<td><%=rs.getString("name") %></td>
<td><%=rs.getString("address") %></td>
<td><%=rs.getString("phone_number") %></td>
<td><a href=delete.jsp?idx=<%=rs.getString("idx") %>>삭제</a></td>
</tr>
<% } %>
</table>
DB 테이블의 전체 레코드를 출력하는 테이블을 만들어 주고,

<%
ch2 = java.net.URLEncoder.encode(ch2, "utf-8");
%>
<a href="list3.jsp?start=0&ch1=<%=ch1 %>&ch2=<%=ch2 %>"> 처음 </a>   
<%
if(listStartPage > pageListSize) {
start = (pagesize * pageListSize) * ((listStartPage - pageListSize - 1) / pageListSize);
%>
<a href="list3.jsp?start=<%=start %>&ch1=<%=ch1 %>&ch2=<%=ch2 %>"> 이전<%=pageListSize %> </a>
<% } else { %>
이전
<% } %>
  
<%
for(int i = listStartPage; i <= listEndPage; i++) {
start = (i - 1) * pagesize;
if(i <= totalPage) {
%>
<a href="list3.jsp?start=<%=start %>&ch1=<%=ch1 %>&ch2=<%=ch2 %>">[<%=i %>] </a>
<%
}
}
%>
<%
if (listEndPage < totalPage) {
start = start + pagesize * pageListSize;
%>
<a href="list3.jsp?start=<%=start %>&ch1=<%=ch1 %>&ch2=<%=ch2 %>">다음<%=pageListSize %> </a>   
<% } else { %>
다음   
<% }
start = (totalPage - 1) * pageSize ;
%>
<a href="list3.jsp?start=<%=lastPage %>&ch1=<%=ch1%>&ch2=<%=ch2%>">
마지막
</a>
페이지 나누기를 위한 코드를 작성해준다.

<form action=list3.jsp>
<select name=ch1>
<option value="name">이 름 </option>
<option value="address">주 소 </option>
</select>
<input type=text name=ch2>
<input type=submit value="검색하기" >
</form>
마지막으로 검색을 위한 폼까지 추가해주면, 페이지 나누기가 적용 완료.
테이블에 border=1을 주고 실행시켜 보자.



이렇게 전체 레코드와 검색 했을 때의 레코드, 페이지 이동을 했을 때도 값을 함께 넘겼기 때문에 결과가 유지되는 것까지 볼 수 있다.
[전체코드]



