jsp

210316 글목록(boardList)

정ㅇr 2021. 3. 16. 20:15
728x90
<!-- 
boardList 1page(-> boardList 다른 페이지)
글입력 -> boardInsertForm -> boardInsertAction -> boardList
상세보기(제목클릭) -> boardOne -> boardDeleteForm(or boardUpdateForm) -> boardDeleteAction(or boardUpdateAction)

메소드 호출        vs      jsp 프로그램 호출
test()					test.jsp
test("goodee")			test.jsp?id=goodee (물음표 뒤에 있는게 매개변수)
test("goodee", 11)		test.jsp?id=goodee&num=11

make("goodee", 11)		<a href="test.jsp?id=goodee&num=11">make</a>
 -->

<!-- 클라이언트가 http://localhost/blog/boardList.jsp 호출 -->
<!-- 톰캣은 boardList.jsp 실행 -->
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!-- 이 소스 파일은 java라는 언어로 구현되어 있고, 결과물의 형태는 UTF-8으로 인코딩 된 html파일이어야 한다. 소스파일의 인코딩은 UTF-8 -->
<!-- 톰캣은 html태그문자는 그대로 둔 채 자바코드들만 해석해서 텍스트로 변경 -->


<!-- 자바에서 특정 클래스를 코드에 구현할 때, 패키지이름.클래스이름 -->
<!-- 자바 static 메소드 호출방법은 패키지이름.클래스이름.메소드이름() -->
<!-- import : 패키지를 포함한 긴 클래스 풀네임을 클래스 이름만으로 사용할 수 있도록 해준다. -->
<%@ page import="java.sql.*" %>
<!-- java.sql패키지 안의 모든 클래스를 import한다. -->
<!-- java.sql.Connection 코드에 사용하고 싶으면 풀네임 대신 Connection으로 사용 가능 -->

