지구정복

[JSP] 12/22 | 달력출력, JDBC라이브러리 JSP에서 사용하기, 커넥션 풀 사용하기 본문

데이터 엔지니어링 정복/JAVA & JSP

[JSP] 12/22 | 달력출력, JDBC라이브러리 JSP에서 사용하기, 커넥션 풀 사용하기

eeaarrtthh 2020. 12. 22. 20:33
728x90
반응형

복습

정적페이지 - html/css/js
동적페이지 - web program => html/css/js

web program
	CGI(Common Gate Interface)
		- 컴파일 후 실행
		- 컴파일 후 실행하므로 언어적인 마인드가 필요
		- 상대적으로 빠름
		- 대표적인 언어가 C/C++/Servlet
	Script
		- 소스가 바로 실행돼서 배우기 쉽다.
		- 상대적으로 느림
		- 대표적인 언어가 JSP 등 최신언어들

정적페이지는 웹서버만 있으면 된다. (아파치, NGiNX 등은 정적페이지 실행위한 웹서버)
동적페이지는 WAS가 있어야 한다.(WAS는 프로그램 해석기라 생각하면 된다)
	* jsp나 Servlet을 위한 WAS는 보통 아파치톰캣이다.

jsp는 html과 자바소스가 혼합된 형태 = html안에 자바 포함
Servlet은 클래스를 실행하는 형태 = 자바 안에 html포함하고 클래스로 구성되어있다.

jsp : 언어가 아니라 자바언어로 서버페이지 요청, 응답하기 위한 기술명이다.
	디렉티브		- <%@	- page, include, taglib
			<%@ page 를 page 디렉티브라고 한다.
				language
				contentType
				pageEncoding
				import
	
	정의		- <%!
			멤버필드
			멤버메서드

	스크립틀릿	- <%
			지역변수
			제어문

	표현식		- <%=
			out.println();


기본객체 5가지
	request	- 요청
			- get	- url과 연결되어서 요청, 길이 제한이 있다.
				- 파일첨부가 안 된다.
				- 주로 <a 태그 방식으로 사용
			- post	- 헤더안에 요청내용 포함해서 요청, 길이 제한 없다.
				- 파일 첨부 가능하다
				- 주로 <form 태그 방식으로 사용
		- getParameter( "변수명" );
		- setCharacterEncoding( "utf-8" );

	response

	out	- 출력객체
			- out.println( html )
	

 

ㅇ어제 했던 실습 강사님 코드

동일한 jsp에서 응답 요청하기

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import = "java.util.Calendar" %>
<%
	request.setCharacterEncoding( "utf-8" );

	String strYear = request.getParameter( "Year" );
	String strMonth = request.getParameter( "Month" );
	
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>

<script type="text/javascript">
	const calendar = function() {
		let year = document.frm.Year.value.trim();
		let month = document.frm.Month.value.trim();
		
		document.frm.submit();
	}
</script>

</head>
<body>

<form action="CalendarEx4.jsp" name="frm" method="post">
&nbsp&nbsp연도  &nbsp&nbsp&nbsp&nbsp&nbsp월 <br>
<select name="Year">
	<option value="2019">2019</option>
	<option value="2020">2020</option>
	<option value="2021">2021</option>
</select>


<select name="Month">
	<option value="1">1월</option>
	<option value="2">2월</option>
	<option value="3">3월</option>
	<option value="4">4월</option>
	<option value="5">5월</option>
	<option value="6">6월</option>
	<option value="7">7월</option>
	<option value="8">8월</option>
	<option value="9">9월</option>
	<option value="10">10월</option>
	<option value="11">11월</option>
	<option value="12">12월</option>
</select>

<input type="button" value="달력출력" onclick="calendar()">

