JSP #4

jjinny_0609·2023년 3월 23일
0

JSP

목록 보기
4/6

varStatus

varStatus는 일반적으로 JSTL(JSP Standard Tag Library)에서 사용되며, JSP 페이지에서 반복문을 수행할 때 사용됩니다. varStatus를 사용하면 반복문의 현재 상태를 나타내는 정보를 저장하고, 해당 정보를 활용하여 특정 작업을 수행할 수 있습니다.

예를 들어, varStatus를 사용하여 반복문에서 현재 반복 횟수를 추적하고, 특정 횟수마다 다른 작업을 수행하거나 특정 조건을 검사할 수 있습니다.

아래는 varStatus를 사용한 JSTL의 예시 코드입니다.

<c:forEach var="item" items="${itemList}" varStatus="loop">
    <c:out value="${item}"/><br>
    <c:if test="${loop.index % 2 == 0}">
        <c:out value="This is an even loop iteration"/><br>
    </c:if>
</c:forEach>

위 코드에서 varStatus를 사용하여 현재 반복 상태를 나타내는 loop 변수를 선언하였습니다. loop 변수를 사용하여 현재 반복 횟수(loop.index), 현재 반복이 처음인지 여부(loop.first), 현재 반복이 마지막인지 여부(loop.last) 등을 알 수 있습니다.

위 코드에서는 loop.index가 짝수일 때 "This is an even loop iteration"을 출력하도록 설정하였습니다.


[예제_formatNumber]

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<c:set var="price" value="10000" />

${price}
<fmt:formatNumber value="${price}" type="number" var="numberType" />
<br />
통화: <fmt:formatNumber value="${price}" type="currency" currencySymbol="" />
<br/>
퍼센트: <fmt:formatNumber value="${price}" type="percent" groupingUsed="false" />
<br/>
숫자: ${numberType}
<br/>
패턴 : <fmt:formatNumber value="${price}" pattern="00000000.00" />
</body>
</html>

[예제_formatDate]

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	
<c:set var="now" value="<%= new java.util.Date() %>" />	
${now}

<fmt:formatDate value="${now}" type="date" dateStyle="full" />
<br>
<fmt:formatDate value="${now}" type="date" dateStyle="short" />
<br>
<fmt:formatDate value="${now}" type="time" />
<br>
<fmt:formatDate value="${now}" type="both" dateStyle="full" timeStyle="full"/>
<br>
<fmt:formatDate value="${now}" pattern="yyyy-MM-dd hh:mm:ss" />	<!-- 소문자는 분을 나타내는 miniute 대문자M이 Month의 월 -->
</body>
</html>


JDBC

JDBC(Java Database Connectivity)는 자바 프로그램에서 데이터베이스에 접속하여 데이터를 다룰 수 있게 해주는 API(Application Programming Interface)입니다. ODBC(Open Database Connectivity)는 Microsoft에서 개발한 데이터베이스 접속 API로, 다양한 데이터베이스 시스템에 접속할 수 있는 표준 인터페이스입니다.

JDBC ODBC 브릿지(bridge)는 JDBC API를 사용하여 ODBC 데이터베이스 드라이버를 호출하도록 구현된 드라이버입니다. 이를 사용하면 ODBC를 지원하는 데이터베이스 시스템에 대해서도 JDBC API를 이용하여 데이터베이스에 접속하고 데이터를 다룰 수 있습니다.

JDBC ODBC 브릿지를 사용하면 자바 애플리케이션에서 ODBC 드라이버를 로드하고 데이터베이스에 연결하는 과정을 JDBC API를 통해 처리할 수 있습니다. JDBC ODBC 브릿지를 사용하여 ODBC 드라이버를 호출하면, ODBC 드라이버가 데이터베이스에 대한 연결을 생성하고 SQL 질의문을 실행하여 결과를 반환합니다.

하지만, 최신 버전의 자바에서는 JDBC 드라이버들이 직접적으로 데이터베이스에 접속하는 것을 권장하고 있으며, JDBC ODBC 브릿지는 지원하지 않는 경우도 있습니다. 이러한 이유로, 최신 버전의 자바에서는 JDBC 드라이버를 직접 사용하여 데이터베이스에 접속하고 데이터를 다루는 것이 일반적입니다.

