JDBC Driver 종류
** 타입1과 2는 순수 자바 드라이버가 지원이 안될때 사용하고 타입3과 4는 JDBC API를 통해 데이타베이스에 접근한다
타입 1: JDBC ODBC Brige + ODBC Driver
ODBC 드라이버를 통해 데이타베이스에 접근
타입 2: Native API partly Java Driver
C 로 작성된 자체 함수 인터페이스를 통해 데이타베이스에 접근
타입 3: JDBC Net pure Java Driver
미들 티어 서버를 통해 데이타베이스에 접근
타입 4: Native protocol pure Java Driver
데이타베이스 벤더가 제공하는 순수 자바 코드로 이루어진 JDBC 드라이버로 직접 데이타베이스에 접속
일반적으로 가장 많이 사용하는 드라이버이다
JDBC API
** 데이타베이스의 테이블 구조를 모르더라도 메타데이타를 통해 데이타베이스를 사용할 수 있다
** java.sql 패키지를 사용한다
** 좀 더 상세한 정보는 해당 API로 확인한다
인터페이스
Connection JDBC API를 통한 데이타베이스 연결
DatabaseMetaData 시스템 Catalog, Key, Table, Transaction에 관련된 사항둥 해당 데이타베이스에 관한
포괄적인 정보를 제공
ResultSetMetaData ResultSet 객체의 칼럼에 대한 타입과 프로퍼티 정보를 가져올 수 있는 인터페이스로
테이블의 칼럼 정보를 제공
ResultSet Statement 객체를 통해 데이타베이스에 전송된 SQL문에 의해 반환되는 데이타
Statement SQL문을 데이타베이스에 전송
PreparedStatement 반복되는 SQL문을 미리 컴파일 한 뒤 데이타베이스에 전송
CallableStatement 데이타베이스 내부의 스토어드 프로시저를 호출하기 위한 인터페이스
클래스
DriverManager JDBC 드라이버들을 관리
Types SQL 데이타 타입 선언
1. Conection
Statement createStatement() /* Statement 객체 생성 */
PreparedStatement preparedStatement(String sql) /* PreparedStatement 객체 생성 */
CallableStatement prepareCall(String sql) /* CallableStatement 객체 생성 */
Transaction 처리
메소드
setAutoCommit(boolean autoCommit)
- 데이타베이스 연결에 대한 자동 커밋 모드를 설정/해제 한다
- 데이타베이스에 대한 새로운 연결이 생성되면 기본적으로 자동 커밋 모드로 설정되기 때문에
매번 SQL문이 수행될 때마다 자동 커밋을 수행한다
- 자동 커밋 모드를 해제했을 경우에는 SQL문 수행후 commit()을 명시적으로 호출하지 않으면
처리 결과가 데이타베이스에 반영되지 않는다
getAutoCommit()
- 현재 설정되어 있는 자동 커밋 모드를 얻는다
commit()
- 작업 이후 발생한 모든 변경 사항을 커밋하여 데이타베이스에 반영하고 데이타베이스에 대한 락을 해제한다
자동 커밋 모드를 해제했을 경우에만 사용할 수 있다
rollback()
- 작업 이후 발생한 모든 변경 사항을 취소하고 데이타베이스에 대한 락을 해제한다
자동 커밋 모드를 해제했을 경우에만 사용할 수 있다
작업 순서
** 트랜잭션을 관련있는 작업 단위로 처리하고자 한다면 autoCommit을 false로 하고 사용자가 판단하는 시점에
commit()이나 rollback()을 처리 해서 트랜잭션을 종료한다
** 작업 수행중 예외가 발생하면 작업 이후 변경된 내용을 작업하기 이전으로 rollback해야 한다
2. DatabaseMetaData
ResultSet getCatalogs() 서버의 데이타베이스 리스트
ResultSet getSchemas(...) 서버의 사용자 리스트
ResultSet getTables(...) 데이타베이스 테이블 리스트
ResultSet getColumns(...) 테이블의 칼럼 리스트
ResultSet getPrimaryKeys(...) 기본 키 리스트
ResultSet getIndexInfo(...) 인덱스 리스트
3. ReslutSetMetaData
String getColumnName(int column) 칼럼명
int getColumnType(int column) 칼럼의 SQL 타입
int getColumnDisplaytSize(int column) NCHAR/NVARCHAR일 경우에는 *2
int getColumnCount() 테이블 칼럼의 갯수
int getScale(int column) 소수점 이하 자리수
4. ResultSet
** SELECT SQL문의 실행 결과로서 생성된 결과에 해당하는 테이블
** Statement를 닫을때, 다른 SQL을 실행할때, 여러 개의 결과를 생성한 상태에서 getMoreResults를 호출하면
이미 생성된 ResultSet은 내부적으로 자동으로 close된다
void close() ResultSet 닫기
boolean first() ResultSet의 첫번째 레코드로 이동
bollean last() ResultSet의 마지막 레코드로 이동
boolean next() 다음 레코드로 이동
boolean previous() 이전 레코드로 이동
boolean wasNull() 칼럼의 값이 NULL인지 검사
int getInt(칼럼) int
long getLong(칼럼) long
double getDouble(칼럼) double
String getString(칼럼) String
Timestamp getTimestamp(칼럼) 날짜/시간/시분초
byte[] getBytes(칼럼) binary, varbinary
Reader getCharacterStream(칼럼) clob, longvarchar
InputStream getBinaryStream(칼럼) blob, longvarbinary
5. Statement
** Statement는 오직 하나의 ResultSet만 생성하기 때문에 ResultSet 객체를 읽는 도중에 다른 ResultSet을 읽어야
한다면 반드시 서로 다른 두개의 Statement 객체가 필요하다
** Statement의 메소드를 실행하기 전에 이미 열려 있는 ResultSet 객체가 있으면 닫아야 한다
ResultSet executeQuery(String sql)
단일 ResultSet을 리턴한다
int executeUpdae(String sql)
insert, delete, update등과 같이 데이타베이스를 변경하여 갱신하는 작업을 한다
boolean execute(String sql)
여러 개의 ResultSet, update count를 리턴한다
boolean getMoreResults()
리턴 결과가 ResultSet이면 true를 결과가 없거나 변경된 갯수이면 false이다
getMoreResults가 false이고 getUpdateCount가 -1이면 더 이상 결과가 없다는것을 의미한다
ResultSet getResultSet()
현재 결과에 해당하는 ResultSet을 얻는다
int getUpdateCount()
변경된 데이타의 갯수를 리턴한다
-1이면 변경된 데이타가 없거나 결과가 ResultSet이라는것을 의미한다
6. PreparedStatement
** Statement 상속한다
** 파라미터를 넘겨줄때는 칼럼의 타입과 일치하는 메소드를 사용해야 하지만 일반적으로 setString을 사용해도 상관없다
ResultSet executeQuery() ResultSet을 리턴한다
int executeUpdate() 실행 결과 값을 리턴한다
boolean execute() 여러개의 결과를 리턴한다
ResultSetMetaData getMetaData ResultSetMetaData를 리턴한다
7. CallableStatement
** PreparedStatement 상속한다
void registerOutParameter(int parameterIndex, int sqlType)
주어진 위치에 해당하는 파라미터를 sqlType을 갖는 out 파라미터로 등록한다
void registerOutParameter(int parameterIndex, int sqlType, int scale)
파라미터 타입이 numeric이나 decimal일 경우 소수점 자리수를 지정한다
파라미터가 있는 프로시저 { call 프로시저명(?, ?, ... ) }
결과 값을 리턴하는 프로시저(Function) { ? = call 프로시저명(?, ?, ...) }
파라미터가 없는 프로시저 { call 프로시저명 }
SQL 데이타 타입
** JDBC에서 사용하는 데이타 타입은 크게 4가지로 나뉘어 진다
정수: BYTE, SHORT, INT, LONG
실수: FLOAT, DOUBLE
문자: CHAR, VARCHAR
날짜/시간: DATE, TIME, TIMSTAMP
java.sql.Types Oracle MSSQL MySql java.sql.ResultSet
----------------------------------------------------------------------------------------------------------------
LONGVARCHAR LONG TEXT/NTEXT TEXT getCharacterStream
CLOB CLOB LONGTEXT
LONGVARBINARY LONG RAW BLOB
BLOB BLOB LONGBLOB getBinaryStream
TINYINT TYNYINT TINYINT
SMALLINT SMALLINT SMALLINT
INTEGER INT INTEGER/INT getInt
BIGINT NUMBER BIGINT BIGINT getLong
BIT BIT
BOOLEAN getByte
DECIMAL DECIMAL DECIMAL
NUMERIC NUMERIC
FLOAT FLOAT FLOAT
REAL REAL
DOUBLE NUMBER(p, s) DOUBLE getDouble
CHAR CHAR/NCAHR CHAR/NCHAR CHAR
VARCHAR VARCHAR2/NVARCHAR2 ARCHAR/NVARCHAR VARCHAR getString
BINARY BINARY
VARBINARY RAW(n) VARBINAR/IMAGE getBytes
DATE DATE SMALLDATETIME DATE getDate
TIME TIME getTime
TIMESTAMP TIMESTAMP DATETIME DATETIME/TIMESTAMP getTimestamp
----------------------------------------------------------------------------------------------------------------
** sql.Types.CLOB, Types.LONGVARCHAR일 경우 MySql은 getString으로 Oracle, MSSQL은 getCharacterStream으로 처리한다
sql.Types.LONGVARBINARY, sql.Types.BLOB은 getBinaryStream으로 처리한다
sql.Types.NUMERIC, sql.Types.DECIMAL일 경우 소수점이 없으면 getLong을 사용한다
sql.Types.BINARY, sql.Types.VARBINARY는 바이트 배열(Byte[])로 데이타를 읽어온다
Oracle MSSQL MySql
----------------------------------------------------------------------------------------------------------------
LONG 2 GB TEXT 65535*2 Byte
CLOB 4 GB TEXT/NTEXT 8000 Byte 이상 LONGTEXT 4 GB
RAW(n) n 바이트
LONG RAW 2 GB BOLB 65535*2 Byte
BLOB 4 GB IMAGE 8000 Byte 이상 LONGBLOB 4 GB
BFIL 외부
TYNYINT 1 Byte TINYINT 1 Byte
SMALLINT 2 Byte SMALLINT 2 Byte
INT 4 Byte INTEGER/INT 4 Byte
NUMBER 숫자 BIGINT 8 Byte 정수 BIGINT 8 Byte
BIT 1 Byte(0, 1)
MONEY/SAMLLMONEY 화페 FLOAT 4 Byte
NUMERIC/DECIMAL 고정 소수점 DECIMAL
NUMBER(p, s) p전체 s소수점 이하 FLOAT/REAL 부동 소수점 DOUBLE 8 Byte
CHAR/NCHAR 고정 4000 Byte CHAR/NCHAR 고정 8000 Byte CHAR 고정 255 Byte
VARCHAR2/NVARCHAR2 가변 4000 Byte VARCHAR/NVARCHAR 가변 8000 Byte VARCHAR 가변 255 Byte
BINARY/VARBINARY 8000 Byte 이하
DATE 날짜(시간) SMALLDATETIME DATE/TIME 3 Byte
TIMESTAMP 4 Byte
TIMESTAMP YY/MM/DD/H/M/S/MS DATETIME 날짜 DATETIME 날짜(시간)
---------------------------------------------------------------------------------------------------------------- ** LONG, LONG RAW ** TABLE ** DECIMAL은 소수를 저장하지만
테이블에 칼럼 하나만 생성 SQL_VARIANT 내부적으로는 문자 형태로 저장
2 GB CURSOR TINYTEXT/TINYBLOB
SELECT 결과로 데이타를 리턴 UNIQUEIDENTIFIER MEDIUMTEXT/MEDIUMBLOB
데이타를 직접 저장 TIMESTAMP는 레코드가 변경 될 경우 ENUM
처음부터 순차적으로 읽음 자동으로 DB에 유일한 값으로 채워짐 YEAR
TO_LOB() 함수를 사용하여 LOB로 변환 시간과 전혀 관계가 없음
오브젝트 유형을 지원하지 않음
** CLOB, BLOB
테이블에 여러개의 칼럼을 생성
4 GB
SELECT 결과로 위치를 리턴
데이타를 직접 또는 간접 저장
랜덤 엑세스가 가능
LONG, LONG RAW로 변환할 수 없음
오브젝트 유형을 지원
JDBC 연결
** 한번 로드된 드라이버는 서버를 restart 하지 않는한 메모리에 남아 있는다
드라이버 클래스
** Mssql일 경우 WEB-INF\lib에 sqljdbc.jar(1.5)와, sqljdbc4.jar(1.6)를 같이 복사하지 않는데
JDK 1.6일 경우 sqljdbc4.jar를 인식하지 못하기 때문이다
반드시 현재 JDK 버전에 맞는 드라이버만을 복사한다
Oracle driver: oracle.jdbc.driver.OracleDriver
url: jdbc:oracle:thin:@localhost:1521:XE(XE는 오라클10g express를 설치할때 사용자가 지정한 sid)
jdbc:oracle:thin:@localhost:1521:oracle9i
** JDK 1.6: ojdbc14.jar
JDK 1.5: ojdbc14.jar
JDK 1.4: classes12.jar
Mssql 2005 driver: com.microsoft.sqlserver.jdbc.SQLServerDriver
url: jdbc:sqlserver://localhost:1433;databaseName=AdventureWorks
2000 driver: com.microsoft.jdbc.sqlserver.SQLServerDriver
url: jdbc:microsoft:sqlserver://localhost:1433;databasename=pubs(databasename=pubs는 작업하는 db 이름)
** JDK 1.6: sqljdbc4.jar
JDK 1.5: sqljdbc.jar
JDK 1.4: msbase.jar, mssqlserver.jar, msutil.jar
Mysql driver: org.gjt.mm.mysql.Driver
url: jdbc:mysql://localhost:3306/mysql?useUnicode=true&characterEncoding=euckr(mysql은 작업하는 db 이름)
** 버전에 상관없이 mysql-connector-java-5.1.10-bin.jar을 사용한다
프로퍼티 파일
** 데이타베이스 연결 정보를 저장하는 파일 형식이다
db.xml
** 웹서버의 홈 디렉토리 c:\inetpub\wwwroot\WEB-INF\classes에 .xml 파일을 보관한다
multi driver를 기본으로 2개 이상 드라이버를 지정할 수 있다
Pool 처리를 한번 하고 나면 드라이버가 메모리에 로드되어 있는 상태이기 때문에
Pool을 해제 하고 싶을 경우나 connection을 추가 수정했을 경우에는 다시 서블릿 컨테이너를 restart 해야 한다
** xml 태그는 대소문자를 구분하기 때문에 주의해야 한다
db.properties
** 웹서버의 홈 디렉토리c:\inetpub\wwwroot\WEB-INF\classes에 .properties 파일을 보관한다
driver는 하나만 지정할 수 있는데 여러개를 지정해도 마지막에 지정된 driver만 로드된다
property name(= 이전까지)은 반드시 소문자로, 값(= 이후부터)은 대문자,소문자 상관없다
값이 없어도 = 은 반드시 써야 한다
drivers=com.microsoft.jdbc.sqlserver.SQLServerDriver
mydb1.url=jdbc:microsoft:sqlserver://localhost:1433;databasename=pubs
mydb1.user=sa
mydb1.password=xxxx
mydb2.url=jdbc:microsoft:sqlserver://localhost:1433;databasename=northwiind
mydb2.user=sa
mydb2.password=xxxx
드라이버 연결
** Class.forName()은 JDBC 스펙과 JVM 구현간의 충돌이 일어날 수 있는데
이것을 피하기 위해서는 Class.forNmae().newInstance()를 사용해야 한다
부록 데이타베이스 커넥션 풀(DBCP) 소스
** dbcp를 통해서 Connection 객체를 얻어왔다면, con.close()를 해주면 된다
실제적인 db컨넥션이 close 되는게 아니라 DBCP가 Pool 에다가 반납하는 작업이 이루어진다
okjsp : http://www.okjsp.pe.kr/seq/151647
'JAVA' 카테고리의 다른 글
Thread의 이너클래스 (0) | 2014.02.11 |
---|---|
[jstl] 모델2JSP책 9장에 실리지 않은 내용 (0) | 2012.10.25 |
eclipse - SVN 에러 - RA layer request failed (0) | 2012.10.24 |
groovy와 java의 차이점 (0) | 2012.08.28 |
OOM 발생시 heap Dump 옵션 (0) | 2012.08.14 |