JSP

[JSP] 페이지 나누기 (Oracle fetch 구문 활용 상위 레코드 출력)

colin2 2024. 4. 26. 11:43

2024.04.22 - [JSP] - [JSP] 검색 기능 구현 | Dynamic Web Project

 

 

이번에는 레코드가 많을 때 보기 편하게 하기 위해 페이지를 나누어 볼 것이다.

 

이번에는 처음으로 오라클 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> &emsp;&emsp;
<% 
if(listStartPage > pageListSize) { 
   	start = (pagesize * pageListSize) * ((listStartPage - pageListSize - 1) / pageListSize);
%>
<a href="list3.jsp?start=<%=start %>&ch1=<%=ch1 %>&ch2=<%=ch2 %>"> 이전<%=pageListSize %> </a> 
<% } else { %>
    이전 
<% } %>
&emsp;&emsp;
<% 
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 %>]&nbsp;&nbsp;</a>
    <%
    }
} 
%>	
<% 
if (listEndPage < totalPage) {
    start = start + pagesize * pageListSize;
%>
<a href="list3.jsp?start=<%=start %>&ch1=<%=ch1 %>&ch2=<%=ch2 %>">다음<%=pageListSize %> </a>    &emsp;&emsp;
<% } else { %>
    다음  &emsp;&emsp;
<% }
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을 주고 실행시켜 보자.

 

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

 

 

[전체코드]