[이클립스와 mysql연결하기]

https://www.mysql.com/ 로 이동

download

MySQL community (GPL) download 클릭

Connector/J 클릭

Platform Independent 클릭

Download 클릭

No thanks, ~ 클릭

압축풀고 mysql-connector-j-(버전) 파일을 복사해서

WEB-INF -> lib 폴더에 복사

그럼 라이브러리에도 추가된 것을 확인할 수 있다.


[예제_자바로 DB연결하기(JDBC)]

연결을 위한 전체 코드

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
    
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
	// JDBC 드라이버 로딩(mysql)
	Class.forName("com.mysql.jdbc.Driver");
	
	// 연결하기
	Connection conn = null;
	
	// 드라이버 매니저에게 Connection 객체를 달라고 요청한다.
	
	// Connection을 얻기 위해 필요한 데이터(jdbcDriver,아이디,비밀번호)
	try{
		String jdbcDriver ="jdbc:mysql://localhost:3306/sample?serverTimezone=Asia/Seoul";
		String dbUser = "root";
		String dbPass = "1234";
		
		DriverManager.getConnection(jdbcDriver,dbUser,dbPass);
		
		out.println("DB 연결 성공");
	}catch(SQLException ex){
		out.println("DB 연결 실패");
	}finally{
		if(conn!=null){conn.close();}
	}
%>
</body>
</html>

연결 안되면 아래와 같이 뜨고

정상적으로 연결될 시 아래와 같이 출력된다.


ResultSetSQL

쿼리를 실행한 결과 데이터 집합을 나타내는 Java 인터페이스입니다. ResultSet은 데이터베이스의 테이블이나 뷰와 같은 데이터 집합에서 검색한 결과를 포함하며, 이를 사용하여 데이터를 읽고 조작할 수 있습니다.

ResultSet 인터페이스는 일련의 컬럼이 있는 데이터 집합을 나타내며, 데이터베이스에서 가져온 데이터를 순회할 수 있는 메서드를 제공합니다. ResultSet 객체는 SQL 쿼리를 실행하는 Statement, PreparedStatement 또는 CallableStatement 객체에서 생성됩니다.

ResultSet은 데이터베이스에서 데이터를 가져오는 방법을 제어하는데 사용되는 메서드를 제공합니다. ResultSet 객체는 데이터를 한 번에 한 행씩 가져올 수 있으며, 다음 행으로 이동하기 위해 next() 메서드를 사용합니다. ResultSet은 열 인덱스 또는 열 이름을 사용하여 특정 열의 데이터를 가져오는 메서드도 제공합니다.

ResultSet 인터페이스는 데이터의 유형과 크기, 행 및 열 인덱스 등과 같은 다양한 속성을 제공합니다. 이러한 속성을 사용하여 ResultSet에서 가져온 데이터를 처리하고 분석할 수 있습니다. 예를 들어, ResultSetMetaData 클래스를 사용하여 ResultSet에 대한 메타데이터를 검색하고, ResultSet의 데이터를 자바 객체에 매핑하는 ORM 프레임워크와 같은 라이브러리를 사용할 수도 있습니다.

executeQuery

Java에서 JDBC API를 사용하여 데이터베이스와 상호작용할 때 executeQuery 메서드는 주어진 SQL 쿼리를 실행하고 그 결과를 ResultSet 객체에 저장합니다. 이 ResultSet 객체는 테이블의 행과 열을 나타내며, 애플리케이션에서는 이 객체를 통해 데이터베이스에서 가져온 데이터를 처리할 수 있습니다.

예를 들어, 다음과 같은 SQL 쿼리문을 실행하고 그 결과를 ResultSet 객체에 저장할 수 있습니다.

String query = "SELECT * FROM customers";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(query);

위의 코드에서 connection은 데이터베이스와의 연결을 나타내는 객체입니다. Statement 객체는 SQL 문을 실행할 수 있으며, executeQuery 메서드를 사용하여 데이터베이스에서 결과를 검색합니다. ResultSet 객체는 executeQuery 메서드가 반환한 결과를 저장하며, 애플리케이션에서 이 객체를 사용하여 데이터를 처리할 수 있습니다.

