Front-End/JSP

[JSP] JSP에서 DB연동하기 (JDBC, 오라클, 커넥션 풀)

현기 2022. 10. 8. 18:36

JDBC(Java DataBase Connectivity)

자바 언어로 DB 프로그래밍을 하기 위한 라이브러리입니다.

 

DBMS에 종속되지 않는 관련 API를 JDK에서 제공합니다.

사용하기 위해서는 각 DBMS 회사에서 제공하는

라이브러리 압축 파일인 JDBC 드라이버가 필요합니다.

 

오라클 JDBC 드라이버를 사용해서

JSP와 오라클 DB를 연동해 봅시다.

 


📝 JDBC 드라이버 가져오기

 

⦁ 어디에 있나요?

DBMS를 설치한 경로에 있습니다. 

C:\oraclexe\app\oracle\product\11.2.0\server\jdbc\lib

✔저는 오라클을 설치 했기 때문에 오라클의 JDBC가 있습니다.

 

이 JDBC를 사용하는 3가지 방법이 있습니다.

주로 3번째 방법을 사용한다고 합니다.

폴더가 없으시면 만들면 됩니다.

📝다음 중 한 가지 방법만 선택 하시면 됩니다.

1. JDK설치디렉터리\jre\lib\ext\ 에 복사하는 방법.
2. 톰캣설치디렉터리\common\lib 폴더에 복사하는 방법
★ 3. 이클립스 프로젝트의 WebContent\WEB-INF\lib 폴더에 복사하는 방법 

 


📝 JDBC에서 사용하는 객체 & 실행과정

 

🧾 JDBC는 다양한 클래스와 인터페이스로 구성된 패키지 java.sql와 javax.sql로 구성되어 있습니다.

 

⦁ DriverManager 클래스

JDK의 정적 클래스 입니다. JDBC 드라이버를 통해 커넥션을 만드는 역할을 합니다.

Calss.forName(드라이버) 메서드를 사용해 클래스를 로딩하면 자동으로 객체가 생성되고

DriverManager에 등록됩니다.

getConnection 메서드를 통해 커넥션 인터페이스의 구현 객체를 생성할 수 있습니다.

✔ 예시 코드
Class.forName(driver);
conn = DriverManager.getConnection(url, "hr", "1234");

 

⦁ Connection 인터페이스

Connect 객체는 DB와 연결된 커넥션을 나타냅니다.

SQL문을 실행시키기 위해서 필요한 Statement 객체를 생성할 때 사용합니다.

 

⦁ Statement 인터페이스

Connection 객체의 createStatment() 메서드를 통해 생성됩니다.

exequteQuery(sql문), exequteUpdate(sql문) 메서드를 사용해서

쿼리문을 실행시킬 수 있습니다.

간단한 쿼리문을 사용할 경우 좋다고 합니다.

✔예시 코드
Statement stmt = conn.createStatement();
int result = stmt.executeUpdate(sql);
-> 리턴 값이 0이면 쿼리문이 실패했다는 뜻입니다.

 

⦁ PreparedStatement 인터페이스

Statement와 비슷합니다. Connect 객체의 preapareStatement() 메서드로 객체를 생성합니다.

차이점은 SQL문이 미리 컴파일 되고, 실행 시간 동안 인수 값을 위한 공간을 확보합니다.

 

쉽게 말하면, 위치 홀더(placeholder)를 사용하여 쿼리문에 넣을 데이터를 ?로 넣으면

SQL문이 실행 되기 전에 실제 값으로 대체됩니다.

 

Statement보다 수행 속도도 빠르고 서버 측면에서도 효율적이라고 합니다.

✔예시 코드
String sql = "INSERT INTO student (num, name) VALUES (?, ?)"; 

PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, 정수);
pstmt.setString(2, 문자열);
pstmt.executeUpdate();  // 0이 아니면 성공입니다.

 


📝DB 연동

 

⦁ JSP 파일 생성

JDBC를 사용하기 위한 사전 작업을 끝냈으니, 코드를 작성해 봅시다.

<%@ page import="java.sql.*" %>
<%
   Connection conn = null;

   String driver ="oracle.jdbc.driver.OracleDriver";
   String url = "jdbc:oracle:thin:@localhost:1521:XE";
   
   Boolean connect = false;
   
   try {
      //DriverManagerr 객체 생성, 등록
      Class.forName(driver);
      
      //오라클 계정 id, 비밀번호 입력
      conn = DriverManager.getConnection(url, "user", "password");
      
      connect = true;
      conn.close();
      
   } catch(Exception e) {
      connect = false;
      e.printStackTrace();
   }
%>

...

<% if(connect = true) { %>
   <h3>연결되었습니다.</h3>
<% } else { %>
   <h3>연결에 실패했습니다.</h3>
<% } %>

 

🤔 하지만 이 방법은 잘 사용하지 않습니다.

 

위와 같이 직접 DB에 연결해서 사용하면,

매번 사용자가 요청할 때마다 드라이버를 로드하고 커넥션 객체를

생성하여 연결하고 종료해야 하기 때문에 매우 비효율 적입니다.

 

또한 아이디와 비밀번호가 그대로 노출되는 문제점도 있습니다.

따라서 거의 100% 커넥션 풀을 사용합니다.

 


📝 커넥션 풀이란?

 

https://linked2ev.github.io/spring/2019/08/14/Spring-3-%EC%BB%A4%EB%84%A5%EC%85%98-%ED%92%80%EC%9D%B4%EB%9E%80/

 

⦁ 개념

WAS가 실행되면서 DB와 미리 커넥션을 연결해 놓은 객체들을 pool에 저장해 두고,

