[JDBC] Connection
Connection 객체는 데이터베이스와의 연결(connection)을 담당한다.
연결 부분은 실행될 SQL문, 그리고 연결을 통해서 리턴되어지는 결과들을 포함한다.
어플리케이션은 한개의 데이터베이스와 하나 이상의 연결을 할수 있거나 또는 많은 서로다른 데이터베이스에 연결할 수도 있다.
2.1.1 Connection 열기
데이터베이스와 연결하는 기본 방법은 URL을 포함하는 스트링을 매개변수로 가지고 있는 DriverManager.getConnection 메쏘드를 사용하는 것이다.
JDBC 관리층으로 간주되는 DriverManager 클래스는 지정된 URL에 연결한다기보다는 드라이버를 알아내려고 한다.
DriverManager 클래스는 등록된 Driver 클래스들의 리스트를 보존한다.
그리고 getConnection 메쏘드가 호출되어질때, URL내의 지정된 데이터베이스에 접속할 수 있는 드라이버를 발견할때까지
리스트에 있는 각 드라이버들을 검사한다.
Driver 클래스의 connect 메쏘드는 이 URL을 실제적으로 접속하는데 사용한다.
사용자는 DriverManager를 사용하지 않고 직접 Driver 메쏘드들을 호출할 수 있다.
이것은 두 개의 드라이버들이 하나의 데이터베이스와 접속할 수 있고 사용자가 명백하게 특정 드라이버를 선택하고자 하는 드문 경우에 유요할 수 있다.
그러나 보통은 DriverManager 클래스가 연결을 오픈하도록 처리하는 것이 더 쉽다.
아래 코드는 "jdbc:msql://ch69.misotech.com:1433/Test"의 URL에 있는 데이터베이스와 "test"라는 사용자계정과 "java"라는 패스워드를 가지고 연결하는 예이다.:
String url = "jdbc:msql://ch69.misotech.com:1433/Test";
Connection con = DriveManager.getConnection(url, "test", "java");
2.1.2 일반적인 사용의 URL들
먼저 일반적인 URL들에 대해 간단한 설명을 하고 계속해서 JDBC URL들에 대해 알아보자.
URL(Uniform Resource Locator)은 인터넷 상의 리소스들을 위치를 알아내기 위한 정보를 준다.
주소라고 생각할 수도 있다. 일반적인 사용에서 URL은 세부분으로 구성된다.:
정보에 접근하기 위해 사용되는 프로토콜. 콜론이 항상 프로토콜 뒤에 온다.
일반적인 프로토콜은 "파일 전송 프로토콜"인 ftp, "하이퍼텍스트 전송 프로토콜"인 http 등이 있다.
만약 프로토콜의 file 이라면, 리소스는 인터넷상이 아닌 로컬 파일 시스템에 있다는 것을 가리킨다.
ftp://javasoft.com/docs/JDK-1_apidocs.zip
http://java.sun.com/products/JDK/1.1
file:/home/jdk1.1/docs/tutorial.html
호스트 정보. 이 부분은 리소스가 존재하는 호스트를 찾거나 접근하기 위해서 필요한 정보를 준다.
호스트 정보는 ftp나 http와 같은 인터넷 어플리케이션이면 더블 슬래시("//")로, 아니면 싱글 슬래시("/")로 시작한다.
호스트 정보는 싱글 슬래스로 끝난다. 호스트 정보는 자체로는 세부분으로 분리된다.
리소스가 인터넷 상에 존재하면 호스트 도메인 이름.; 리소스가 로컬 파일이면 호스트 이름대신 파일의 경로가 있다.
사용자 로그인 이름과 패스워드. 필요로 하는 경우 포함된다.
포트번호. 필요로 하는 경우 포함되며, 호스트 이름과 콜론 다음에 온다.
가장 평범한 경우는 더블 슬래시와 호스트 이름만을 가진다.:
http://java.sun.com
다음은 포트번호 80을 포함하는 URL이다.:
http://java.sun.com:80/doc/tutorual.html
다음은 호스트이름의 부분으로 로긴 이름 "happy"와 패스워드 "1234"를 가진 URL의 예이다.
http://netsmile.grin.com."happy"."1234"/news/latest
접근되어질 것의 경로. 다음의 예제에서 info와 java는 디렉토리들이고 index.html은 파일이다.
http://www.misotech.com/info/java/index.html
2.1.3 JDBC URL들
JDBC URL은 드라이버가 데이터베이스를 인식하고 그것과 연결하기위해 데이터베이스를 확인하는 방법을 제공한다.
드라이버는 오직 하나의 URL 명명법만을 이해하며 다른 URL들은 무시한다.
JDBC URL의 형식은 드라이버 제작자에 의해 결정된다.
첫 번째 부분은 항상 jdbc가 된다. 두 번째 부분은 드라이버 제작자가 제공하는 서브 프로토콜일 것이다. JDBC URL의 나머지 부분은 데이터소스이다. 사용자 로그인 네임과 패스워드와 같은 데이터 소스에 접근할 때 필요한 정보를 제공한다. JDBC의 역할은 단지 드라이버 제작자들이 구조화된 JDBC URL들을 사용하도록 몇가지의 약속들을 제시하는 것이다.
JDBC URL들을 다양한 종류의 드라이버에서 사용하기 때문에, 약정은 필연적으로 매우 탄력적일 것이다.
첫째로, 데이터베이스의 명시를 위해서 드라이버마다 서로 다른 스킴(scheme)을 사용하도록 한다.
예를 들어 odbc 서브 프로토콜은 URL에 서브네임 다음에 속성값을 포함해도록 해준다.
두 번째로, JDBC URL들은 드라이버 제작자가 URL내의 모든 필요한 정보를 인코드할 수 있도록 한다.
예를 들어, 사용자는 어떠한 시스템관리 작업없이 주어진 데이터베이스와 통신하는 애플릿을 데이터베이스와 연결하는 것이 가능한다.
세 번째로, JDBC URL들은 간접레벨을 허용한다. 즉, JDBC URL은 동적으로 네트워크 네이밍 시스템(Network Naming System)에 의해서 실제 이름으로 변환되어지는 로컬 호스트나 데이터베이스 이름을 참고한다.
이것은 시스템 어드민들이 JDBC 이름의 한부분으로 특정 호스트를 지정하는 것을 피하게 해준다.
많은 DNS, NIS, DCE와 같은 네임 서비스들이 있으며 어떤 것을 사용해도 무방하다.
JDBC URL들에서 필요한 많은 모양들을 표준 URL 명명 메카니즘이 이미 제공하기 때문에, JDBC URL 규정에 단지 하나의 문법을 추가하면 된다. JDBC URL을 위한 표준 문법은 다음과 같다.:
jdbc::
JDBC URL은 세부분을 가지며, 콜론으로 구분된다.:
jdbc는 프로토콜이다. JDBC URL에서의 프로토콜은 항상 jdbc이다.
은 보통 드라이버나 데이터베이스 접속 메카니즘이며 이것은 하나 이상의 드라이버들에 의해 지원되어질 것이다. 잘알려진 서브 프로토콜 이름의 예는 odbc이며, 이것은 ODBC 스타일의 데이터 소스 이름들을 나타내는 URL들을 위해 지정되어진다. 예를 들어, JDBC-ODBC 브리지를 통해 데이터베이스에 접근하기 위해서는 다음과 같은 URL을 사용해야 할 것이다. :
jdbc:odbc:fred
이 예제에서, 서브프로토콜은 odbc이고, 서브네임 fred는 로컬 ODBC 데이터 소스이다.
은 데이터베이스를 확인하는 방법이다. 서브네임은 서브 프로토콜에 좌우되어 변경되고 드라이버 제작자가 선택한 어떠한 내부 문법에 의해 서브서브네임을 가질 수 있다. 서브네임의 요점은 데이터베이스의 위치를 알기 위한 충분한 정보를 주는 것이다. 이전 예제에서, fred는 ODBC가 정보의 나머지를 제공하기 때문에 충분하다. 그러나, 리모트 서버상의 데이터베이스는 더많은 정보를 요구한다. 예를들어, 만약 데이터베이스가 인터넷에 의해서 접근되어진다면, 네트워크 주소가 서브네임의 부분으로서 JDBC URL에 포함되어져야 하고 표준 URL 표기법 "//hostname:port/sub_subname"을 따라야한다. msql이 인터넷상의 호스트에 접속하기위한 프로토콜이라고 가정하면, JDBC URL은 아래와 같은 모양일 것이다. :
jdbc:msql://ch69.misotech.com:1114/Test
2.1.4 "odbc" 서브프로토콜
서브 프로토콜 odbc는 특별한 경우이다. 이것은 ODBC 스타일의 데이터소스 이름을 나타내는 URL을 위한 것이고 서브네임(데이터소스네임) 다음에 지정될 수 있는 속성값들을 허용하는 모양을 가지고 있다. odbc 서브프로토콜을 위한 완전한 문법은 다음과 같다.:
jdbc:odbc:[;=]*
그러므로 다음은 유효한 jdbc:odbc 이름들이다.:
jdbc:odbc:qeor7
jdbc:odbc:wombat
jdbc:odbc:wombat;CacheSize=20;ExtensionCase=LOWER
jdbc:odbc:qeora;UID=kgh;PWD=fooey
2.1.5 서브프로토콜들을 등록하기
드라이버 개발자는 JDBC URL에서 서브 프로토콜로써 사용될 수 있는 이름을 지정할 수 있다.
DriverManager 클래스가 등록된 드라이버들의 리스트로 이 이름을 보낼 때에, 이 이름이 지정되어있는 드라이버는 그것을 승인하고 확인된 데이터베이스에 연결한다.
예를 들어 odbc는 JDBC-OBDC 브리지를 위해 지정된 서브프로토콜이다.
또다른 예제로, 만약 Miracle Corportion이 있다면, Miracle DBMS들에 연결하는 JDBC 드라이버를 위한 서브 프로토콜로써
"miracle"을 등록하여 다른 사람들이 사용하지 않도록 하고 싶어할 것이다.
JavaSoft는 JDBC 서브 프로토콜 이름들을 위한 비공식적인 등록절차를 대행하고 있다.
서브 프로토콜 이름을 등록하기 위해서는 email을 아래의 주소로 보내라.
jdbc@wombat.eng.sun.com
2.1.6 SQL문들을 전송하기
일단 연결이 되면, 데이터베이스에 SQL문을 전송하는데 사용되어진다.
JDBC는 전송될 수 있는 SQL문의 종류에 제한을 두지 않는다.
이것은 데이터베이스-특정 SQL문, 심지어 non-SQL 문들의 사용을 허용하는 대단한 융통성을 제공한다.
그러나, 사용자는 데이터베이스가 전송되어지는 SQL문을 처리할수 있고 결과를 허용할 수 있는지를 확인해야한다.
예를 들어, 저장 프로시져를 지원하지 않는 DBMS로 저장프로시져 호출을 보내는 어플리케이션은 실행되지 않고 예외상황을 발생할 것이다.
JDBC는 드라이버가 JDBC COMPLIANT로 지명되어지기 위해서 적어도 ANSI SQL-2 Entry Level 능력들을 제공할 것을 요구한다.
이것은 사용자가 적어도 이러한 기능의 표준 레벨에 의지할 수 있음을 의미한다.
JDBC는 SQL문들을 데이터베이스로 전송하기 위해 세가지 클래스를 제공하며, Connection 인터페이스에 있는 세가지 메쏘드들을 가지고 이러한 클래스들의 인스턴스를 생성한다.
세가지 클래스와 Connection 인터페이스에 있는 메쏘드는 다음과 같다.:
Statement - createStatement 메쏘드에 의해 생성된다. Statement 객체는 간단한 SQL 문들을 전송하는데 사용된다.
PreparedStatement - prepareStatement 메쏘드에 의해 생성된다.
PreparedStatement 객체는 하나이상의 입력 인자를 매개변수(IN 매개변수)로 가지는 SQL문을 위해 사용되어진다.
PreparedStatement는 IN 매개변수의 값을 설정하는 메쏘드들을 가지며, 이것들은 SQL문이 실행되어질 때 데이터베이스로 전송된다.
PreparedStatement의 인스턴스는 Statement를 상속하기 때문에 Statement 메쏘드들을 포함한다.
PreparedStatement 객체는 미리 컴파일되고 이후의 사용의 위해 저장되기 때문에 Statement 객체보다 더욱 효과적이 될 수 있는 잠재력을 가진다.
CallableStatement - prepareCall 메쏘드에 의해 생성된다.
CallableStatement객체는 SQL 저장 프로시져들-함수를 호출하는 것처럼 이름에 의해 호출되어지는(call by name) SQL문의 그룹-을 실행하는데 사용된다.
CallableStatement 객체는 PreparedStatement로부터 IN 매개변수를 처리하기 위한 메쏘드를 상속받고 OUT과 INOUT 매개변수를 처리하기 위한 메쏘드를 추가한다.
다음은 다른 형태의 SQL문들을 생성하는데 어떠한 Connection 메쏘드가 적당한가를 결정하기 위한 방법을 제공한다.
createStatement 메쏘드는 다음을 위해 사용되어진다.
간단한 SQL문들(매개변수 없음)
prepareStetement 메쏘드는 다음을 위해 사용되어진다.
하나 이상의 IN 매개변수들을 가지는 SQL문들
자주 실행되어질 간단한 SQL문들
prepareCall 메쏘드는 다음을 위해 사용된다.
저장 프로시져들의 호출
2.1.7 트랜젝션들
트랜젝션은 실행되고 완결된 다음 회부되거나 되돌아오는 하나 이상의 SQL문으로 구성된다.
commit 나 rollback 메쏘드가 호출될때, 현재 트랜젝션이 끝나고 다른 것이 시작된다.
새로운 연결은 디폴트로 auto-commit 모드이다.
이것은 SQL문이 완결될때에, commit 메쏘드가 그 SQL문을 자동적으로 요청하게 됨을 의미한다.
이러한 경우에 각 SQL문을 개별적으로 회부되어지기 때문에, 트랙젝션을 오직 하나의 SQL문으로 구성된다.
만약 auto-commit 모드가 비활성화 된다면, 트랙젝션은 commit나 rollback 메쏘드가 명백하게 호출되기 전까지는 종료되지 않는다.
따라서 트랜젝션은 commit나 rollback 메쏘드의 마지막 호출 이후에 실행되어지는 모든 SQL문을 포함할 것이다.
이러한 두 번째 경우에서, 트랙젝션에 있는 모든 SQL문들은 그룹으로써 회부되거나 되돌아온다.
commit 메쏘드는 SQL문이 데이터베이스에 만드는 변화를 영구적으로 만들고, 또한 트랜젝션에 의한 어떠한 락들도 풀어놓는다.
rollback 메쏘드는 변화들을 취소할 것이다.
때때로 사용자는 다른 하나가 원하지 않는다면 효과를 가지는 변화를 원하지 않을 것이다.
이것은 auto-commit를 비활성화 시키고 갱신된 두 개를 하나의 트랜젝션으로 그룹지음으로써 완성할 수 있다.
만약 두 개의 갱신이 모두 성공했다면 효과를 영구히 하기위해서 commint 메쏘드가 호출되고, 하나가 실패하거나 두 개 모두 실패하면 갱신이 실행되기 전에 있던 값을 다시 저장하기 위해서 rollback 메쏘드가 호출된다.
대부분의 JDBC 드라이버들은 트랙젝션을 지원한다.
사실상 JDBC-COMPLIANT 드라이버들은 트랜젝션을 지원해야한다.
DatabaseMetaData는 DBMS가 제공하는 트랜젝션 지원 레벨을 설명하는 정보를 준다.
2.1.8 트랜젝션 분리 레벨들
만약 DBMS가 트랜젝션 처리를 지원한다면, 동시에 하나의 데이터베이스에서 두 개의 트랜젝션이 동작할 때 일어날 수 있는 잠재적인 충돌을 관리하는 방법을 가지고 있을 것이다.
사용자는 잠재적인 충돌들을 해결하는데 DBMS가 어떠한 보호 레벨을 사용할 수 있는가를 나타내는 트랜젝션 분리 레벨을 지정할 수 있다.
예를 들어, 한 트랜젝션이 값을 바꾸고 변화가 확정되거나 취소되기전에 두 번째 트랜젝션이 그 값을 읽을 때 무엇이 발생하는가?
허용이 된다면, 첫 번째 트랜젝션이 취소될때에 두 번째 트랜젝션에 의해 읽어진 변화된 값이 유효하지 않게 되는가?
JDBC 사용자는 변화가 영구히 되기전에 값을 읽을수 있도록 다음의 코드를 가지고 DBMS에게 명령할 수 있다.
여기서 con은 현재의 연결이다.:
con.setTransactionIsolation(TRANSACTION_READ_UNCOMMITTED);
트랙젝션 분리 레벨이 높으면 높을수록, 충돌을 피하기위해서 더욱 주의를 해야한다.
Connection 인터페이스는 트랜젝션이 전혀 지원되지 않는 것을 가장 낮게 그리고 하나의 트랜젝션이 데이터베이스상에서 동작중에 있는동안
다른 트랜젝션들이 그 트랜젝션에 의해 읽혀진 데이터에 어떠한 변화도 만들지 않는 것을 가장 높게 하여 5개의 레벨을 정의한다.
전형적으로 분리 레벨이 높으면 높을수록 어플리케이션의 속도는 더욱 느려진다.
(왜냐하면 락 오버헤드가 증가하고 사용자들 사이에 동시발생이 감소하기 때문이다.)
개발자는 어떤 분리 레벨을 사용할 것인가에 대해 결정할 때 성능을 위한 요구와 데이터 일관성을 위한 요구를 비교 평가해야만 한다.
물론 실제적으로 지원될 수 있는 레벨은 사용하는 DBMS의 능력에 좌우된다.
새로운 Connection 객체를 생성할때에 트랜젝션 분리 레벨은 드라이버에 의존하지만 보통 데이터베이스에 디폴트이다.
사용자는 트랜젝션 분리 레벨을 변경하기 위해서 setIsolationLevel 메쏘드를 호출할 것이고 새로운 레벨은 사실상 연결 부분의 나머지가 될 것이다.
단지 하나의 트랜젝션을 위해 트랜젝션 분리 레벨을 바꾸는 경우에는 트랜젝션이 시작하기 전에 설정하고 트랜젝션이 종료된 후에는 재설정한다.
트랜젝션 도중에 분리레벨을 변경하는 것을 바람직하지 않다.
왜냐하면 이것은 commit 메쏘드를 즉시 호출을 하여 그 시점까지의 어떠한 변화들을 영구적으로 만들기 때문이다.
연결 부분은 실행될 SQL문, 그리고 연결을 통해서 리턴되어지는 결과들을 포함한다.
어플리케이션은 한개의 데이터베이스와 하나 이상의 연결을 할수 있거나 또는 많은 서로다른 데이터베이스에 연결할 수도 있다.
2.1.1 Connection 열기
데이터베이스와 연결하는 기본 방법은 URL을 포함하는 스트링을 매개변수로 가지고 있는 DriverManager.getConnection 메쏘드를 사용하는 것이다.
JDBC 관리층으로 간주되는 DriverManager 클래스는 지정된 URL에 연결한다기보다는 드라이버를 알아내려고 한다.
DriverManager 클래스는 등록된 Driver 클래스들의 리스트를 보존한다.
그리고 getConnection 메쏘드가 호출되어질때, URL내의 지정된 데이터베이스에 접속할 수 있는 드라이버를 발견할때까지
리스트에 있는 각 드라이버들을 검사한다.
Driver 클래스의 connect 메쏘드는 이 URL을 실제적으로 접속하는데 사용한다.
사용자는 DriverManager를 사용하지 않고 직접 Driver 메쏘드들을 호출할 수 있다.
이것은 두 개의 드라이버들이 하나의 데이터베이스와 접속할 수 있고 사용자가 명백하게 특정 드라이버를 선택하고자 하는 드문 경우에 유요할 수 있다.
그러나 보통은 DriverManager 클래스가 연결을 오픈하도록 처리하는 것이 더 쉽다.
아래 코드는 "jdbc:msql://ch69.misotech.com:1433/Test"의 URL에 있는 데이터베이스와 "test"라는 사용자계정과 "java"라는 패스워드를 가지고 연결하는 예이다.:
String url = "jdbc:msql://ch69.misotech.com:1433/Test";
Connection con = DriveManager.getConnection(url, "test", "java");
2.1.2 일반적인 사용의 URL들
먼저 일반적인 URL들에 대해 간단한 설명을 하고 계속해서 JDBC URL들에 대해 알아보자.
URL(Uniform Resource Locator)은 인터넷 상의 리소스들을 위치를 알아내기 위한 정보를 준다.
주소라고 생각할 수도 있다. 일반적인 사용에서 URL은 세부분으로 구성된다.:
정보에 접근하기 위해 사용되는 프로토콜. 콜론이 항상 프로토콜 뒤에 온다.
일반적인 프로토콜은 "파일 전송 프로토콜"인 ftp, "하이퍼텍스트 전송 프로토콜"인 http 등이 있다.
만약 프로토콜의 file 이라면, 리소스는 인터넷상이 아닌 로컬 파일 시스템에 있다는 것을 가리킨다.
ftp://javasoft.com/docs/JDK-1_apidocs.zip
http://java.sun.com/products/JDK/1.1
file:/home/jdk1.1/docs/tutorial.html
호스트 정보. 이 부분은 리소스가 존재하는 호스트를 찾거나 접근하기 위해서 필요한 정보를 준다.
호스트 정보는 ftp나 http와 같은 인터넷 어플리케이션이면 더블 슬래시("//")로, 아니면 싱글 슬래시("/")로 시작한다.
호스트 정보는 싱글 슬래스로 끝난다. 호스트 정보는 자체로는 세부분으로 분리된다.
리소스가 인터넷 상에 존재하면 호스트 도메인 이름.; 리소스가 로컬 파일이면 호스트 이름대신 파일의 경로가 있다.
사용자 로그인 이름과 패스워드. 필요로 하는 경우 포함된다.
포트번호. 필요로 하는 경우 포함되며, 호스트 이름과 콜론 다음에 온다.
가장 평범한 경우는 더블 슬래시와 호스트 이름만을 가진다.:
http://java.sun.com
다음은 포트번호 80을 포함하는 URL이다.:
http://java.sun.com:80/doc/tutorual.html
다음은 호스트이름의 부분으로 로긴 이름 "happy"와 패스워드 "1234"를 가진 URL의 예이다.
http://netsmile.grin.com."happy"."1234"/news/latest
접근되어질 것의 경로. 다음의 예제에서 info와 java는 디렉토리들이고 index.html은 파일이다.
http://www.misotech.com/info/java/index.html
2.1.3 JDBC URL들
JDBC URL은 드라이버가 데이터베이스를 인식하고 그것과 연결하기위해 데이터베이스를 확인하는 방법을 제공한다.
드라이버는 오직 하나의 URL 명명법만을 이해하며 다른 URL들은 무시한다.
JDBC URL의 형식은 드라이버 제작자에 의해 결정된다.
첫 번째 부분은 항상 jdbc가 된다. 두 번째 부분은 드라이버 제작자가 제공하는 서브 프로토콜일 것이다. JDBC URL의 나머지 부분은 데이터소스이다. 사용자 로그인 네임과 패스워드와 같은 데이터 소스에 접근할 때 필요한 정보를 제공한다. JDBC의 역할은 단지 드라이버 제작자들이 구조화된 JDBC URL들을 사용하도록 몇가지의 약속들을 제시하는 것이다.
JDBC URL들을 다양한 종류의 드라이버에서 사용하기 때문에, 약정은 필연적으로 매우 탄력적일 것이다.
첫째로, 데이터베이스의 명시를 위해서 드라이버마다 서로 다른 스킴(scheme)을 사용하도록 한다.
예를 들어 odbc 서브 프로토콜은 URL에 서브네임 다음에 속성값을 포함해도록 해준다.
두 번째로, JDBC URL들은 드라이버 제작자가 URL내의 모든 필요한 정보를 인코드할 수 있도록 한다.
예를 들어, 사용자는 어떠한 시스템관리 작업없이 주어진 데이터베이스와 통신하는 애플릿을 데이터베이스와 연결하는 것이 가능한다.
세 번째로, JDBC URL들은 간접레벨을 허용한다. 즉, JDBC URL은 동적으로 네트워크 네이밍 시스템(Network Naming System)에 의해서 실제 이름으로 변환되어지는 로컬 호스트나 데이터베이스 이름을 참고한다.
이것은 시스템 어드민들이 JDBC 이름의 한부분으로 특정 호스트를 지정하는 것을 피하게 해준다.
많은 DNS, NIS, DCE와 같은 네임 서비스들이 있으며 어떤 것을 사용해도 무방하다.
JDBC URL들에서 필요한 많은 모양들을 표준 URL 명명 메카니즘이 이미 제공하기 때문에, JDBC URL 규정에 단지 하나의 문법을 추가하면 된다. JDBC URL을 위한 표준 문법은 다음과 같다.:
jdbc:
JDBC URL은 세부분을 가지며, 콜론으로 구분된다.:
jdbc는 프로토콜이다. JDBC URL에서의 프로토콜은 항상 jdbc이다.
jdbc:odbc:fred
이 예제에서, 서브프로토콜은 odbc이고, 서브네임 fred는 로컬 ODBC 데이터 소스이다.
jdbc:msql://ch69.misotech.com:1114/Test
2.1.4 "odbc" 서브프로토콜
서브 프로토콜 odbc는 특별한 경우이다. 이것은 ODBC 스타일의 데이터소스 이름을 나타내는 URL을 위한 것이고 서브네임(데이터소스네임) 다음에 지정될 수 있는 속성값들을 허용하는 모양을 가지고 있다. odbc 서브프로토콜을 위한 완전한 문법은 다음과 같다.:
jdbc:odbc:
그러므로 다음은 유효한 jdbc:odbc 이름들이다.:
jdbc:odbc:qeor7
jdbc:odbc:wombat
jdbc:odbc:wombat;CacheSize=20;ExtensionCase=LOWER
jdbc:odbc:qeora;UID=kgh;PWD=fooey
2.1.5 서브프로토콜들을 등록하기
드라이버 개발자는 JDBC URL에서 서브 프로토콜로써 사용될 수 있는 이름을 지정할 수 있다.
DriverManager 클래스가 등록된 드라이버들의 리스트로 이 이름을 보낼 때에, 이 이름이 지정되어있는 드라이버는 그것을 승인하고 확인된 데이터베이스에 연결한다.
예를 들어 odbc는 JDBC-OBDC 브리지를 위해 지정된 서브프로토콜이다.
또다른 예제로, 만약 Miracle Corportion이 있다면, Miracle DBMS들에 연결하는 JDBC 드라이버를 위한 서브 프로토콜로써
"miracle"을 등록하여 다른 사람들이 사용하지 않도록 하고 싶어할 것이다.
JavaSoft는 JDBC 서브 프로토콜 이름들을 위한 비공식적인 등록절차를 대행하고 있다.
서브 프로토콜 이름을 등록하기 위해서는 email을 아래의 주소로 보내라.
jdbc@wombat.eng.sun.com
2.1.6 SQL문들을 전송하기
일단 연결이 되면, 데이터베이스에 SQL문을 전송하는데 사용되어진다.
JDBC는 전송될 수 있는 SQL문의 종류에 제한을 두지 않는다.
이것은 데이터베이스-특정 SQL문, 심지어 non-SQL 문들의 사용을 허용하는 대단한 융통성을 제공한다.
그러나, 사용자는 데이터베이스가 전송되어지는 SQL문을 처리할수 있고 결과를 허용할 수 있는지를 확인해야한다.
예를 들어, 저장 프로시져를 지원하지 않는 DBMS로 저장프로시져 호출을 보내는 어플리케이션은 실행되지 않고 예외상황을 발생할 것이다.
JDBC는 드라이버가 JDBC COMPLIANT로 지명되어지기 위해서 적어도 ANSI SQL-2 Entry Level 능력들을 제공할 것을 요구한다.
이것은 사용자가 적어도 이러한 기능의 표준 레벨에 의지할 수 있음을 의미한다.
JDBC는 SQL문들을 데이터베이스로 전송하기 위해 세가지 클래스를 제공하며, Connection 인터페이스에 있는 세가지 메쏘드들을 가지고 이러한 클래스들의 인스턴스를 생성한다.
세가지 클래스와 Connection 인터페이스에 있는 메쏘드는 다음과 같다.:
Statement - createStatement 메쏘드에 의해 생성된다. Statement 객체는 간단한 SQL 문들을 전송하는데 사용된다.
PreparedStatement - prepareStatement 메쏘드에 의해 생성된다.
PreparedStatement 객체는 하나이상의 입력 인자를 매개변수(IN 매개변수)로 가지는 SQL문을 위해 사용되어진다.
PreparedStatement는 IN 매개변수의 값을 설정하는 메쏘드들을 가지며, 이것들은 SQL문이 실행되어질 때 데이터베이스로 전송된다.
PreparedStatement의 인스턴스는 Statement를 상속하기 때문에 Statement 메쏘드들을 포함한다.
PreparedStatement 객체는 미리 컴파일되고 이후의 사용의 위해 저장되기 때문에 Statement 객체보다 더욱 효과적이 될 수 있는 잠재력을 가진다.
CallableStatement - prepareCall 메쏘드에 의해 생성된다.
CallableStatement객체는 SQL 저장 프로시져들-함수를 호출하는 것처럼 이름에 의해 호출되어지는(call by name) SQL문의 그룹-을 실행하는데 사용된다.
CallableStatement 객체는 PreparedStatement로부터 IN 매개변수를 처리하기 위한 메쏘드를 상속받고 OUT과 INOUT 매개변수를 처리하기 위한 메쏘드를 추가한다.
다음은 다른 형태의 SQL문들을 생성하는데 어떠한 Connection 메쏘드가 적당한가를 결정하기 위한 방법을 제공한다.
createStatement 메쏘드는 다음을 위해 사용되어진다.
간단한 SQL문들(매개변수 없음)
prepareStetement 메쏘드는 다음을 위해 사용되어진다.
하나 이상의 IN 매개변수들을 가지는 SQL문들
자주 실행되어질 간단한 SQL문들
prepareCall 메쏘드는 다음을 위해 사용된다.
저장 프로시져들의 호출
2.1.7 트랜젝션들
트랜젝션은 실행되고 완결된 다음 회부되거나 되돌아오는 하나 이상의 SQL문으로 구성된다.
commit 나 rollback 메쏘드가 호출될때, 현재 트랜젝션이 끝나고 다른 것이 시작된다.
새로운 연결은 디폴트로 auto-commit 모드이다.
이것은 SQL문이 완결될때에, commit 메쏘드가 그 SQL문을 자동적으로 요청하게 됨을 의미한다.
이러한 경우에 각 SQL문을 개별적으로 회부되어지기 때문에, 트랙젝션을 오직 하나의 SQL문으로 구성된다.
만약 auto-commit 모드가 비활성화 된다면, 트랙젝션은 commit나 rollback 메쏘드가 명백하게 호출되기 전까지는 종료되지 않는다.
따라서 트랜젝션은 commit나 rollback 메쏘드의 마지막 호출 이후에 실행되어지는 모든 SQL문을 포함할 것이다.
이러한 두 번째 경우에서, 트랙젝션에 있는 모든 SQL문들은 그룹으로써 회부되거나 되돌아온다.
commit 메쏘드는 SQL문이 데이터베이스에 만드는 변화를 영구적으로 만들고, 또한 트랜젝션에 의한 어떠한 락들도 풀어놓는다.
rollback 메쏘드는 변화들을 취소할 것이다.
때때로 사용자는 다른 하나가 원하지 않는다면 효과를 가지는 변화를 원하지 않을 것이다.
이것은 auto-commit를 비활성화 시키고 갱신된 두 개를 하나의 트랜젝션으로 그룹지음으로써 완성할 수 있다.
만약 두 개의 갱신이 모두 성공했다면 효과를 영구히 하기위해서 commint 메쏘드가 호출되고, 하나가 실패하거나 두 개 모두 실패하면 갱신이 실행되기 전에 있던 값을 다시 저장하기 위해서 rollback 메쏘드가 호출된다.
대부분의 JDBC 드라이버들은 트랙젝션을 지원한다.
사실상 JDBC-COMPLIANT 드라이버들은 트랜젝션을 지원해야한다.
DatabaseMetaData는 DBMS가 제공하는 트랜젝션 지원 레벨을 설명하는 정보를 준다.
2.1.8 트랜젝션 분리 레벨들
만약 DBMS가 트랜젝션 처리를 지원한다면, 동시에 하나의 데이터베이스에서 두 개의 트랜젝션이 동작할 때 일어날 수 있는 잠재적인 충돌을 관리하는 방법을 가지고 있을 것이다.
사용자는 잠재적인 충돌들을 해결하는데 DBMS가 어떠한 보호 레벨을 사용할 수 있는가를 나타내는 트랜젝션 분리 레벨을 지정할 수 있다.
예를 들어, 한 트랜젝션이 값을 바꾸고 변화가 확정되거나 취소되기전에 두 번째 트랜젝션이 그 값을 읽을 때 무엇이 발생하는가?
허용이 된다면, 첫 번째 트랜젝션이 취소될때에 두 번째 트랜젝션에 의해 읽어진 변화된 값이 유효하지 않게 되는가?
JDBC 사용자는 변화가 영구히 되기전에 값을 읽을수 있도록 다음의 코드를 가지고 DBMS에게 명령할 수 있다.
여기서 con은 현재의 연결이다.:
con.setTransactionIsolation(TRANSACTION_READ_UNCOMMITTED);
트랙젝션 분리 레벨이 높으면 높을수록, 충돌을 피하기위해서 더욱 주의를 해야한다.
Connection 인터페이스는 트랜젝션이 전혀 지원되지 않는 것을 가장 낮게 그리고 하나의 트랜젝션이 데이터베이스상에서 동작중에 있는동안
다른 트랜젝션들이 그 트랜젝션에 의해 읽혀진 데이터에 어떠한 변화도 만들지 않는 것을 가장 높게 하여 5개의 레벨을 정의한다.
전형적으로 분리 레벨이 높으면 높을수록 어플리케이션의 속도는 더욱 느려진다.
(왜냐하면 락 오버헤드가 증가하고 사용자들 사이에 동시발생이 감소하기 때문이다.)
개발자는 어떤 분리 레벨을 사용할 것인가에 대해 결정할 때 성능을 위한 요구와 데이터 일관성을 위한 요구를 비교 평가해야만 한다.
물론 실제적으로 지원될 수 있는 레벨은 사용하는 DBMS의 능력에 좌우된다.
새로운 Connection 객체를 생성할때에 트랜젝션 분리 레벨은 드라이버에 의존하지만 보통 데이터베이스에 디폴트이다.
사용자는 트랜젝션 분리 레벨을 변경하기 위해서 setIsolationLevel 메쏘드를 호출할 것이고 새로운 레벨은 사실상 연결 부분의 나머지가 될 것이다.
단지 하나의 트랜젝션을 위해 트랜젝션 분리 레벨을 바꾸는 경우에는 트랜젝션이 시작하기 전에 설정하고 트랜젝션이 종료된 후에는 재설정한다.
트랜젝션 도중에 분리레벨을 변경하는 것을 바람직하지 않다.
왜냐하면 이것은 commit 메쏘드를 즉시 호출을 하여 그 시점까지의 어떠한 변화들을 영구적으로 만들기 때문이다.
댓글