본문 바로가기
WORKS/DataBase

[DataBase] JSP 파일에서 DB 연동하기 / JSP DB 연동하기 / Connection Pool 이용 Oracle 데이터베이스 연결 / DBCP, JNDI

by Jelly 젤리 2022. 2. 25.

지난 글에서는 JDBC를 이용하여 Oracale Database와 연결해보는 과정을 살펴보았습니다.

이번 글에서는 JDBC의 단점을 보완한 Connection Pool이라는 개념을 알아보도록 하겠습니다.


JDBC 프로그래밍의 문제점

JDBC와 DBMS와의 연동작업은 Connection이라는 객체를 생성하면서 이루어졌는데요

이 연동작업은 클라이언트로부터의 요청이 있을 때마다 매번 이루어져야한다는 점에서 문제가 발생합니다.

이러한 일련의 과정들은 시간과 비용적인 측면에서 비효율을 낳습니다.


DBCP (DataBase Connection Pool)

Connection Pool은 연결 풀이라고도 합니다.

이 개념은 데이터베이스로의 추가 요청이 필요할 때 연결을 재사용할 수 있도록, 데이터 베이스 메모리 내에서 관리되는 캐시라고 보시면 됩니다.

Pool은 말 그대로 수영장같은 개념입니다. 이 연결을 한번 해두면 풀에 연결이 계속 위치해있기 때문에, 다시 사용하려는 요청이 들어왔을 때 풀에 있는 것을 그대로 다시 가져다 쓰면 되는 것입니다. 즉 새로운 연결을 할 필요가 없다는 점이 큰 장점입니다.

다만 모든 커넥션이 사용중에 있으면 새로운 연결이 만들어져 풀에 추가됩니다.

커넥션 풀은 사용자가 데이터베이스에 연결을 수립하는데까지 대기해야하는 시간을 줄입니다.

 

다시 말해, Connection 객체를 프로그램이 실행될 때마다 생성하는 것이 아니라 어플리케이션 서비스 전에 서버에서 미리 생성하여 pool에 담아둔 것을 필요할 때마다 가져다 쓰는 것입니다. 마치 수영장(Connection Pool)에 둥둥 떠다니는 공용 공(Connection)들을 떠올리시면 이해가 편할겁니다.


커넥션 풀의 생성

커넥션 풀 객체를 이용하기 위해서는 Context라는 인터페이스가 필요합니다.

이 인터페이스는 java.naming.Context의 경로를 갖습니다.

Context 인터페이스의 생성은 InitialContext 클래스를 이용하여 생성합니다.

 


DataSource 객체

커넥션풀을 관리해주는 객체는 DataSource가 있습니다.

이 객체는 JNDI라는 Server를 통하여 이용되며, DataSource 객체를 이용해 Connection객체를 획득하거나 반납하는 작업을 합니다.

DataSource의 경로는 javax.sql.DataSource입니다.

 

JNDI Server에서는 lookup()메소드를 이용해 DataSource 객체를 얻습니다.

이후 DataSource객체의 getConnection()메소드를 통해 connection pool에 free 상태의 Connection 객체를 획득하는 것입니다.

이렇게 얻어진 Connection 객체를 통해 DBMS의 작업을 수행하면 됩니다.

작업이 끝나면 DataSource 객체를 통해 Connection Pool에 다시 Connection을 반환합니다.

 

https://docs.oracle.com/javase/7/docs/api/javax/sql/DataSource.html

 

DataSource (Java Platform SE 7 )

A factory for connections to the physical data source that this DataSource object represents. An alternative to the DriverManager facility, a DataSource object is the preferred means of getting a connection. An object that implements the DataSource interfa

docs.oracle.com

+ JNDI Server? (더보기 클릭)

더보기

JNDI(Java Naming and Directory Interface)

디렉터리 서비스에서 제공하는 데이터 및 객체를 발견(discover)하고 참고(lookup)하기 위한 자바 API

자바 애플리케이션을 외부 디렉터리 서비스(주소 데이터베이스 등)에 연결하는 등의 용도로 쓰입니다.

javax.naming 패키지 안에 존재합니다.


DBCP를 이용한 데이터베이스 연동

아래에서 코드를 보면서 설명하도록 하겠습니다.

1.연결 코드

[3] 데이터베이스 작업을 위한 import

[4] DataSource 객체를 사용하기 위한 import

[5] JNDI 작업을 위한 import