<!DOCTYPE html> <!-- 이 문서는 html5규칙을 지켜서 만든 문서입니다. -->
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<html>
<head>
<meta charset="UTF-8">
<title>boardList</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
</head>
<body class="container">
	<h1>boardList</h1>
	<!-- 메인 메뉴 -->
	<div>
		<!-- request.getContextPath()호출하면 결과값으로 프로젝트이름을 문자열로 남긴다. 여기서는 "/blog" 문자열을 남긴다 -->
		<a href="<%=request.getContextPath()%>/boardList.jsp">홈으로(전체보기)</a>
		<!-- 톰캣에 의해서 다음과 같이 해석된다. <a href="/blog/boardList.jsp"> -->
		<a href="<%=request.getContextPath()%>/boardInsertForm.jsp">글입력</a>
	</div>
	<!-- 서브 메뉴 -->
	<div>
		<%
			// 문자열배열(8)을 만들어 submenu라는 배열참조변수에 대입한다.
			String[] submenu = {"html","css","javascript","java","jsp","rdbms","sql","spring"};
			
			// foreach 반복문 : 배열값은 참조타입을 요소의 개수만큼 반복하면서 각 요소를 앞변수에 복사해서 사용
			for(String sm : submenu) { // submenu배열의 크기가 8이므로, 8번 반복하면서 각 요소를 sm에 복사해 사용함
		%>
				<a href="<%=request.getContextPath()%>/boardList.jsp?boardCategory=<%=sm%>"><%=sm%></a>
		<%		
			}
		%>
	</div>
	<%
		int currentPage = 1; // cureentPage의 디폴트 값은 1
		
		// request.getParameter("currentPage") : jsp페이지를 호출시 입력값을 읽는 메소드
		// 주소창에 boardList.jsp로 호출하면 request.getParameter("currentPage") 값은 null이 되어서 if문은 실행되지 않는다.
		if(request.getParameter("currentPage") != null) { // boardList.jsp?currentPage=2 이런식으로 넘어왔다.
			// currentPage안의 문자열값을 숫자로 변경하여 currentPage값에 대입(복사)
			// request.getParameter("") 메소드로 넘겨 받는 값은 무조건 문자열이다.
			currentPage = Integer.parseInt(request.getParameter("currentPage")); // 넘겨진 currentPage값을 숫자변경
		}
		
		// 주소창에 boardList.jsp로 호출하면 boardCategory값은 넘겨받지 못해서 null이 된다.
		// 55라인의 링크를 통해 boardList.jsp를 호출하면 boardList.jsp?boardCategory=값 호출되므로 boardCategory값이 넘어온다.
		String boardCategory = request.getParameter("boardCategory");
		System.out.println("boardCategory : " + boardCategory);
		
		
		int rowPerPage = 10; // 한 페이지에 10개의 행을 보여주기로 설정
		/*
			currentPage 1이면 beginRow는 0이고 (0행부터 9행까지 10(rowPerPage)개),
			currentPage 2이면 beginRow는 1이고, (10행부터 19행까지 10(rowPerPage)개)
			....
			다음과 같은 패턴의 공식이 나오더라.
		*/
		int beginRow = (currentPage-1) * rowPerPage; // 현재페이지와 rowPerPage를 이용하여 보여줄 테이블의 시작 행을 구한다. 
		
		// jsp프로그램 안에서 mariadb 프로그램을 사용할 수 있도록 해야 함.
		// Class.forName()이라는 메소드를 이용해서 org.mariadb.jdbc.Driver 클래스를 호출한다.
		// org.mariadb.jdbc.Driver 클래스가 있는 jar 파일을 WEB-INF/lib 안에 위치 시킨다.
		Class.forName("org.mariadb.jdbc.Driver"); // Class를 이름으로 불러낸다는 의미
		
		// Class.forName()으로 메모리에 로드된 마리아DB에 접속한다. (주소:포트번호/db이름, 사용자계정, 사용자암호)
		Connection conn = DriverManager.getConnection("jdbc:mariadb://localhost:3306/blog","root","java1004");
		// 대입연산자(=) 왼쪽은 변수자리, conn 변수는 많은 값이 저장되어 있는 참조타입(기본타입 8개를 제외한 모든 타입은 참조타입)
		System.out.println("conn : "+conn);
		// select board_no, board_title, board_user from board
		
		
		// 보통 기본타입은 0, 0.0, false 초기화
		// 참조타입 null값으로 초기화, String은 ""로 초기화 하기도 함
		String sql = null;
		PreparedStatement stmt = null;
		// boardCategory가 null이냐 아니냐에 따라서 sql값과 stmt값이 달라진다.
		// *기억하기* 하나의 jsp 프로그램에서 동일한 기능을 수행하는 sql값(쿼리가) 분기되는 것을 동적쿼리라고 하기도 함. 
		
		if(boardCategory == null) {
			sql = "select board_no, board_category, board_title, board_user from board order by board_no desc limit ?, ?";
			stmt = conn.prepareStatement(sql);
			stmt.setInt(1, beginRow);
			stmt.setInt(2, rowPerPage);
		} else { // 서브메뉴에서 category를 누른 경우
			sql = "select board_no, board_category, board_title, board_user from board where board_category = ? order by board_no desc limit ?, ?";
			stmt = conn.prepareStatement(sql);
			stmt.setString(1, boardCategory);
			stmt.setInt(2, beginRow);
			stmt.setInt(3, rowPerPage);
		}
		// 꼭! stmt 확인 (디버깅)
		System.out.println(stmt);
		
		// ResultSet 테이블의 값들을 담을 수 있는 참조타입
		ResultSet rs = stmt.executeQuery(); // select 쿼리를 실행시 executeQuery() -> DB 값이 바뀌지 않음, insert/update/delete 실행시 executeUpdate() -> DB 값이 바뀜
	%>
	<table class="table">
		<thead>
			<tr>
				<th>board_no</th>
				<th>board_category</th>
				<th>board_title</th>
				<th>board_user</th>
			</tr>
		</thead>
		<tbody>
			<%
				while(rs.next()) { // 행의 이동하면서 열값을 읽을 준비
			%>
					<tr>
						<!-- rs.get...() 열을 이동 값을 읽는 기능 -->
						<td><%=rs.getInt("board_no")%></td>
						<td><%=rs.getString("board_category")%></td>
						<td><a href="<%=request.getContextPath()%>/boardOne.jsp?boardNo=<%=rs.getInt("board_no")%>"><%=rs.getString("board_title")%></a></td>
						<td><%=rs.getString("board_user")%></td>
					</tr>
			<%		
				}
			%>
		</tbody>
	</table>
	<%
		if(currentPage > 1) { // 현재페이지가 1페이지면 이전페이지가 없기 때문에
			if(boardCategory == null) { // boardCategory값이 있을 때와 없을 때 boardList.jsp?뒤의 입력값(매개변수)의 개수 또는 형태가 다르다. 
	%>
				<a href="<%=request.getContextPath()%>/boardList.jsp?currentPage=<%=currentPage-1%>">이전</a>
	<%
			} else {
	%>
				<a href="<%=request.getContextPath()%>/boardList.jsp?currentPage=<%=currentPage-1%>&boardCategory=<%=boardCategory%>">이전</a>	
	<%			
			}
		}
		
		// 다음 버튼의 경우 마지막 페이지이면 다음버튼이 존재해서는 안됨
		// 마지막 페이지를 구하려고 하니까 전체 행의 수를 알아야 한다.
		
		// select의 결과물은 ResultSet이라는 새로운 테이블
		PreparedStatement stmt2 = conn.prepareStatement("select count(*) from board"); // 전체 행의 수를 구하는 쿼리
		ResultSet rs2 = stmt2.executeQuery();
		int totalRow = 0; // 숫자는 보통 0으로 초기화
		if(rs2.next()) {
			totalRow = rs2.getInt("count(*)"); // 1000
		}
		// 마지막 페이지 = 전체 행의 수 / 한 페이지에 나타낼 행의 수, 소수점은 올림한다. (나누어 떨어지지 않으면 몫에서 1 plus한다.)
		int lastPage = totalRow / rowPerPage;
		if(totalRow % rowPerPage != 0) {
			lastPage += 1; // lastPage = lastPage+1; lastPage++;
		}
		
		if(currentPage < lastPage) {
			if(boardCategory == null) {
	%>
				<a href="<%=request.getContextPath()%>/boardList.jsp?currentPage=<%=currentPage+1%>">다음</a>
	<%
			} else {
	%>
				<a href="<%=request.getContextPath()%>/boardList.jsp?currentPage=<%=currentPage+1%>&boardCategory=<%=boardCategory%>">다음</a>
	<%			
			}
		}
	%>
</body>
</html>
반응형