중요한 점은 executeQuery 메서드가 SELECT 문을 실행할 때만 사용해야 한다는 것입니다. INSERT, UPDATE, DELETE 문을 실행할 때는 executeUpdate 메서드를 사용해야 합니다. 또한, executeQuery 메서드는 읽기 전용 ResultSet 객체를 반환하므로 결과를 수정할 수 없습니다. 결과를 수정해야 하는 경우, executeUpdate 메서드를 사용해야 합니다.

[예제_게시판을 만들어보기(mysql db값을 불러오기)]

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<table border="1">
	<tr>
		<td>게시판번호</td><td>제목</td><td>작성자</td><td>작성일</td><td>조회</td><td>좋아요</td>
	</tr>
<!-- 게시판 윗 부분은 반복하지 않아도 되므로 밖으로 빼줘서 처리해줌 -->
<%
	// JDBC 드라이버 로딩(mysql)
	Class.forName("com.mysql.jdbc.Driver");
	// java api에 db를 연결하기 위한 객체
	Connection conn = null;
	
	// workbench에서 sql을 작성한 후 (ctrl+enter)
	// sql문장을 작성을 하고, 그 sql문장을 실행을 위한 객체
	Statement stmt = null;
	
	// select의 결과를 DBMS에서 java로 저장하기 위한 객체
	ResultSet rs = null;
	
	// 연결하기
	// 드라이버 매니저에게 Connection 객체를 달라고 요청한다.
	// Connection을 얻기 위해 필요한 데이터(url,아이디,비밀번호)
	try{
		String jdbcDriver ="jdbc:mysql://localhost:3306/naver_1?serverTimezone=Asia/Seoul";
		String dbUser = "root";
		String dbPass = "1234";
		
		String query = "select * from board";	//executeQuery	- select만 다르다..
		// String query = "update board set title='가나다' where no = 1";	//executeUpdate
		// String query = "insert into board(title, content) values('제목입니다.','내용은 여기에...')";	// excuteUpdate
		// String query = "delete from board where no = 1";	//excuteUpdate
		
		conn = DriverManager.getConnection(jdbcDriver,dbUser,dbPass);
		
		stmt = conn.createStatement();
		// workbench ctrl+enter(쿼리문장을 실행)를 통해 도출된 select 결과를 ResultSet에 저장 ↓
		rs = stmt.executeQuery(query);
		
		// 데이터가 있을때까지 반복 -> 데이터가 있으면(true), 데이터가 없으면(false)값을 리턴하기 때문에
		// = 값이 있으면 넘겨줌
		while(rs.next()){		
%>
	<tr>
		<td>
			<%=rs.getInt("no") %>
		</td>
		<td><%=rs.getString("title") %></td>
		<td><%=rs.getString("id") %></td>
		<td><%=rs.getString("regdate") %></td>
		<td><%=rs.getInt("count") %></td>
		<td><%=rs.getInt("good") %></td>
	</tr>	
<%
	}
	out.println("DB 연결 성공");
		}catch(SQLException ex){
			out.println("DB 연결 실패");
		}finally{
			if(conn!=null){conn.close();}
	}
%>
</table>
</body>
</html>

mysql의 값

연결완료

[오류_게시판 윗 부분을 밖으로 빼줘서 처리해준 이유]
아래와 같이 입력하면 게시판 윗부분이 값이 있는 만큼 반복되어서 출력되기 때문에 아래와 같은 결과를 볼 수 있게된다.

게시판 윗 부분을 밖으로 빼줘서 처리해준 이유.jpg


PreparedStatement

PreparedStatement는 JDBC API를 사용하여 SQL 쿼리문을 실행할 때 사용하는 인터페이스 중 하나입니다. 이 인터페이스를 사용하면 SQL 쿼리문을 미리 컴파일하여 사용자 입력 값을 동적으로 바인딩할 수 있습니다.

PreparedStatement를 사용하면 SQL 쿼리문에서 사용되는 변수를 ?로 표시할 수 있습니다. 그리고 이 ?에 대한 값을 나중에 동적으로 할당할 수 있습니다. 이 방식은 SQL Injection 공격을 막아주며, 실행 속도를 높이는 데에도 도움을 줍니다.