</form>
<%
	if ( strYear != null && strMonth != null ) {
		int year = Integer.parseInt( strYear );
		int month = Integer.parseInt( strMonth );

		int START_DAY_OF_WEEK = 0;
		int END_DAY_OF_WEEK = 0;
		int END_DAY = 0;
		
		Calendar sDay = Calendar.getInstance();
		Calendar eDay = Calendar.getInstance();
		
		sDay.set(year, month-1, 1 );
		eDay.set(year, month, 1-1 );
		
		START_DAY_OF_WEEK = sDay.get( Calendar.DAY_OF_WEEK );
		END_DAY_OF_WEEK  = eDay.get( Calendar.DAY_OF_WEEK );
		END_DAY = eDay.get( Calendar.DATE );
		
		out.println( "<table width='800' border='1'>" );
		out.println( "<tr>" );
		out.println( "<td colspan='7'>       "  + year + "년 " + month + "월" + "</td>");
		out.println( "</tr>" );
		
		out.println( "<tr>" );
		out.println( "<td>SU</td><td>MO</td><td>TU</td><td>WE</td><td>TH</td><td>FR</td><td>SA</td>");
		out.println( "</tr>" );

		for ( int i = 1; i<START_DAY_OF_WEEK; i++ ) {
			out.print("<td></td>");
		}
		
		for( int i=1, n=START_DAY_OF_WEEK ; i<=END_DAY ; i++, n++ ) {
			if( n % 7 == 1 ) out.println( "<tr>");
			out.print( "<td>" + i + "</td>" );
			if( n % 7 == 0 ) out.println("</tr>");
		}
	        
		for( int i=END_DAY_OF_WEEK ; i<=6 ; i++ ) {
			out.println( "<td></td>" );
		}
		out.println( "</table>" );
	}
%>


</body>
</html>

 

ㅇ 외부 라이브러리 사용하기(JDBC)

먼저 jdbc 라이브러리를 복사해서 이클립스 웹 다이나믹 프로젝트 안에 lib 폴더에 넣는다.

 

이제 mariaDB에 dept 테이블 내용을 DB와 연동해서 출력해보자.

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.SQLException" %>

<%
	String url = "jdbc:mysql://localhost:3307/sample";
	String user = "root";
	String password = "!123456";
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
	Connection conn = null;
	PreparedStatement pstmt = null;
	ResultSet rs = null;
	//jsp는 오류를 스스로 없애서 jsp 코딩할때는 스스로 에러처리 코드를 넣어줘야한다.
	try {
		Class.forName( "org.mariadb.jdbc.Driver" );
		conn = DriverManager.getConnection(url, user, password);
		
		String sql = "select deptno, dname, loc from dept";
		pstmt = conn.prepareStatement(sql);
		rs = pstmt.executeQuery();
		while ( rs.next() ) {
			out.println( rs.getString( "deptno" ) + "<br>" );
		}
		
	} catch (ClassNotFoundException e) {
		out.println( "에러 : " + e.getMessage() );
	} catch (SQLException e) {
		out.println( "에러 : " + e.getMessage() );
	} finally {
		if ( rs != null ) rs.close();
		if ( pstmt != null ) pstmt.close();
		if ( conn != null ) conn.close();
	}
	
%>
</body>
</html>

 

실습) HTML 테이블에 아래와 같이 출력이 되도록 코딩해보자.

-코드

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.SQLException" %>

<%
	String url = "jdbc:mysql://localhost:3307/sample";
	String user = "root";
	String password = "!123456";
	
	Connection conn = null;
	PreparedStatement pstmt = null;
	ResultSet rs = null;
	
	StringBuffer html = new StringBuffer();
	
	try {
		Class.forName( "org.mariadb.jdbc.Driver" );
		conn = DriverManager.getConnection(url, user, password);
		
		String sql = "select deptno, dname, loc from dept";
		pstmt = conn.prepareStatement(sql);
		rs = pstmt.executeQuery();
		

		html.append( "<table border='1' width='500'>" );
		while ( rs.next() ) {
			html.append( "<tr>" );
			html.append( "<td>" + rs.getString( "deptno" ) + "<br>" + "</td>" );
			html.append( "<td>" + rs.getString( "dname" ) + "<br>" + "</td>" );
			html.append( "<td>" + rs.getString( "loc" ) + "<br>" + "</td>" );
			html.append( "</tr>" );
		}
		html.append( "</table>" );
		
	} catch (ClassNotFoundException e) {
		out.println( "에러 : " + e.getMessage() );
	} catch (SQLException e) {
		out.println( "에러 : " + e.getMessage() );
	} finally {
		if ( rs != null ) rs.close();
		if ( pstmt != null ) pstmt.close();
		if ( conn != null ) conn.close();
	}
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
	out.println( html );