클라이언트 요청이 오면 커넥션을 빌려주고, 처리가 끝나면 다시 반납받아

저장하는 방식을 말합니다.

 

⦁ 동시 접속자가 많을 경우

사용 중인 커넥션이 반납될 때까지 번호순대로 대기 상태로 기다립니다.

 

⦁ 사용해보기

1. WebContent/META-INF 폴더에 context.xml 파일 생성

#context.xml

<Context>
	<Resource name = "jdbc/OracleDB"
			auth="Container"
			driverClassName="oracle.jdbc.driver.OracleDriver"
			type="javax.sql.DataSource"
			url = "jdbc:oracle:thin:@localhost:1521:xe"
			username="hr"
			password="1234"
			maxActive="20"
			maxIdle="10"
			maxWait="-1"	
	/>
</Context>

 

2. WEB-INF/web.xml 파일에 작성

web.xml이 가장 먼저 불러오는 파일이기 때문에 여기에

context.xml을 불러오도록 작성해야 합니다.

  #web.xml에 작성
  
  <resource-ref>
  	<description>Connection</description>
  	<res-ref-name>jdbc/OracleDB</res-ref-name>
  	<res-type>javax.sql.DataSource</res-type>
  	<res-auth>Container</res-auth>
  </resource-ref>

 

3. JSP 파일 생성하고 커넥션 풀 사용하기

<%@ page import="java.sql.*" %>
<%@ page import="javax.sql.*" %>
<%@ page import="javax.naming.*" %>
<%
	Connection conn = null;
	
	try{
		Context init = new InitialContext();
		DataSource ds = (DataSource) init.lookup("java:comp/env/jdbc/OracleDB");
		conn = ds.getConnection();
		
		out.println("<h3>연결되었습니다.</h3>");
	} catch(Exception e){
		out.println("<h3>실패</h3>");
		e.printStackTrace();
	}
%>

 

✔ 쉽지 않았지만 커넥션 풀은 정말 많이 사용하기 때문에 잘 알아둬야 한다고 합니다. 😀

 

 


📝 JDBC & JSP 실습

 

✔ 지금까지 JDBC의 이론들에 대해 알아보았습니다.

마지막으로 JDBC를 활용하여 간단하게 구현해 봅시다.

 

더보기

1페이지는 DB에 있는 회원들의 정보를 보여줍니다.

2페이지는 받은 파라미터를 DB에 INSERT 해주고 사용자를 다시 1페이지로 보냅니다.

 

📝PAGE1

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@ page import="java.util.*"%>
<%@ page import="java.sql.*" %>
<%@ page import="javax.sql.*" %>
<%@ page import="javax.naming.*" %>
<%
	Connection conn = null;
	String sql="SELECT * FROM temp"; //쿼리문
	ArrayList<String> arr = new ArrayList<String>(); //결과 담을 변수
	int count = 1;

	try{
		Context init = new InitialContext();
		DataSource ds = (DataSource) init.lookup("java:comp/env/jdbc/OracleDB");
		conn = ds.getConnection();
		
		PreparedStatement pstmt = conn.prepareStatement(sql);
		ResultSet rs = pstmt.executeQuery();
		
		while(rs.next()){			
			arr.add(""+count+" : "+rs.getString(1)+", "+rs.getString(2));
			count++;
		}
		
	} catch(Exception e){
		out.println("<h3>레코드 등록 실패</h3>");
		e.printStackTrace();
	}
%>

<!DOCTYPE html>
<html>
<head>
<meta charset="EUC-KR">
<title>JDBC 실습</title>

</head>
<body>
<center>
	<h3>이벤트 등록</h3>
	<hr/>
	<form id="userinfoForm" action="Page2.jsp" method="post">
		<table>
			<tr>
				<td>등록이름 : </td>
				<td><input type="text" size="20" name="uname" minlength="2" maxlength="10"></td>
				<td>이메일 : </td>
				<td><input type="text" size="20" name="email" minlength="2" maxlength="30"></td>
				<td><input type="submit" width="10" id="btn" value="등록"></td>
			</tr>
		</table>
	<hr/>
</center>

<p># 등록 이름</p>
<%
for(String s : arr){
	out.println("<p>"+s+"</p>");
}; 
%>

</body>
</html>

 

📝PAGE2

<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
    
<%@ page import="java.sql.*" %>
<%@ page import="javax.sql.*" %>
<%@ page import="javax.naming.*" %>
<%
	//파라미터 받아오기
	request.setCharacterEncoding("EUC-KR");
	String uname = request.getParameter("uname");
	String email = request.getParameter("email");

	Connection conn = null;
	String sql="INSERT INTO temp (name, email) VALUES (?, ?)"; //쿼리문	

	try{
		Context init = new InitialContext();
		DataSource ds = (DataSource) init.lookup("java:comp/env/jdbc/OracleDB");
		conn = ds.getConnection();
		
		PreparedStatement pstmt = conn.prepareStatement(sql);
		pstmt.setString(1, uname);
		pstmt.setString(2, email);
		if(pstmt.executeUpdate() != 0){
			out.println("<h3>레코드 등록 성공</h3>");
		}
		
	} catch(Exception e){
		out.println("<h3>레코드 등록 실패</h3>");
		e.printStackTrace();
	}
	
	response.sendRedirect("Page1.jsp");
%>   

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

 


 


참고 문헌 : 

 

https://linked2ev.github.io/spring/2019/08/14/Spring-3-%EC%BB%A4%EB%84%A5%EC%85%98-%ED%92%80%EC%9D%B4%EB%9E%80/

https://steady-coding.tistory.com/564

https://programmingyoon.tistory.com/53

반응형