본문으로 바로가기

JSP에서 DB연동 하기 - JNDI, DBCP(커넥션풀) 이용

category 코딩/JSP 2016. 11. 14. 22:26







<개발환경>

  • Eclipse

  • JSP

  • Tomcat 8.0

  • Oracle 11g 




JNDI외 DBCP란?



JNDI(Java Naming and Directory Interface) 란?


JNDI의 정의를 보면 디렉터리 서비스에서 제공하는 데이터 및 객체를 발견하고 참고(lookup)하기 위한 자바 API라고 되어있다. 쉽게 말하면 외부에 있는 객체를 가져오기 위한 기술이다. Tomcat와 같은 WAS를 보면 특정 폴더에 필요한 데이터 소스(라이브러리)가 있는데 그것을 우리가 사용하기 위해 JNDI를 이용해서 가져오는 것이다.



■ DBCP(Database Connection Pool, 커넥션 풀) 란?


데이터베이스와 연결된 커넥션을 미리 만들어서 저장해두고 있다가 필요할 때 저장된 공간(pool)에서 가져다 쓰고 반환하는 기법을 말한다. 커넥션 풀을 이용하면 커넥션을 미리 만들어두고 사용하기 때문에 매번 사용자가 요청할 경우 드라이버를 로드하고, 커넥션 객체를 생성해 연결하고 종료하는 비효율적인 작업을 하지 않아도 된다.  즉 데이터베이스의 부하를 줄일 수 있고 자원을 효율적으로 관리할 수 있다.




JNDI와 DBCP의 전체적인 구성





①. 사용자가 요청을 한다.

②. 요청은 Control을 거쳐 Molel로 전달된다.

③. Molel로 넘어간 요청은 JNDI에 등록된 데이터베이스 객체(Type:DataSource)를 검색한다.

④. JNDI를 통해 찾은 객체로부터 커넥션을 획득한다.

⑤. 데이터베이스 작업이 끝난 후 획득한 커넥션을 반납한다.




사전 준비



필요 파일


  • JDBC 드라이버 : 데이터베이스와 연결하기 위한 드라이버

  • Collections  : 자카르타 Pool API의 jar 파일

  • DBCP : DBCP API 관련 jar 파일

  • Pool : Pool API가 사용하는 자카르타 Collection API의 jar 파일


※ 참고 : commons-dbcp, commons-pool, commons-collections 라이브러리는 톰캣 6.0 부터 tomcat-dbcp.jar로 통합



파일 다운로드




여기에서는 톰캣 8.0과 오라클을 사용할 것이다. 따라서 필요한 파일은 tomcat-dbcp.jar와 오라클 JDBC 드라이버인 ojdbc6.jar 이다.


  • ojdbc6.jar : 설치한 드라이브:\app\오라클 설치한 사용자 계정\product\11.2.0\dbhome_1\jdbc\lib

  • tomcat-dbcp.jar : C:\Program Files\Apache Software Foundation\Tomcat 8.0\lib




JNDI와 DBCP를 이용한 DB연동 - 첫번째 방법



첫번째 방법은 context.xml과 web.xml을 이용하는 방법이다.


■ 작업 순서

  1. API 관련 jar 파일 설치 - lib폴더

  2. DBCP 정보 설정 - context.xml

  3. JNDI 리소스 사용 설정 - web.xml

  4. 자바 혹은 JSP 페이지에서 사용



1. API 관련 jar 파일 설치 - lib폴더



tomcat-dbcp.jar와 ojdbc6.jar 파일을 [WebContent] - [WEB-INF] - [lib] 폴더에 집어넣는다.



2. DBCP 정보 설정 - context.xml



이클립스에에서 [Servers] - [Tomcat v6.0 Server at localhost-config] 에 있는 context.xml 파일을 연다.





그리고 </Context> 위에 <Resource> 부분을 추가해 준다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<Resource auth="Container" 
          name="jdbc/orcl" 
          driverClassName="oracle.jdbc.driver.OracleDriver" 
          type="javax.sql.DataSource" 
          url="jdbc:oracle:thin:@ip주소:포트번호:전역 데이터베이스 이름" 
          username="접속계정"
          password="계정 비밀번호" 
          loginTimeout="10" 
          maxActive="50" 
          maxIdle="20"
          maxWait="5000" 
          testOnBorrow="true" />
 
 
<!--
    auth : 컨테이너를 자원 관리자로 기술
    name : JDBC이름, 변경 가능
    driverClassName : JDBC 드라이버
    type : 웹에서 이 리소스를 사용할 때 DataSource로 리턴됨
    username : 접속계정
    password : 접속할 계정 비밀번호
    
    loginTimeout : 연결 끊어지는 시간
    maxActive : 최대 연결 가능한 Connection수 (기본 20개)
    maxIdle : Connection pool 유지를 위해 최대 대기 connection 숫자
    maxWait : 사용 가능한 커넥션이 없을 때 커넥션 회수를 기다리는 시간 (1000 = 1초)
    testOnBorrow : db에 test를 해볼 것인지