%>
</body>
</html>

 

실습) 우편번호 검색기 만들기 아래와 같이 만들어보자.

 

-코드

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%@ page import="java.sql.DriverManager" %>
<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.SQLException" %>

<%
	request.setCharacterEncoding( "utf-8" );

	String strDong = request.getParameter( "dong" );
	
	StringBuffer html = new StringBuffer();
	if ( strDong != null ) {
		String url = "jdbc:mysql://localhost:3307/sample";
		String user = "root";
		String password = "!123456";
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
	
		try {
			Class.forName( "org.mariadb.jdbc.Driver" );
			conn = DriverManager.getConnection(url, user, password);
			
			String sql = "select zipcode, sido, gugun, dong, ri, bunji, seq from zipcode where dong like ?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString( 1, strDong + "%");
			rs = pstmt.executeQuery();
	
			html.append( "<table border='1' width='900'>" );
			while ( rs.next() ) {
				html.append( "<tr width='100'>" );
				html.append( "	<td>" + rs.getString( 1 ) + "<br>" + "</td>" );
				html.append( "	<td>" + rs.getString( 2 ) + "<br>" + "</td>" );
				html.append( "	<td>" + rs.getString( 3 ) + "<br>" + "</td>" );
				html.append( "	<td>" + rs.getString( 4 ) + "<br>" + "</td>" );
				html.append( "	<td>" + rs.getString( 5 ) + "<br>" + "</td>" );
				html.append( "	<td>" + rs.getString( 6 ) + "<br>" + "</td>" );
				html.append( "	<td>" + rs.getString( 7 ) + "<br>" + "</td>" );
				html.append( "</tr>" );
			}
			html.append( "</table>" );
			
		} catch (ClassNotFoundException e) {
			out.println( "에러 : " + e.getMessage() );
		} catch (SQLException e) {
			out.println( "에러 : " + e.getMessage() );
		} finally {
			if ( rs != null ) rs.close();
			if ( pstmt != null ) pstmt.close();
			if ( conn != null ) conn.close();
		}
	}
%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>우편번호 검색기</title>
<script type="text/javascript">
	const checkfrm = function() {
		if ( document.frm.dong.value.trim() == '' ) {
			alert( '동이름을 입력해주세요' );
			return;
		}
		document.frm.submit();
	}
</script>

</head>
<body>

<form action="ZipcodeEx1.jsp" name="frm" method="post">
동이름 입력하기<input type="text" name="dong">&nbsp&nbsp&nbsp
<input type="button" value="검색하기" onclick="checkfrm()">
</form>

<br><br><hr><br>
<%= html %>
</body>
</html>

 

 

ㅇ 커넥션 풀

p416

위에서는 데이터베이스에 직접적인 연결을 하였다.

커넥션 풀 기법이란 데이터베이스와 연결된 커넥션을 미리 만들어서 풀(pool) 속에 저장해 두고 있다가 필요할 때에 커넥션을 풀에서 가져다 쓰고 다시 반환하는 기법을 의미한다.

풀 속에 데이터베이스와 연결된 커넥션을 미리 생성해놓는다. 데이터베이스 커넥션이 필요하면, 커넥션을 새로 생성하는 것이 아니라 풀 속에 미리 생성된 커넥션을 가져다가 사용하고, 사용이 끝나면 커넥션을 풀에 반환한다.

커넥션 풀의 특징은 다음과 같다.

1. 풀 속에 미리 커넥션이 생성되어 있기 때문에 커넥션을 생성하는 데 드는 연결 시간을 줄일 수 있다.

