Connection 관리
기존 JDBC 프로그램 구현으로 DBMS와 연동 작업을 할때는 웹 클라이언트로부터 요청이 있을 때마다 DB서버에 연결하기 위해 Connection 객체를 얻어내야 했다.
하지만 이러한 기존의 JDBC 프로그래밍 작업에는 문제가 있다.
- DB프로그램에서 트랜잭션 처리와 Connection 관리는 시스템의 성능과 안전성에 큰 영향을 미친다.
- Connection 과정은 일정 시간이 필요한 부담과 작업이다.
- 불필요한 연결에 의한 서버 자원의 낭비를 발생한다.
Connection Pool
Connection 객체를 프로그램이 실행될 때마다 생성하는 것이 아니라, 웹 애플리케이션이 서비스되기 전에 웹서버에서
미리 생성하여 준비한 다음, 필요할 때 준비된 Connection을 가져다 사용함으로써 JDBC 프로그래밍의 문제점들을
개선한 기술
DataSource
Connection Pool은 Connection 객체가 생성되어 운용되는데, 이를 직접 웹 애플리케이션에서 다루기 힘들기 때문에 DataSource라는 개념을 도입하여 사용
DataSource에 대해 정의하자면 아래와 같다.
- 커넥션 풀의 Connection을 관리하기 위한 객체
- JNDI Server를 통해서 이용
- DataSource 객체를 통해서 필요한 Connection을 획득, 반납 등의 작업
DataSource를 이용하려면 다음의 절차를 따릅니다.
- JNDI Server에서 lookup( ) 메소드를 통해 DataSource 객체를 획득
- DataSource 객체의 getConnection( ) 메소드를 통해서 Connection Pool에서 Free 상태의 Connection 객체를 획득
- Connection 객체를 통한 DBMS 작업을 수행
- 모든 작업이 끝나면 DataSource 객체를 통해서 Connection Pool에 Connection을 반납
JNDI (Java Naming and Directory Interface)
디렉터리 서비스에서 제공하는 데이터 및 객체를 발견하고 참고하기 위한 자바 API
구현하기
DataSource는 서버에서 관리하는 리소스인 커넥션 풀을 사용할 수 있게 하는 객체로서,
서버가 시작할 때 커넥션 풀이 서버에 준비되어 있어야 한다.
server.xml 설정
Connection Pool은 서버에서 관리하는 자원
서버 환경 설정 파일인 Server.xml에 Connection 풀에 관한 설정을 한다.
<GlobalNamingResources>
.... 생략 ....
<Resource driverClassName="oracle.jdbc.driver.OracleDriver"
url="jdbc:oracle:thin:@127.0.0.1:1521:xe"
username="scott"
password="tiger"
name="jdbc/myoracle"
type="javax.sql.DataSource"
maxActive="4"
maxIdle="2"
maxWait="5000" />
</GlobalNamingResources>
<Resource> 태그의 속성
- driverClassName : DB작업을 위해 로딩할 JDBC 드라이버 파일에 드라이버 인터페이를 상속하는 파일명을 전체 이름으로 지정 ( Class.forName() 메소드의 인자값 )
- url : 접속할 DB 서버의 URL을 지정
- username : DB 서버에 로그인할 계정을 지정
- password : DB 서버에 로그인할 게정의 비밀번호를 지정
- name : 현재 리소스를 등록할 이름을 지정
- type : 리소스의 타입을 지정 , Connection Pool을 사용할 수있도록 해주는 객체의 javax.sqlDataSource
- maxActive : 생성할 Conneciton 수를 지정
- maxIdle : 일반적으로 활용할 Connection 수를 지정
- maxWait : Connection의 사용 요청이 있을 때 대기 시간을 지정, 5000은 5초를 의미하며, 5초가 지난 후에도 Connection을 얻지 못하면 Exception이 발생
이클립스에서 문제점
DBCP2에서는 maxActive 속성이 사용되지 않으며 maxActive로 설정한 값은 무시되며 대신 maxTotal을 사용하라고 경고 메시지를 띄운다.
해결 방법
WAS_HOME/conf/context.xml 파일을 편집한다.
<Context>
.... 생략 ....
<ResourceLink
global="jdbc/myoracle"
name="jdbc/myoracle"
type="javax.sql.DataSource" />
</Context>
web.xml 설정
서버에서 관리하는 리소스를 웹 애플리케이션에서 사용하기 위하여 /WEB-INF/web.xml 파일에 사용할 리소스에
대한 정보를 다음과 같이 지정
.... 생략....
<resource-ref>
<description>Oracle DataSource example</description>
<res-ref-name>jdbc/myoracle</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
.... 생략....
</web-app>
<resource-ref> 태그의 하위 태그
- <description> : 리소스에 대한 설명을 지정
- <res-ref-name> : 사용하고자 하는 리소스의 이름을 지정
- <res-type> : 사용하고자 하는 리소스의 타입을 지정
- <res-auth> : 리소스에 대한 권한이 누구인지 지정
DataSource를 사용하여 DB작업
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.sql.*" %>
<%@ page import="javax.sql.*" %>
<%@ page import="javax.naming.*" %>
<%
//1. JNDI 서버 객체 새성
InitialContext ic= new InitialContext();
//2. lookup()
DataSource ds = (DataSource) ic.lookup("java:comp/env/jdbc/myoracle");
//3. getConnection()
Connection conn = ds.getConnection();
Statement stmt=conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from test");
while(rs.next()) {
out.print(rs.getString("id") + ":" + rs.getString(2) + "<br>");
}
//반납
rs.close();
stmt.close();
conn.close();
%>
<%@ page import="java.sql.*" %>
<%@ page import="javax.sql.*" %>
<%@ page import="javax.naming.*" %>
java.sql 패키지는 일반 데이터베이스 작업을,
javax.sql 패키지는 DataSource 객체를 사용하기 위해,
javax.naming 패키지는 JNDI 작업을 하기 위해 import
InitialContext ic= new InitialContext();
커넥션 풀에 접근하려면 JNDI 서비스를 사용해야 한다.
JNDI는 서버에서 관리하고 있는 리소스에 대한 정보를 알고 있고 특정 리소스를 찾아서 사용할 수있도록 객체를 반환해주는 역할
DataSource ds = (DataSource) ic.lookup("java:comp/env/jdbc/myoracle");
ic.lookup( )은 리소스를 찾은 후 리소스를 사용할 수 있도록 객체를 반환해주는 메소드
lookup( ) 메소드의 인자값으로는 찾으려는 리소스의 등록된 이름을 지정
우리가 찾으려는 리소스의 이름은 "jdbc/myoracle" 이고 WAS인 톰캣에서 리소스를 관리하는 가상의 디렉터리는 "java:comp/env"
그러므로 lookup( ) 메소드의 최종인자 값은 "java:comp/env/jdbc/myoracle"이다.
Connection conn = ds.getConnection();
ds 변수는 DataSource 이다. DataSource 객체의 getConnection( )는 커넥션 풀에 준비된 Connection 객체를 빌려오는
메소드
빌려오는 Connection을 conn에 담습니다.
Statement stmt=conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from test");
while(rs.next()) {
out.print(rs.getString("id") + ":" + rs.getString(2) + "<br>");
}
rs.close();
stmt.close();
conn.close();//반납
%>
'JSP' 카테고리의 다른 글
프런트 컨트롤러 디자인 패턴 (0) | 2023.03.14 |
---|---|
MVC (2) | 2023.03.14 |
PreparedStatement 사용 이유 (0) | 2023.03.14 |
JDBC 프로그래밍 (0) | 2023.03.14 |
JSP - EL ( Expression Language ) (0) | 2023.03.14 |