-->
cs



3. JNDI 리소스 사용 설정 - web.xml



[WebContent] - [WEB-INF]에 web.xml을 생성한다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xmlns="http://java.sun.com/xml/ns/javaee" 
         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
         id="WebApp_ID" version="2.5">
 <display-name>JSP_create</display-name>
 
<resource-ref>
     <description>connection</description>
     <res-ref-name>jdbc/orcl</res-ref-name>
     <res-type>javax.sql.DataSource</res-type>
     <res-auth>Container</res-auth>
</resource-ref>
 
<!--
    description : 설명
    res-ref-name : JDBC 이름, <Resource>의 name 부분과 동일하게 입력
    res-type : <Resource>의 type 부분과 동일하게 입력
    res-auth : <Resource>의 auth 부분과 동일하게 입력
-->
 
 
</web-app>
cs



생성한 web.xml에 <resource-ref> 부분을 작성해 준다.



4. 자바 혹은 JSP 페이지에서 사용


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.sql.Connection;
import java.sql.SQLException;
 
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
 
public class DBConnection 
{
    public static Connection getConnection() throws SQLException, NamingException, 
    ClassNotFoundException{
            Context initCtx = new InitialContext();
            
            //initCtx의 lookup메서드를 이용해서 "java:comp/env" 에 해당하는 객체를 찾아서 evnCtx에 삽입
            Context envCtx = (Context) initCtx.lookup("java:comp/env");
            
            
            //envCtx의 lookup메서드를 이용해서 "jdbc/orcl"에 해당하는 객체를 찾아서 ds에 삽입
            DataSource ds = (DataSource) envCtx.lookup("jdbc/orcl");
            
            //getConnection메서드를 이용해서 커넥션 풀로 부터 커넥션 객체를 얻어내어 conn변수에 저장
            Connection conn = ds.getConnection();
            return conn;
            
            /*
             * 위의 코드를 아래와 같이 줄여서 작성 가능하다.
             Context context = new InitialContext();
             DataSource dataSource = (DataSource) context.lookup("java:comp/env/jdbc/oracle");
             Connection con = dataSource.getConnection(); 
             
             */
    }
}
cs




JNDI와 DBCP를 이용한 DB연동 - 두번째 방법



두번째 방법은 server.xml과 context.xml을 이용하는 방법이다.


작업 순서

  1. API 관련 jar 파일 설치 - lib폴더

  2. DBCP 정보 설정 - server.xml

  3. context.xml 파일 수정

  4. 자바 혹은 JSP 페이지에서 사용



1. API 관련 jar 파일 설치 - lib폴더



tomcat-dbcp.jar와 ojdbc6.jar 파일을 [WebContent] - [WEB-INF] - [lib] 폴더에 집어넣는다.



2. DBCP 정보 설정 - server.xml




이클립스에에서 [Servers] - [Tomcat v6.0 Server at localhost-config] 에 있는 server.xml 파일을 연다.





연동을 위해 server.xml에 소스 코드를 추가할 것이다. server.xml에 보면 <GlobalNamingResources>라는 태그가 있다. 이 태그 사이에 소스 코드를 추가하면 된다.





<GlobalNamingResources> 사이에 <Resource> 부분을 추가해 준다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<Resource auth="Container" 
          name="jdbc/orcl" 
          driverClassName="oracle.jdbc.driver.OracleDriver" 
          type="javax.sql.DataSource" 
          url="jdbc:oracle:thin:@ip주소:포트번호:전역 데이터베이스 이름" 
          username="접속계정"
          password="계정 비밀번호" 
          loginTimeout="10" 
          maxActive="50" 
          maxIdle="20"
          maxWait="5000" 
          testOnBorrow="true" />
 
 
<!--
    auth : 컨테이너를 자원 관리자로 기술
    name : JDBC이름, 변경 가능
    driverClassName : JDBC 드라이버
    type : 웹에서 이 리소스를 사용할 때 DataSource로 리턴됨
    username : 접속계정
    password : 접속할 계정 비밀번호
    
    loginTimeout : 연결 끊어지는 시간
    maxActive : 최대 연결 가능한 Connection수 (기본 20개)
    maxIdle : Connection pool 유지를 위해 최대 대기 connection 숫자
    maxWait : 사용 가능한 커넥션이 없을 때 커넥션 회수를 기다리는 시간 (1000 = 1초)
    testOnBorrow : db에 test를 해볼 것인지
-->
cs



위 코드를 보면 name="jdbc/orcl"로 되어있다. 여기서 jdbc/ 뒤에는 사용자가 임의로 지정하면 된다. 만약 뒤에 test로 하고 싶다면 name="jdbc/test" 이렇게 해주면 된다.