2. 커넥션을 계속해서 재사용하기 때문에 생성되는 커넥션 수가 일정하게 유지된다.

 

WAS에서 만들어진 커넥션 풀을 이름을 정하고 그 커넥션 풀을 사용한다.

이를 JNDI라 한다.

이를 설정하는 것을 context.xml파일을 이용해서 한다.

 

 

JNDI를 이용해 커넥션 풀의 이름을 정하고 데이터베이스에 연결해보자.

먼저 새로운 프로젝트를 만들고 jdbc api를 lib폴더에 넣어놓자.

[new] > [file] > [source] 에서 아래와 같이 데이터베이스 연결에 대한 설정을 작성한다.

또한 아래의 xml파일은 META-INF에 집어넣는다.

<?xml version="1.0" encoding="utf-8" ?>
<Context>
	<Resource 
		name = "jdbc/mariadb1"
		auth = "Container"
		type = "javax.sql.DataSource"
		driverClassName = "org.mariadb.jdbc.Driver"
		url = "jdbc:mysql://localhost:3307/sample"
		username = "root"
		password = "!123456"
	/>
</Context>

이때 name에서 mariadb1은 사용자 임의로 정할 수 있다.

또한 톰캣서버가 켜져있으면 꺼야된다.

 

이제 새로운 jsp파일을 아래와 같이 만든다. 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%@ page import = "javax.naming.Context" %>
<%@ page import = "javax.naming.InitialContext" %>
<%@ page import = "javax.naming.NamingException" %>
<%@ page import = "javax.sql.DataSource" %>

<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.SQLException" %>


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>

<%
	Connection conn = null;
	PreparedStatement pstmt = null;
	ResultSet rs = null;
	
	try {
		Context initCtx = new InitialContext();
		//자바 환경변수 검색
		Context envCtx = (Context)initCtx.lookup( "java:comp/env" );
		//자바 환경변수에서 커넥션풀 이름이 mariadb1인 것을 찾아서 데이터 정보를 dataSource에 저장한다.
		DataSource dataSource = (DataSource)envCtx.lookup( "jdbc/mariadb1" );
		conn = dataSource.getConnection();
		out.println( "연결 성공" );
		
		String sql = "select deptno, dname, loc from dept";
		pstmt = conn.prepareStatement(sql);
		rs = pstmt.executeQuery();
		while( rs.next() ) {
			out.println( rs.getString(1) + "<br>");
		}
		
	} catch(NamingException e) {
		out.println( "error: " + e.getMessage() );
	} catch(SQLException e) {
		out.println( "error: " + e.getMessage() );
	} finally {
		if ( rs != null ) rs.close();
		if ( pstmt != null ) pstmt.close();
		if ( conn != null ) conn.close();
	}
%>

</body>
</html>

 

 

 

실습) 위에서 했던 우편번호 검색기를 커넥션 풀을 이용해서 만들어보자.

-context.xml

<?xml version="1.0" encoding="utf-8" ?>
<Context>
	<Resource 
		name = "jdbc/mariadb1"
		auth = "Container"
		type = "javax.sql.DataSource"
		driverClassName = "org.mariadb.jdbc.Driver"
		url = "jdbc:mysql://localhost:3307/sample"
		username = "root"
		password = "!123456"
	/>
</Context>

-ZipcodeEx1

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
    
<%@ page import = "javax.naming.Context" %>
<%@ page import = "javax.naming.InitialContext" %>
<%@ page import = "javax.naming.NamingException" %>
<%@ page import = "javax.sql.DataSource" %>

<%@ page import="java.sql.Connection" %>
<%@ page import="java.sql.PreparedStatement" %>
<%@ page import="java.sql.ResultSet" %>
<%@ page import="java.sql.SQLException" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>

<script type="text/javascript">
	const checkfrm = function() {
		if ( document.frm.dong.value.trim() == '' ) {
			alert( '동이름을 입력해주세요' );
			return;
		}
		document.frm.submit();
	}
</script>

</head>
<body>