예를 들어, 다음과 같은 SQL 쿼리문을 실행하는 경우 PreparedStatement를 사용할 수 있습니다.

String name = "John";
String query = "SELECT * FROM customers WHERE name = ?";
PreparedStatement statement = connection.prepareStatement(query);
statement.setString(1, name);
ResultSet resultSet = statement.executeQuery();

위의 코드에서는 SQL 쿼리문에서 name 변수를 ?로 대체하고, PreparedStatement 객체의 setString 메서드를 사용하여 이 변수에 대한 값을 설정합니다. 이후 executeQuery 메서드를 호출하여 SQL 쿼리문을 실행하고 결과를 ResultSet 객체에 저장합니다.

PreparedStatement를 사용하면 매번 SQL 쿼리문을 실행하기 전에 쿼리문을 미리 컴파일할 수 있으므로 실행 속도가 빨라집니다. 또한, 사용자 입력 값을 동적으로 할당할 수 있으므로 SQL Injection 공격을 방지할 수 있습니다. 따라서 PreparedStatement는 보안과 성능 측면에서 모두 유용한 인터페이스입니다.

PreparedStatement 클래스가 제공하는 set 메서드

set 메서드는 SQL 쿼리문에서 ?로 표시된 변수에 값을 할당하는 데 사용됩니다. 다음은 PreparedStatement 클래스에서 제공하는 일부 set 메서드의 예시입니다.

  • setString(int parameterIndex, String x)
    SQL 쿼리문에서 ?로 표시된 문자열 변수에 값을 할당합니다.

  • setInt(int parameterIndex, int x)
    SQL 쿼리문에서 ?로 표시된 정수형 변수에 값을 할당합니다.

  • setDouble(int parameterIndex, double x)
    SQL 쿼리문에서 ?로 표시된 실수형 변수에 값을 할당합니다.

  • setDate(int parameterIndex, Date x)
    SQL 쿼리문에서 ?로 표시된 날짜 변수에 값을 할당합니다.

  • setTime(int parameterIndex, Time x)
    SQL 쿼리문에서 ?로 표시된 시간 변수에 값을 할당합니다.

  • setObject(int parameterIndex, Object x)
    SQL 쿼리문에서 ?로 표시된 변수에 값을 할당할 때, 값의 데이터 형식을 명시하지 않고 Object로 할당할 수 있습니다.

이 외에도 PreparedStatement 클래스는 다양한 set 메서드를 제공합니다. set 메서드를 사용하여 SQL 쿼리문에서 ?로 표시된 변수에 값을 할당할 때는 변수의 데이터 형식에 맞는 set 메서드를 사용해야 합니다. 그렇지 않으면 예기치 않은 결과가 발생할 수 있습니다.

PrepagedStatement 예제 (특정 게시물 조회)

viewBoardlist.jsp (실행)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<table border="1">
	<tr>
		<td>게시판번호</td><td>제목</td><td>작성자</td><td>작성일</td><td>조회</td><td>좋아요</td>
	</tr>