그리고 URL 부분에 ip 주소를 보자. 자신의 PC에 오라클이 설치되어 있다면 ip 주소에 localhost로 적으면 된다. 이 부분에 대한 자세한 설명은 아래 링크를 참고하면 된다.





3. context.xml 파일 수정




다음으로 할 일은 context.xml을 복사하는 것이다. Servers를 보면 context.xml 파일이 있다. 이것을 복사한다. 그리고 자신의 웹 프로젝트에 있는 META-INF 폴더에 붙여넣기 한다.


위에는 ST01_SignUp이라는 웹프로젝트에 META-INF 폴더에 붙여넣기 하였다.





그리고 META-INF 폴더에 붙여넣기한 context.xml을 연다. 그리고 위와 같은 소스 코드를 추가해주면 된다.


1
<ResourceLink global="jdbc/orcl" name="jdbc/orcl" type="javax.sql.DataSource"/>
cs


주의할 점은 global과 name 부분이다. 이것은 위에 server.xml의 <Resource>에 있는 name 부분과 똑같이 적어주어야 한다.



4. 자바 혹은 JSP 페이지에서 사용


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import java.sql.Connection;
import java.sql.SQLException;
 
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
 
public class DBConnection 
{
    public static Connection getConnection() throws SQLException, NamingException, 
    ClassNotFoundException{
            Context initCtx = new InitialContext();
            
            //initCtx의 lookup메서드를 이용해서 "java:comp/env" 에 해당하는 객체를 찾아서 evnCtx에 삽입
            Context envCtx = (Context) initCtx.lookup("java:comp/env");
            
            
            //envCtx의 lookup메서드를 이용해서 "jdbc/orcl"에 해당하는 객체를 찾아서 ds에 삽입
            DataSource ds = (DataSource) envCtx.lookup("jdbc/orcl");
            
            //getConnection메서드를 이용해서 커넥션 풀로 부터 커넥션 객체를 얻어내어 conn변수에 저장
            Connection conn = ds.getConnection();
            return conn;
            
            /*
             * 위의 코드를 아래와 같이 줄여서 작성 가능하다.
             Context context = new InitialContext();
             DataSource dataSource = (DataSource) context.lookup("java:comp/env/jdbc/oracle");
             Connection con = dataSource.getConnection(); 
             
             */
    }
}
cs




DB연동 예제 - 두번째 방법 사용



세팅을 끝냈다면 연동은 예제를 통해 알아보자. 간단한 예제이므로 JSP 파일 1개와 JAVA 파일 1개로 구성되어 있다. 패키지 구조는 아래와 같다. 




여기서 사용하는 테이블은 오라클 기본 계정인 SCOTT에 있는 EMP 테이블이다.



  • DBtest.jsp


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<%@ page language="java" contentType="text/html; charset=EUC-KR"
    pageEncoding="EUC-KR"%>
<%@ page import="java.sql.*"%>
<%@ page import="test.DBConnection"%> <!-- DB연결 클래스를 import한다. -->
<html>
 
<head>
</head>
<body>
    <center>
        <table border="3" bordercolor="skyblue">
        <tr bgcolor="skyblue"><td>이름<td>직업</tr>
        
        <%
        // 쿼리문
        String query="select ename, job from emp";
        
        // 커넥션 연결
        Connection conn = DBConnection.getConnection();
        
        // DB에 쿼리문을 보낸다.
        PreparedStatement pstmt = conn.prepareStatement(query);
        
        // 쿼리문의 결과값을 rs에 담는다.
        ResultSet rs = pstmt.executeQuery();
        
        // 결과값을 출력한다.
        while(rs.next()){
            out.println("<tr>");
            out.println("<td>"+rs.getString("ename"));
            out.println("<td>"+rs.getString("job"));
            out.println("</tr>");
        }
        
        %>
        </table>
    </center>
</body>
</html>
cs



DBtest는 DB에서 데이터를 가져와 화면에 보여주는 기능을 한다. 



  • DBConnection.java


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package test;
 
import java.sql.Connection;
import java.sql.SQLException;
 
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
 
public class DBConnection 
{
    public static Connection getConnection() throws SQLException, NamingException, 
    ClassNotFoundException{
            Context initCtx = new InitialContext();
            Context envCtx = (Context) initCtx.lookup("java:comp/env");
            DataSource ds = (DataSource) envCtx.lookup("jdbc/orcl");
            Connection conn = ds.getConnection();
            return conn;
    }
}
cs



DBConnection은 JNDI를 바탕으로 DB연결을 담당하는 클래스이다. 여기서 주의할 부분은 lookup("jdbc/orcl") 이다. 여기에는 context.xml의 <ResourceLink>에 있는 name 부분과 똑같이 적어주어야 한다. 



  • 실행결과




DBtest.jsp를 실행하면 EMP 테이블에서 ENAME와 JOB을 가져와 화면에 출력해준다.




MySQL 사용시 참고







RSS구독 링크추가 트위터 이메일 구독