[15]Connection 객체를 지정하기 위해 참조변수 세팅

[18] Context 인터페이스를 오버라이딩. InitialContext라는 클래스를 통해 생성

[19] DataSource 객체의 lookup이라는 메서드를 이용해 앞에서 생성해준 클래스의 객체를 반환받는다.
       이 때 데이터소스 객체는 Object타입으로 소스를 반환해주기 때문에 DataSource type으로 형변환을 해줍니다.
       ("java:comp/env/" 까지는 고정이고 그 뒤로는 context.xml 파일에 기입한 정보 중 name 값을 넣어줍니다)

[20] DataSource 객체의 getConnection이라는 메소드를 이용해 연결을 얻어옵니다 -> Connection Pool에 담겨진 Connection 객체를 빌려오는 행위가 여기서 이루어집니다.

[+] conn.close()를 써주어 연결을 반납할 수 있습니다.

 

이렇게만 써서는 컨텍스트를 불러오지 못합니다. 아래에서 더 살펴보도록 하겠습니다.

더보기

-Connection Pool 얻어오기-

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

    pageEncoding="UTF-8"%>

<%@ page import="java.sql.*"%>

<%@ page import="javax.sql.*"%>

<%@ page import="javax.naming.*"%>

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<title>Connection Pool - DataSource</title>

</head>

<body>

<div align="center">

<%

    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();

    }

%>

</div>

</body>

</html>


2. context.xml 파일 설정

여기서는 Context에서 Resource를 설정해줍니다.

[3] driverClassName : DB작업을 위해 로딩할 JDBC 드라이버 파일에 드라이버 인터페이스를 상속하는 파일명을 전체 이름으로 지정. Class.forName()의 인자값으로 들어가는 내용입니다. 

[4] url : 접속할 DB 서버의 URL 

[5] username : DB 서버의 계정

[6] password : 해당 계정의 비밀번호

[7] name : 현재 리소스를 등록할 이름

[8] type : 리소스의 타입. Connection Pool을 사용할 수 있도록 해주는 객체인 javax.sql.DataSource 타입으로 지정합니다.

[9] auth : -

[10] maxActive : 생성할 커넥션 개수. 동시에 사용할 수 있는 최대 커넥션의 개수를 지정(기본값 8)

[11] maxIdle : 일반적으로 활용할 커넥션 수. Connection 객체를 유지할 수 있는 최대 값을 지정 (기본값 8)

[12] maxWait : 커넥션 요청이 있을 때의 대기 시간 지정(1/1000초 단위). 이 시간이 지나도 커넥션을 사용하지 못한다면 예외가 발생합니다.

더보기

-서버의 context.xml을 context.xml을 META-INF에 복붙하고 안에 내용 아래와 같이 설정하는 방식 사용-

<?xml version="1.0" encoding="UTF-8"?>

<Context>

    <Resource driverClassName="oracle.jdbc.driver.OracleDriver"

    url="jdbc:oracle:thin:@localhost:1521:XE"

    username="jelly"

        password="****"

    name="jdbc/OracleDB"

    type="javax.sql.DataSource"

        auth="Container"

        maxActive="20"

        maxIdle="10"

        maxWait="-1"

         />

</Context>

 

찾아보니 서버의 server.xml과 context.xml을 설정해주는 방식도 있었습니다. 방식이 여러가지인것같아요!


3. web.xml 파일 설정

WEB-INF - lib 폴더 하위의 web.xml에는 resouce-ref 태그를 삽입해줍니다.

[13] description : 리소스에 대한 설명

[14] res-ref-name : 사용하고자 하는 리소스의 이름

[15] res-type : 사용하고자 하는 리소스의 타입

[16] res-auth : 리소스에 대한 권한 지정

더보기

-web.xml파일의 web-app태그 안에 resource-ref태그 설정을 해줍니다-

<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>


정리하자면,

DB를 활용한 홈페이지를 제작하여서 그 홈페이지에서 데이터베이스에 접근할 때 JDBC 드라이버가 필요하고

JDBC가 Connection Pool의 형식으로 데이터베이스에 연결되었을 때 DataSource객체를 가져다 쓰기 위해서 JNDI가 필요합니다.

 

 


여기까지 Oracle Database와 파일을 연동하는 방법을 알아보았습니다.

다음 글에서는 웹 브라우저에서 데이터를 직접 db에 저장하고 삭제하고 수정하는 글들을 차례로 살펴보도록 하겠습니다!

728x90

댓글