<%
	request.setCharacterEncoding( "utf-8" );
	
	String strDong = request.getParameter( "dong" );
	
	StringBuffer html = new StringBuffer();

	if ( strDong != null ) { 
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		try {
			Context initCtx = new InitialContext();
			//자바 환경변수 검색
			Context envCtx = (Context)initCtx.lookup( "java:comp/env" );
			//자바 환경변수에서 커넥션풀 이름이 mariadb1인 것을 찾아서 데이터 정보를 dataSource에 저장한다.
			DataSource dataSource = (DataSource)envCtx.lookup( "jdbc/mariadb1" );
			conn = dataSource.getConnection();
			
			String sql = "select zipcode, sido, gugun, dong, ri, bunji, seq from zipcode where dong like ?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString( 1, strDong + "%");
			rs = pstmt.executeQuery();
	
			html.append( "<table border='1' width='900'>" );
			while ( rs.next() ) {
				html.append( "<tr width='100'>" );
				html.append( "	<td>" + rs.getString( 1 ) + "<br>" + "</td>" );
				html.append( "	<td>" + rs.getString( 2 ) + "<br>" + "</td>" );
				html.append( "	<td>" + rs.getString( 3 ) + "<br>" + "</td>" );
				html.append( "	<td>" + rs.getString( 4 ) + "<br>" + "</td>" );
				html.append( "	<td>" + rs.getString( 5 ) + "<br>" + "</td>" );
				html.append( "	<td>" + rs.getString( 6 ) + "<br>" + "</td>" );
				html.append( "	<td>" + rs.getString( 7 ) + "<br>" + "</td>" );
				html.append( "</tr>" );
			}
			html.append( "</table>" );
			
		} catch(NamingException e) {
			out.println( "error: " + e.getMessage() );
		} catch(SQLException e) {
			out.println( "error: " + e.getMessage() );
		} finally {
			if ( rs != null ) rs.close();
			if ( pstmt != null ) pstmt.close();
			if ( conn != null ) conn.close();
		}
	}
%>

<form action="ZipcodeEx1.jsp" name="frm" method="post">
동이름 입력하기<input type="text" name="dong">&nbsp&nbsp&nbsp
<input type="button" value="검색하기" onclick="checkfrm()">
</form>

<br><br><hr><br>
<%= html %>

</body>
</html>

 

ㅇ 게시판 만들기

Page Navigation(페이지간의 흐름)
*흐름상 숨겨진 페이지 찾기(디자인 없는 페이지)
	ex: 글쓰기에서 [쓰기]버튼을 누르면 DB에 적용된 후 다시 글목록으로 이동해야 한다.

글목록(board_list1.jsp)
	글쓰기(borad_write1.jsp)
		(글자료 필요)
		board_write_ok1.jsp
	(글번호 필요)
	글보기(borad_view1.sjp)
		(글번호 필요)
		글수정(borad_modify1.jsp)
			(글번호, 글자료 필요)
			board_modify_ok1.jsp
		(글번호 필요)
		글삭제(borad_delete1.jsp)
			(글번호, 글자료 필요)
			board_delete_ok1.jsp


-데이터베이스 테이블 구성
글번호	seq		int		not null		pk
제목	subject		varchar(150	not null
글쓴이	writer		varchar(12)	not null
비밀번호	password		varchar(12)	not null
내용	content		varchar(2000)
이메일	mail		varchar(50)
조회수	hit		int		not null
아이피	wip		varchar(15)	not null
등록일	wdate		datetime		not null


create table board1 (
seq int not null primary key auto_increment,
subject varchar(150) not null,
writer varchar(12) not null,
mail varchar(50),
password varchar(12)	 not null,
content varchar(2000),
hit int not null,
wip varchar(15) not null,
wdate datetime not null
);

insert into board1 values (0, '제목', '이름', 'test@test.com', '1234', '내용', 0, '000.000.000.000', now() );

auto_increment는 pk이며 int인 컬럼만 가능하고 테이블당 하나만 설정할 수 있다.

 

728x90
반응형
Comments