<!-- 게시판 윗 부분은 반복하지 않아도 되므로 밖으로 빼줘서 처리해줌 -->
<%
	// JDBC 드라이버 로딩(mysql)
	Class.forName("com.mysql.jdbc.Driver");
	// java api에 db를 연결하기 위한 객체
	Connection conn = null;
	
	// workbench에서 sql을 작성한 후 (ctrl+enter)
	// sql문장을 작성을 하고, 그 sql문장을 실행을 위한 객체
	Statement stmt = null;
	
	// select의 결과를 DBMS에서 java로 저장하기 위한 객체
	ResultSet rs = null;
	
	// 연결하기
	// 드라이버 매니저에게 Connection 객체를 달라고 요청한다.
	// Connection을 얻기 위해 필요한 데이터(url,아이디,비밀번호)
	try{
		String jdbcDriver ="jdbc:mysql://localhost:3306/naver_1?serverTimezone=Asia/Seoul";
		String dbUser = "root";
		String dbPass = "1234";
		
		String query = "select * from board";	//executeQuery	- select만 다르다..
		// String query = "update board set title='가나다' where no = 1";	//executeUpdate
		// String query = "insert into board(title, content) values('제목입니다.','내용은 여기에...')";	// excuteUpdate
		// String query = "delete from board where no = 1";	//excuteUpdate
		
		conn = DriverManager.getConnection(jdbcDriver,dbUser,dbPass);
		
		stmt = conn.createStatement();
		// workbench ctrl+enter(쿼리문장을 실행)를 통해 도출된 select 결과를 ResultSet에 저장 ↓
		rs = stmt.executeQuery(query);
		
		// 데이터가 있을때까지 반복 -> 데이터가 있으면(true), 데이터가 없으면(false)값을 리턴하기 때문에
		// = 값이 있으면 넘겨줌
		while(rs.next()){		
%>
	<tr>
		<td>
			<%=rs.getInt("no") %>
		</td>
		<td><a href="viewBoardDetail.jsp?no=<%= rs.getInt("no")%>"><%=rs.getString("title") %></a></td>
		<td><%=rs.getString("id") %></td>
		<td><%=rs.getString("regdate") %></td>
		<td><%=rs.getInt("count") %></td>
		<td><%=rs.getInt("good") %></td>
	</tr>	
<%
	}
	out.println("DB 연결 성공");
		}catch(SQLException ex){
			out.println("DB 연결 실패");
		}finally{
			if(conn!=null){conn.close();}
	}
%>
</table>
</body>
</html>

viewBoardDetail.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<table border="1">
	<tr>
		<td>게시판번호</td>
		<td>제목</td>
		<td>내용</td>
		<td>작성자</td>
		<td>작성일</td>
		<td>조회</td>
		<td>좋아요</td>
	</tr>
<!-- 게시판 윗 부분은 반복하지 않아도 되므로 밖으로 빼줘서 처리해줌 -->
<%
	int no = Integer.parseInt(request.getParameter("no"));
	// JDBC 드라이버 로딩(mysql)
	Class.forName("com.mysql.jdbc.Driver");
	// java api에 db를 연결하기 위한 객체
	Connection conn = null;
	
	// workbench에서 sql을 작성한 후 (ctrl+enter)
	// sql문장을 작성을 하고, 그 sql문장을 실행을 위한 객체
	PreparedStatement pstmt = null;
	
	// select의 결과를 DBMS에서 java로 저장하기 위한 객체
	ResultSet rs = null;
	
	// 연결하기
	// 드라이버 매니저에게 Connection 객체를 달라고 요청한다.
	// Connection을 얻기 위해 필요한 데이터(url,아이디,비밀번호)
	try{
		String jdbcDriver ="jdbc:mysql://localhost:3306/naver_1?serverTimezone=Asia/Seoul";
		String dbUser = "root";
		String dbPass = "1234";
		
		conn = DriverManager.getConnection(jdbcDriver,dbUser,dbPass);
		
		String query = "select * from board where no = ?";	// excuteQuery
		
		pstmt = conn.prepareStatement(query);
		pstmt.setInt(1, no);	//첫번째 물음표에는 no값을 넣어라
		
		rs = pstmt.executeQuery();
		
		if(rs.next()){		
%>
	<tr>
		<td>
			<%=rs.getInt("no") %>
		</td>
		<td><%=rs.getString("title") %></td>
		<td><%=rs.getString("id") %></td>
		<td><%=rs.getString("content") %></td>
		<td><%=rs.getString("regdate") %></td>
		<td><%=rs.getInt("count") %></td>
		<td><%=rs.getInt("good") %></td>
	</tr>	
<%
	}
	out.println("DB 연결 성공");
		}catch(SQLException ex){
			out.println("DB 연결 실패");
		}finally{
			if(conn!=null){conn.close();}
	}
%>
</table>
</body>
</html>

viewBoardlist.jsp를 실행 -> 아무 게시판 제목을 클릭

클릭한 게시판 제목의 번호와 정보를 가지고 온다.

profile
뉴비 개발자 입니다. velog 주소 : https://velog.io/@jjinny_0609 Github 주소 :

0개의 댓글