아래 기능들을 구현하기 위해 전체 코드 중 주요하게 바뀌는 부분만 작성해보겠다
list.jsp
<%
String p = request.getParameter("p");
String f = request.getParameter("f");
NoticeService noticeService = new NoticeService();
List<Notice> list = noticeService.getList(field, query);
%>
NoticeService.java
String sql = "SELECT * FROM ("
+ " SELECT ROWNUM NUM, N.* " // 윗줄과 아랫줄 사이 공백 필요 여부 잘 확인하기
+ " FROM ("
+ " SELECT * FROM NOTICE"
+ " WHERE "+field+" LIKE '%"+query+"%'" // field(제목 or 작성자), query(사용자가 검색한 값)
+ " ORDER BY REGDATE DESC"
+ " ) N "
+ ")"
+ "WHERE NUM BETWEEN 1 AND 5";
list.jsp
<%
String p = request.getParameter("p"); // 페이저 구현을 위한 변수
String f = request.getParameter("f");
String q = request.getParameter("q");
// 변수 초기화: 기본 값을 설정하는 것
int page_ = 1; // jsp가 가지고 있는 내장 변수가 페이지라는 이름을 사용하고 있어서 오류 발생
String field = "title";
String query = "";
// 사용자가 입력한 값으로 대치
if(p != null && !p.equals(""))
page_ = Integer.parseInt(p);
if(f != null && !f.equals(""))
field = f;
if(q != null && !q.equals(""))
query = q;
NoticeService noticeService = new NoticeService();
List<Notice> list = noticeService.getList(page_, field, query); // 사용자가 검색한 결과 얻게 하기
%>
<nav class="pager mt-3">
<h1 class="d-none">페이저</h1>
<div class="button">이전</div>
<ul>
<%for(int i=0; i<5; i++) {%>
<li><a class="<%=page_ == i+1 ? "text-strong" : "" %>" href="list.jsp?p=<%=i+1 %>&f=<%=field %>&q=<%=query %>"><%=i+1 %></a></li> <!--이렇게 해서 사용자가 검색한 결과 내에서 paging 할 수 있게 하기-->
<%} %>
</ul>
<div class="button">다음</div>
</nav>
NoticeService.java
List<Notice> list = new ArrayList<>();
int size = 10; // 한 페이지에 출력할 게시판 글 개수
int startNum = 1+(page-1)*size;
int endNum = page*size;
String sql = "SELECT * FROM ("
+ " SELECT ROWNUM NUM, N.* " // 윗줄과 아랫줄 사이 공백 필요 여부 잘 확인하기
+ " FROM ("
+ " SELECT * FROM NOTICE"
+ " WHERE "+field+" LIKE '%"+query+"%'" // field(제목 or 작성자), query(사용자가 검색한 값)
+ " ORDER BY REGDATE DESC"
+ " ) N "
+ ")"
+ "WHERE NUM BETWEEN " + startNum + " AND " + endNum; // 페이저 구현을 위해 출력할 목록의 개수 정하기
list.jsp
<section class="search-form">
<h1>검색폼</h1>
<form action="list.jsp" method="get"> <!-- action을 생략하면 현재 url과 같은 주소로 요청이 감 -->
<label class="d-none">검색 분류</label>
<%
String selectedTitle = "";
String selectedWriterId = "";
if(field.equals("title"))
selectedTitle = "selected";
if(field.equals("writer_id"))
selectedWriterId = "selected";
%>
<select name="f">
<option value="">분류 선택</option> <!-- value를 비워놓으면 분류 선택칸을 선택 안했음을 알 수 있음 -->
<option <%=selectedTitle %> value="title">제목</option> <!-- 사용자가 제목을 선택했을 때 selectedTitle 부분이 selected로 바뀌어서 사용자가 제목을 선택했음을 알 수 있게 함 -->
<option <%=selectedWriterId %> value="writer_id">작성자</option> <!-- 사용자가 작성자를 선택했을 때 selectedWriterId 부분이 selected로 바뀌어서 사용자가 작성자를 선택했음을 알 수 있게 함 -->
</select>
<label class="d-none">검색어</label>
<input type="text" name="q" value="<%=query%>">
<input type="submit" value="검색">
</form>
</section>
list.jsp
<section class="page-status mt-3">
<h1 class="d-none">현재 페이지 정보</h1>
<%
int count = noticeService.getCount(field, query);
int lastPage = count / 10 + (count % 10 == 0 ? 0 : 1); <!-- 총 페이지 개수를 10으로 나눠 나머지가 없으면 0을, 있으면 1을 더하기 -->
%>
<div>
<span class="text-strong"><%=page_ %></span> / <%=lastPage %> pages
</div>
</section>
NoticeService.java
public int getCount(String field, String query) throws SQLException, ClassNotFoundException {
int count = 0; // 검색한 결과값이 총 몇 페이지인지 알아내기
String url = "jdbc:oracle:thin:@hi.namoolab.com:1521/xepdb1";
String sql = "SELECT COUNT(ID) COUNT FROM NOTICE"
+ " WHERE "+field+" LIKE '%"+query+"%'";
Class.forName("oracle.jdbc.OracleDriver");
Connection con = DriverManager.getConnection(url, "NEWLEC", "11111"); // 서블릿 프로세스가 끝나면 연결이 끊어짐
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(sql);
if(rs.next())
count = rs.getInt("COUNT");
rs.close();
st.close();
con.close();
return count;
}
NoticeList.java
@WebServlet("/api/notice/list")
public class NoticeList extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter out = resp.getWriter();
try {
NoticeService noticeService = new NoticeService();
List<Notice> list = noticeService.getList(1, "title", "");
out.println(list); // toString을 직접 호출하지 않아도 어떤 객체를 out.print로 호출하면 자동으로 toString이 호출되도록 약속되어 있다.
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
ex1.js
request.onload = function() { // 바뀐 버전
console.log(request.responseText); // 요청한 데이터가 다 도착했을 때 이 코드를 출력해달라
// json 형태의 데이터가 통으로 옴
var list = JSON.parse(request.responseText);
console.log(list[0].id);
console.log(list[0].regDate);
}
오늘은 JSP에서 DB의 데이터를 이용해 하나의 페이지 안에 포함된 여러 기능을 구현해보는 시간을 가졌다. 수업 때 잠깐이라도 다른 생각을 하면 흐름을 놓치기 십상이기 때문에 최대한 집중해서 따라가려고 노력했다. 선생님이 치시는 코드를 보면 알 것 같다가도 내가 혼자 해보려고 하면 막막해지기도 하는데, 이럴수록 더 반복하고 연습하면서 끝까지 잘 헤쳐나가야겠다!