-
데이터를 유지하기 위해서 초창기에는 애플리케이션마다 별도의 파일 시스템에 데이터를 저장하는 방법을
사용했다. 그런 이 방법은 여러 애플리케이션에서 데이터에 접근하기 가 어렵고 데이터의 종속성과
독립성, 동시 사용성, 데이터 무결성에 심각한 문제가 발생했다.
중복된 데이터 때문에 보안을 보장하기도 힘들었다.
초창기 파일 시스템의 문제였던 데이터의 종속성과 중복성 문제를 해결하고 여러 애플리케이션들이 데이터를
공유 할수 있도록 개선한 시스템이 DBMS(Data Base Management System)입니다. DBMS 는 데이터베이스를 공용
할 수 있도록 관리하는 시스템을 의미한다.
JDBC 프로그래밍
JDBC 프로그래밍은 자바 프로그램 내에서 DB 관련 작업을 하는 프로그램을 의미한다.DB관련 작업을하려면 DBMS가 필요하며,자바 프로그램내에서 DBMS에 접근하여 DB관련 작업을 하기위한 API들이 필요하다.이번 절에서 DBMS를 설치한 후 JDBC API를 이해하고 JDBC 프로그램의 절차를 학습한다.JDBC 개요
JDBC는 JavaDataBase Connectivity의 약자로 자바언어로 다양한 종류의 관계형 데이터 베이스에 접속하고SQL문을 수행하여 처리하고자 할때 싸용되는 표준 SQL 인터페이스 API 이다.JDBC는 자바의 표준 애디션에서 지원하는 기술로서접속하려는 DBMS 서버에 따라서 JDBC 드라이버가 필요하다.다음은 JDBC 기술로 구현하는 자바프로그램의 연동 과정을 설명하는 그림이다.(1) JDBC 인터페이스
jdbc 인터페이스는 JDBC를 프로그램을 하기위한 API들로서 SE에서 제공하는 java.sql 패키지를 의미한다.java.sql 패키지의 객체들이다.java.sql 패키지는 개발자가 JDBC프로그래밍을 할때 필요한 기능이 있는 객체들로 구성되어 있다.java.sql 패키지에는 여러 개의 인터페이스와 클래스 객체들이 있는데.JDBC 프로그래밍을 할때 사용되는 객체는 인터페이스들이다.즉. JDBC 프로그래밍을 할때는 java.sql의 인터페이스들로 작업한다.이 말은 옳은 말이면서 옳지 않은 말이다.옳은 말이라는 의미는 개발자가 JDBC 프로그램을 구현하면서 실제로 사용하는 객체들은 대부분 인터페이스가 맞다.옳지 않은 말이란 의미는 실제로 DB관련 기능이 동작하려면 인터페이스만으로는 작업할 수 없기 때문이다.인터페이스틑 선언부만 있는 객체
그래서 JDBC프로그래밍을 할때는 java.sql의 인터페이스들로 구현하며 , 실제로 구현된 프로그램이 정상적으로 동작하게 하려면
java.sql의 인터페이스들을 상속하여 메소드의 몸체를 구현한 클래스 파일들이 필요하다.
이 파일들을 JDBC 드라이버라고 하며 사용하는 DB벤더사에서 내려받아 사용하면 된다.
(2)JDBC 드라이버
드라이버 파일준비하는 방법은 2가지1. 데이터베이스가 설치된 폴더에 저장된 파일을 사용하는 방법2. 오라클 웹사이트에서 접속해서 내려받는 방법JDBC 파일연결
java.sql 패키지의 인터페이스들을 상속하여 구현한 JDBC 드라이버 파일은 JDBC 프로그래밍을 하기전에 반드시 준비해서 자바 프로그램에서
사용할 수 있도록 연결 해두어야한다.
JDBC 드라이버 파일준비
오라클설치 폴더의 JDBC드라이버 파일위치C:\oracleexe\app\oracle\product\11.2.0\server\jdbc\lib다운받을 수 잇는 주소www.oracle.com/technetwork/database/enterprise-edition/jdbc-112010-090769.htmlJDBC 드라이버 파일 연결
준비된 JDBC 드라이버 파일을 웹 애플리케이션에 자동으로 인식 할 수 있는 곳은 두군데 ,첫째는 WAS가 설치된 HOME 폴더 밑의 lib폴더두번째는 각웹 애플리케이션 /WEB-INF/lib 폴더에 저장해야한다./WEB-INF/lib 폴더에 저장하면 해당 웹 애플리케이션에서만 사용할 수 있다는 차이점이 있다.구현
JDBC 프로그램잉을 구현하기에 앞서 머저 준비 되어야 하는 환경을 다시 확인1. DB API : DB 작업을 하기 위해 사용하는 java.sql 패키지로서 SE 에서 제공한다.
2. JDBC 드라이버 : 실제 DB 작업을 처리하는 파일로서 /WEB-INF/lib에 준비 되어있다.
3. DBMS : DBMS는 오라클 11g EE으로 설치를 완료한다.
JDBC 프로그램 실행 환경이 준비되었다면 JDBC 프로그램을 구현한다. 일반적으로 JDBC 프로그래밍을 할때 다음 순서로 작업 해야 한다.
1. JDBC 드라이버 로딩하기
2. DBMS 서버와 접속하기
3. Statement 또는 PreparedStatement 객체 생성하기
4. SQL 문 실행하기
5. 자원 해제 하기
(1) JDBC 드라이버 로딩
JDBC 프러그래밍을 할때 사용되는 개체는 SE에서 제공하는 java.sql의 인터페이스 들이지만,실제 데이터베이스에 관한 작업을 처리하는 기능은 JDBC드라이버에 구현되어있다.따라서 DB에 관한 작업을 할때 가장 먼저 해야 하는 일은 준비된 JDBC 드라이버 파일을 사용할 수 있게메모리에 로딩 하고 사용준비를 하는 것이다.준비된 JDBC 드라이버를 사용할 수있도록 메모리에 준비작업을 해주는 메소드 java.lang 패키지의 Class 클래스에서제공하는 forName( ) 메소드이다.static Class <?> forName(String className)
사용방법은 다음과 같다.Class.forName("oracla.jdbc.driver.OracleDriver");forName() 메소드는 static으로 선언되어 있어서 사용할 때 "클래스이름. 메소드이름( )" 형태로 사용한다.forName( ) 메소드의 인자값으로 JDBC 드라이버 파일 안에서드라이버 인터페이스를 상속하고 있는 클래스이름을 패키지 이름과 함께 정확히 명시해두어야 한다.드라이버 인터페이스를 상속하고 있는 파일은 사용하는 JDBC 드라이버마다 다르다.JDBC드라이버 파일을 준비한 다음 파일에 대한 정볼르 확인한다.Class.forName( )에 의해 JDBC 드라이버 파일의 드라이버 인터페이스를 상속한 클래스가
동적으로 로딩될때 자동으로 JDBC 인스턴스가 생성되어 사용준비가 완료된다.
(2) DBMS 서버 접속
JDBC 드라이버의 사용준비가 완료되면 이제 본격적으로 DB 작업을 한다.첫번째 작업이 데이터베이스 서버에 접속하여 연결하는 작업이다.DB 서버와의 연결작업은java.sql 패키지의 DriverManager 클래스의 getConnection( ) 메소드를 사용한다.static Connnection getConnection(String url , String user , String password)
getConnection( ) 메소드는 static으로 선언되었으므로 다음과 같이 "클래스이름.메소드이름" 형식으로 사용한다.Connection conn= DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","scott","tiger")getConnection 메소드의 인자값에 대한 설명은 다음과 같다.
- String url : 접속할 서버의 URL을 정확하게 지정한다.
jdbc:oracle:thin:@localhost:1521:xe
| | | |
오라클 protocol 서버주소 서버포트 DB이름
String user : DB 서버에 로그인할 계정을 지정한다.
Stgring password : DB 서버 로그인할 비밀 번호를 지정한다.
Connection
DriverManager.getConnection( ) 은 실제 자바 프로그램과 데이터베이스를 네트워크상에서 연결을 해주는 메소드이다.
연결에 성공하면 DB와 연결된 상태를 Connection 객체로 표현하여 반환한다.
Connection은 네트워크상의 연결 자체를 의미한다.
(3) Statment 객체
다음 자바 프로그램과 DB 사이에 연결된 Connection을 나타내는 그림이다.Connection 객체는 실제 자바 프로그램과 DB 사이를 네트워크 상에서 연결된 상태를 의미이 Connection을 자바 프로그램과 DB 사이에 연결된 길이라고 생각해야한다.즉 DriverManager.getConnection( ) 메소드는 자바 프로그램과 DB와 연결된 길을 만들어 주는 기능을 한다.1대1로 연결된 길(Connection)이 만들어 졌으면 이 길을 통해 자바 프로그램은 DB 쪽으로 SQL 문을 전송하고,DB는 처리된 결과를 다시 자바 프로그램 쪽으로 전달해야한다.바로 이역할을 하는 객체가 Statement이다.즉 Statement 객체는 도로 전용으로 만들어지며 , 서로에게 데이터를 전달해주는 객체이다.Statement 생성
Statement 객체를 생성하려면 Connection 객체에서 제공하는 createStatement( ) 메소드를 사용한다.State createStatement( )
Connection 객체의 변수가 conn 일 때 Statement 객체를 생성하는 코드는 다음과 같다.
Statement stmt = conn.createStatement( );
위 코드가 실행되면 다음 그림에서 보는 것 처럼 자바 프로그램과 DB와 연결된 길의 이름은 conn 이고 , conn이란 도로전용으로 사용되는 SQL문과
처리결과를 서로 전달해주는 트럭과 같은 역할을 하는 stmt가 만들어진 것이다.
SQL 문 실행
SQL 문을 실행하기위해 사용되는 메소드는 Statement 객체에서 제공하는 executeQuery( ) 또는 executeUpdate를 사용한다.다음 은 Statement 객체에서 제공하는 executeQuery( ) 와 executeUpdate( ) 메소드의 형식이다.- ResulteSet executeQuery(String sql)- int executeUpdate(String sql)둘다 SQL 문을 실행하는 것은 맞지만메소드 실행되는 것은 맞지만, 메소드가 실행된후 반환값이 다르다.executeUpdate() 메소드에서 반환하는 int 값이 바로 화면에 표시되는 숫자를 의미한다.즉 SQL 문 실행후 변경된 레코드의 개수이다.executeQuery( ) 메소드에서 반환하는 ResultSet은 select한 결과값을 가지고 있는 객체이다.따라서 select문은 executeQuery( ) 메소드를 사용하고, 나머지 명령뭉은 executeUpdate( )를 사용하면된다.ResultSet
executeQuery( ) 메소드에서 반환하는 ResultSet은 select한 결과값을 가지고 있는 객체이다.ResultSet rs = stmt.executeQuery("select * from test");위와 같은 SQL명령문을 실행 했을때 ResultSet 객체가 rs가 가지는 값은 다음과 같다.ResultSet 객체의 특징은 내부적으로 위치를 나타내느 커서라는 개념이 있다.또한 ResultSet 객체는 select 한 결과레코드가 있든 없든 항상 시작 빈행과 끝 빈행을 가진다.void afterLast( );void beforeFirst( );afterLast( )는 커서를 끝 빈행으로 위치시키며, beforeFirst( )는 커서를 시작 빈행으로 위치시키는 메소드이다.boolean next( );next( )는 커서 다음에 레코드가 있는지를 판단하여 없으면 false를 반환하고 , 있으며 true를 반환한 다음에 커서를 다음 레코드로 이동 시키는 메소드이다.String getString (int columnIndex)
String getString (String columLabel)
ResultSet 객체가 가지고 있는 getter 메소드들은 모두 칼럼의 값을 추출하는 메소드이다.
PreparedStatement 객체
preparedStatement 객체는 Statement 객체와 같은 기능을 수행하는 객체로서 , 연결된 DB 에 SQL 문을 실행한 후 결괏값을 가져오는 메소드를가지고 있다.Statement와 다른점은 PreparedStatement 객체는 실행할 SQL문을 ? 기호와 함깨 작성 할 수있다는 점이다.동적으로 값을 할당할때 ? 기호를 사용하면 가독성과 유지보수성이 좋다.두객체의 차이점을 설명하는 코드String id = request.getParameter("id");String pwd = request.getPrameter("pwd");/* Statement 사용시 */Statement stmt = conn.createStatement( );stmt.executeUpdate("insert into test values ('"+id+"','"+pwd+"')");/* PreparementStatement 사용*/PreparedStatement pstmt = conn.preparedStatement("insert into test values(?,?)");pstmt.setString(1,id);pstmt.setString(2,pwd);pstmt.executeUpdate();String id = request.getParameter("id");String pwd = request.getParameter("pwd");pstmt.executeUpdate();String id = request.getParameter("id");String pwd = request.getParameter("pwd");request.getParameter( ) 메소드는 클라이언트로부터 전송받은 파라미터값을 추출하는 메소드이다.
추출된 값을 변수 id와 pwd에 저장한다.
request 변수의 타입을 HttpServletRequest라고 가정한다.
Statement stmt =conn.createState( );
stmt.executeUpdate("insert into test values ('"+id+"','"+pwd+"')");
변수 id와 pwd에 저장된 test 테이블에 insert하기 위해 Statement stmt를 생성한 후 stmt.executeUpdate() 메소드를 사용하여 insert명령문을 실행한다.실행 되는 SQL 문을 보면 다음과 같다.stmt.executeUpdate("insert into test values ('"+id+"','"+pwd+"')");만약 id=cc , pwd=33 이 저장되어 있다면 다음과 같은 SQL문이 실행된다.insert into test values('cc' , 33)간단한 SQL 문이지만 ''(작은 따옴표)와 , (쉼표)를 일일이 챙겨야 한다. 그래서 오류가 발생할 확률도 높고 가독성도 좋지 않다.PreparedStatement pstmt = conn.preparedStatement("insert into test values(?,?)");
이 작업을 쉽게 할 수있도록 도와주는 객체가 PreparedStatement이다.
다음은 Connection 객체가 가지고 있는 PreparedStatement 객체를 생성하는 메소드이다.
PreparedStatement prepareStatement(String sql)
preparedStatement( ) 메소드를 통해 Preparedment 객체를 생성할때 인자값으로 실행할 SQL문을 지정하는데,
값을 동적으로 지정할때 ? 기호로 대체 할 수 있다.
"insert into test values(?,?)"
명령문은 test 테이블에 레코드를 삽입하는데, 값을 따로 지정하겠다는 의미로 ? 기호를 사용하고 있다.
미완성 SQL이라고 보면 된다.
pstmt.setString(1,id);
pstmt.setString(2.pwd);
pstmt는 PreparedStatement 객체로서 미완성인 SQL을 가지고 잇는 객체이다.
SQL문의 값을 따로 지정하기위해 ? 기호로 처리했기 때문이다.
? 자리에 값을 지정하기 위해 사용하는 메소드는
PreparedStatement 객체가 가지고 있는 setter 메소드를 활용한다.
추출하고자 하는 타입의 setter 메소드를 선택하여 사용한다.
setString(int parameterIndex, String x)
setTime(int parameterIndex, Time x)
pstmt.setString( )은 String 타입으로 값을 설정한다. 이떄 따로 ''(작은 따옴표)를 지정할 필요가 없다.
메소드 자체, 메소드 자체 내에서 데이터 타입을 처리하기 때문이다. PreaparedStatement 객체의 setter 메소드는
기본적으로 인자값이 두개이다.
첫번째 값을 ?의 위치이며 두번째 값은 설정하는 값이다.
pstmt.setString(1,id); //pstmt의 첫 번째 물음표에 id 변숫값을 문자열 타입으로 설정
pstmt.setString(2,pwd); //pstmt의 두 번째 물은표에 pwd 변숫값을 문자열 타입으로 설정
pstmt.executeUpdate( );
pstmt가 가지고 있는 SQL 문을 실행한다. pstmt 생성시 SQL 문을 지정했으므로 별도로 지정하지 않는다.
[5] 자원 해제
JDBC 프로그래밍을 하려면 JDBC 드링버를 로딩한 후 DB 서버와 접속하여 Connection 객체를 얻어야하며 ,다음에는 Connection에서 사용할 Statement 또는 PreparedStatement 객체를 생성하여 SQL문을 실행한다.SQL 문 실행 시 select 문이면 select 문이면 select 결과값을 갖는 ResultSet 객체를 반환 받아 사용해야한다.즉 다음과 같은 객체들을 사용한다.Connection : DB 연결 객체Statement 또는 Preparedment 객체 : SQL 문 실행 객체ResultSet 객체 : select 문 결과를 가지는 객체위와 같은 객체들이 DB관련 작업을 할 때 필요합니다.이 객체들을 이용하여 DB 관련 처리 작업이 완료된 다음에는 사용했던 객체들을 메모리를 해제 해주어야한다.메모리에서 해제하는 작업은 close를 활용한다.[6] 실습
JDBC.jsp 파일을 새로 생성하여 다음과 같이 구현한다. DB에 test 테이블을 생성하는 예제이다.123456789101112131415161718192021222324252627282930<%@page import="java.sql.Statement"%><%@page import="java.sql.Connection"%><%@page import="java.sql.DriverManager"%><%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="UTF-8"><title>Insert title here</title></head><body><%//1. JDBC Driver 로딩하기Class.forName("oracle.jdbc.driver.OracleDriver");//2. DB 서버 접속하기String url ="jdbc:oracle:thin:@localhost:1521:xe";Connection conn = DriverManager.getConnection(url,"scott","tiger");//3.Statement or PreparedStatement 객체 생성하기Statement stmt = conn.createStatement();//4. SQL 실행stmt.execute("create table test(id varchar2(5),pwd varchar2(5))");//5. 자원 해제stmt.close();conn.close();%></body></html>cs 한번 오류남WEB/INF -> lib 에 ojdbc 를 추가를 안해둠SQLplus에서 확인
1234567891011121314151617SQL*Plus: Release 11.2.0.2.0 Production on 화 3월 5 12:00:13 2019Copyright (c) 1982, 2014, Oracle. All rights reserved.Connected to:Oracle Database 11g Express Edition Release 11.2.0.2.0 - 64bit ProductionSQL> desc testName Null? Type----------------------------------------- -------- ----------------------------ID VARCHAR2(5)PWD VARCHAR2(5)SQL>cs 위코드를 테이블에 레코드를 삽입하는 예제
123456789101112131415161718192021222324252627282930313233<%@page import="java.sql.Statement"%><%@page import="java.sql.Connection"%><%@page import="java.sql.DriverManager"%><%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="UTF-8"><title>Insert title here</title></head><body><%//1. JDBC Driver 로딩하기Class.forName("oracle.jdbc.driver.OracleDriver");//2. DB 서버 접속하기String url ="jdbc:oracle:thin:@localhost:1521:xe";Connection conn = DriverManager.getConnection(url,"scott","tiger");//3.Statement or PreparedStatement 객체 생성하기Statement stmt = conn.createStatement();//4. SQL 실행//stmt.execute("create table test(id varchar2(5),pwd varchar2(5))");stmt.executeUpdate("insert into test values ('aa','11')");stmt.executeUpdate("insert into test values ('bb','22')");stmt.executeUpdate("insert into test values ('cc','33')");//5. 자원 해제stmt.close();conn.close();%></body></html>cs 12345678910SQL> select * from test2 ;ID PWD---------- ----------aa 11bb 22cc 33SQL>cs 테이블에 입력란 레코드들을 선택하여 화면에 출력하는 예제
1234567891011121314151617181920212223242526272829303132333435<%@page import="java.sql.ResultSet"%><%@page import="java.sql.Statement"%><%@page import="java.sql.Connection"%><%@page import="java.sql.DriverManager"%><%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="UTF-8"><title>Insert title here</title></head><body><%//1. JDBC Driver 로딩하기Class.forName("oracle.jdbc.driver.OracleDriver");//2. DB 서버 접속하기String url ="jdbc:oracle:thin:@localhost:1521:xe";Connection conn = DriverManager.getConnection(url,"scott","tiger");//3.Statement or PreparedStatement 객체 생성하기Statement stmt = conn.createStatement();//4. SQL 실행ResultSet rs = stmt.executeQuery("select * from test");while (rs.next()){out.print("<br>" +rs.getString("id")+":"+rs.getString(2));}//5. 자원 해제stmt.close();conn.close();%></body></html>cs 결과
aa:11
bb:22
cc:33실행시 전달된 파라미터 테이블에 PreparedState객체를 사용하여 삽입한다.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647<%@page import="java.sql.PreparedStatement"%><%@page import="java.sql.ResultSet"%><%@page import="java.sql.Statement"%><%@page import="java.sql.Connection"%><%@page import="java.sql.DriverManager"%><%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="UTF-8"><title>Insert title here</title></head><body><%//1. JDBC Driver 로딩하기Class.forName("oracle.jdbc.driver.OracleDriver");//2. DB 서버 접속하기String url ="jdbc:oracle:thin:@localhost:1521:xe";Connection conn = DriverManager.getConnection(url,"scott","tiger");//3.Statement or PreparedStatement 객체 생성하기Statement stmt = conn.createStatement();//4. SQL 실행String id = request.getParameter("id");String pwd = request.getParameter("pwd");PreparedStatement pstmt = conn.prepareStatement("insert into test values (?,?)");pstmt.setString(1, id);pstmt.setString(2, pwd);pstmt.execute();ResultSet rs = stmt.executeQuery("select * from test");while (rs.next()){out.print("<br>" +rs.getString("id")+":"+rs.getString(2));}//5. 자원 해제pstmt.close();stmt.close();conn.close();%></body></html>cs http://localhost:8081/edu/JDBC.jsp?id=ee&pwd=55
로 요청하면
결과
aa:11
bb:22
cc:33
dd:44
ee:55DataSource
클라이언트 요청이 있을때 마다 DB 서버에 연결은 시도한다는것은
많은 위험을 감수 해야한다. (속도, 예외 발생)
이러한 문제점을 해결하기 위한 기술로서 웹 클라이언트 요청이 들어올때 마다 DB서버와 연결하는 것이 아니라.
미리 서버에서 연결한 후 활용하는 방법이 있다.
개요
Connection관리
DB작업을 하려면 반드시 DB 서버와 연결하여 Connection 객체를 얻어내야 한다. 그런데 우리가 개발하고자 하는 프로그램은 웹 프로그램이다.웹프로그램은 동시에 여러 사용자에 의해 요청이 일어날 수있는 특성이 있으므로 자원 분배와 응답속도에 대하여효율적으로 구현해야한다그런데 웹 클라이언트로 부터 요청이 있을 때마다 Connection을 얻기 위한 작업을 할 때는 다음과 같은 문제점이 있다.- DB 프로그램에서 트랜잭션 처리와 Connection 관리는 시스템의 성능과 안정성에 큰 영향을 미친다.- Connection과정은 일정시간이 필요한 부담되는 작업이다.- 불필요한 연결에 의한 서버 자원의 낭비를 발생한다.위 문제를 해결하기 위해 나온것이 Connection Pool
Connection Pool
커넥션 풀 개념은 Connection 객체를 프로그램이 실행될 때마다 생성하는 것이 아니라 .웹 애플리케이션이 서비스 되기 전에 웹서버에서 미리 생성하여 준비한다음준비된 COnnection 을 가져다 사용함으로 써 JDBC 프로그래밍의 문제점들을 개선한 기술이다.Connection 객체는 서버가 시작할 때 서버에서 여러개를 준비할 수 있다.이렇게 준비된 Connection 객체들을 가지고 있는 리소스들을 Connection Pool이라고 한다.[3] DataSource
커넥션 풀에는 여러개의 커넥션 객체가 생성되어 운용되는데 각각을 직접 웹 애플리케이션에서 이용하면체계적인 관리가 힘들게 되므로 DataSource라는 개념을 도입하여 사용하고 있다.DataSource라는 객체는 Connection Pool을 관리하는 목적으로 사용되는 객체로 웹 애플리케이션이 DataSource 객체를 통해서 Connection을 얻어오고 반납하는 등의 작업을 수행할 수 있다.결국 웹 애플리케이션에서 DataSource 객체를 얻음으로써 Connection Pool을 이용하게되는데.이 DataSource 객체는 JNDI Server에 의해 웹 애플리케이션에 전달하는 방식을 따르고 있다.DataSource를 이용하지 않는 기존의 방식(DriverManager를 이용하는 방식)은 내부적으로 static 한 필드를사용하기 때문에 스레드 환경에서 바람직하지 않다.따라서 될 수 있으면 DataSource를 이용하여 Connection을 관리하는 것이 좋다.DataSource 객체에 대해 정리한 내용- Connection Pool의 Connection을 관리하기 위한 객체이다.- JNDI Server를 통해서 이용된다.- DataSource 객체를 통해서 필요한 Connection을 획득, 반납등의 작업을 한다.DataSource 이용방법
DataSource를 이용하려면 다음과 같은 절차를 거처야한다.1. JNDI server 에서 lookup() 메소드를 통해 DataSource 객체를 획득한다.2. DataSource 객체의 getConnection( ) 메소드를 통해서 Connection Pool에서 Free 상태의 Connection을 획득한다.3. Connection 객체를 통한 DBMS 작업을 수행한다.4. 모든 작업이 끝나면 DataSource 객체를 통해서 Connection Pool에 Connection 을 반납한다.[4]JNDI
JNDI(Java Naming and Directory Interface) 는 API와 SPI 로 이루어져 있으며, API는 애플리케이션에서 네이밍 혹은 디렉터리 서비스에접근하는데 사용하며 , SPI는 새로운 서비스를 개발할 때 사용된다.Naming & Directory 서비스
웹 애플리케이션은 전체 J2EE 일부분을 구성 기술이며이 J2EE는 분산 환경 기술이다.분산환경은 네트워크로 연결된 수많은 컴퓨터에 분산된 여러 자원이 하나의 시스템으로 구성되며, 네트워크상에서 어떤 하나의 애플리케이션이 필요한 자원을 찾고 획득하는 일은 가장 중요한 일중 하나이다.이렇게 분산 컴퓨팅과 엔터프라이즈 컴퓨팅 환경에서의 자원획득과 이용의 효율성을 위해 제공하는 서비스가Naming & Directory 이다.Naming& Directory 서비스는 실제 어떤 자원을 가지고 서비스 한다는 의미가 아니라.어떤 서버나 애플리케이션에서 분산환경에 서비스하고자 하는 자원을 이Naming & Directory 서버에 이름값과 실제 자원을 연결하여 등록하면,해당 자원을 이용하고자 하는 다른 애플리케이션에서 Naming & Directory 서버에 접근하여 이름값만을 가지고자원을 연결하여 이용할수 있게 하는 개념이다.흔히 DNS 서버가 이런기능을 해주는데우리가 입력한 URL은 DNS 서버를 거치면서 입력한 도메인에 해당하는 IP주소를 얻고그 IP주소로 우리는 접속하게 된다.결국 DNS 서버는 실제 인터넷 서비스를 수행 해주는 곳이 아니며단지 도메인과 IP 주소만을 연결 해주는 기능을 하는 것이다.Naming & Directory 서버 또한 분산 환경에서 자원을 연결해주는 기능을 수행한다.구현
DataSource를 사용하기 위한 설정작업(1)Server.xml 설정
ConnectionPool은 서버에서 관리하는 자원 그래서 서버 환경설정파일인 server.xml 에 ConnectionPool에 관한 설정을 한다.설정한 내용에 따라 서버가 시작하면서 리소스 준비작업이 이루어진다.WAS_HOME/conf/server.xml 파일을 편집한다.이클립스에서 다음에 위치한 파일이 동일한 파일이다.123456789101112<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"/><Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/></GlobalNamingResources>cs <resource> 태그의 속성에 대한 설명은 다음과 같다.- driverClassName : DB 작업을 위해 로딩할 JDBC 드라이버파일에 드라이버 인터페이스를 상속하는 파일명 전체이름으로 지정한다.Class.forName() 메소드의 인자값이다.- url : 접속할 DB 서버의 URL을 지정한다.- username : DB 서버에 로그인할 계정을 지정한다.- password : DB 서버에 로그인할 계정의 비밀번호를 지정한다.- name : 현재 리소스를 등록할 이름을 지정한다.- type : 리소스 타입을 지정한다. Connection Pool을 사용할 수 있도록 해주는 객체의 타입은 javax.sql.DataSource이다.- maxActive : 생성할 커넥션의 수를 지정한다.- maxIdle : 일반적으로 활용할 Connection 수를 지정한다.- maxWait : Connection의 사용 요청이 있을떄 대기 시간을 지정합니다. 5000sms 5초 5초이후에 Connection을 얻지 못하면 Exception 이 발생한다.context.xml파일에 다음과 같이 설정 내용을 추가한다.1<ResourceLink global="jdbc/myoracle" name ="jdbc/myoracle" type="javax.sql.DataSource"/>cs 서버에 등록된 리소스를 웹 애플리케이션에서 찾아서 사용할 수 있도록 글로벌한 이름을 지정한다.서버에서의 설정은 server.xml 에 Connection 을 만들기 위해 정보를 설정한 수 contest.xml 파일에Connection Pool 의 이름을 등록함으로써 완료되었다.(2)web.xml 설정
서버에서 관리하는 리소스를 웹 애플리케이션에서 사용하기 위하여 /WEB-INF/web.xml 파일에 사용할 리소스에 대한 정보를 다음과 같이지정한다.123456<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>cs description : 리소스에 대한 설명res-ref-name : 사용하고자 하는 리소스의 이름을 지정한다.res-type : 사용하고자 하는 리소스의 타입을 지정한다.res-auth : 리소스에 대한 권한이 누구인지 지정한다.실제 DB작업123456789101112131415161718192021222324252627282930313233343536<%@page import="java.sql.ResultSet"%><%@page import="java.sql.Statement"%><%@page import="javax.sql.DataSource"%><%@page import="java.sql.Connection"%><%@page import="javax.naming.InitialContext"%><%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="UTF-8"><title>Insert title here</title></head><body><%//1. JDNI 서버 객체 생성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("<br>"+rs.getString("id")+":"+rs.getString(2));}rs.close();stmt.close();conn.close();%></body></html>cs //1. JDNI 서버 객체 생성
InitialContext ic = new InitialContext();
Connection Pool에 접근하려면 JNDI 서비스를 사용해야한다. JDNI는 서버에서 관리하고 있는 리소스에대한 정보를 알고
특정 리소스를 찾아서 사용할 수있도록 객체를 반환해주는 역할을 합니다.
리소스가 로컬에 있을때는 단순히 initialContext 객체만 생성하면 된다.
//2. lookup()
DataSource ds = (DataSource)ic.lookup("java:comp/env/jdbc/myoracle");
ic.lookup() 은 리소스를 찾은 후 리소스를 사용할 수있도록 객체를 반환해주는 메소드이다.
리소스의 등록된 이름을 지정해야한다.
아까 등록한 "jdbc/myoracle"이다.
lookup("jdbc/myoracle")으로 해야하는데 lookup("java:comp/env/jdbc/myoracle")을 지정했다.
이것은 WAS로 톰캣을 이용하기 때문이다
톰캣에서는 리소스를 관리하는 가상의 디렉터리가 있는데 경로가 java:comp/env 이다.
톰켓을 사용할때만 붙여준다.
lookup() 은 반환 타입이 오브젝트 타입이기때문에 형변환이 필요함
결과
aa:11
bb:22
cc:33
dd:44
ee:55'Servlet' 카테고리의 다른 글
EL(Expression Language) (0) 2019.03.06 데이터베이스요약 (0) 2019.03.06 표준 액션 태그와 JSP 자바빈즈 요약 (0) 2019.03.04 표준 액션태그와 JSP 자바빈즈 (0) 2019.03.04 내장객체 요약 (0) 2019.03.04