Java | JDBC with Oracle
JDBC
Java Database Connectivity
자바에서 Database에 접속할 수 있도록 제공하는 API
JDBC 개요
- 자바 어플리케이션에서 표준화된 데이터베이스 접근 제공
- 각 데이터베이스 접속에 대한 상세한 정보를 알 필요 없음
java.sql 패키지에 DB에 관련된 거의 모든 것이 인터페이스로 구성되어 있음
즉, 데이터베이스는 달라도 같은 이름의 메소드를 사용하게 됨 - DB에 맞는 JDBC Driver 필요
- 과정: 웹에서 DB 요청 → jsp → JDBC api → JDBC Driver → DB
JDBC API
- DB에 대해서 적절한 처리를 할 수 있도록 설계된 인터페이스 및 클래스 집합
- java.sql 패키지에서 제공되므로 import 해야 함
JDBC Driver
- 특정 DB와 통신하기 위해 어플리케이션 서버와 DB를 연결하는 것
- 4종류의 타입이 존재함
type | Driver 종류 | 설명 |
---|---|---|
1 | Jdbc-ODBC Bridge | 자바 표준 API에서 제공하는 ODBC Driver 이용 MS의 AccessDB 연동시 사용 |
2 | Native-API | 해당 DBMS 라이브러리 API를 JDBC API로 wrapping한 형태 클라이언트에 해당 DB 라이브러리와 JDBC 드라이버가 같이 존재 |
3 | Proxy | JDBC 드라이버에서 요청한 것을 중간에 DB 미들웨어를 통해서 명령 실행 클라이언트는 100% 자바 JDBC 드라이버 제공 |
4 | Pure | JDBC 드라이버에서 직접 DB에 명령하는 방식 인트라넷 환경에 적합 |
※ 웹페이지와 데이터베이스를 연동할 때는 주로 Pure 드라이버 사용
1~3번은 요즘엔 잘 사용되지 않는다고 함
전체 과정_Connect to ORACLE
① JDBC Driver Load
접속할 데이터베이스 드라이버를 메모리에 올림
Class.forName(DRIVER_CLASS);
// Class.forName("oracle.jdbc.driver.OracleDriver");
※ Class< T > 클래스, static Class< ? > forName(String className) 메소드
className으로 주어진 클래스와 관련된 Class 객체 반환
className은 패키지명.클래스명으로 이루어짐
② Connection
DB에 사용자가 연결된 상태를 관리하는 인터페이스
DB정보로 Connection 객체를 얻어와야 함
Connection conn = DriverManager.getConnection(JDBC_URL, "ID", "PWD")
// JDBC_URL = "jdbc:oracle:thin:@ip주소:port번호:SID"
- IP 주소: 오라클이 설치된 컴퓨터의 IP 주소 혹은 도메인 이름
- 포트: 오라클에서 네트워크를 통한 접속을 처리하기 위해 실행되어 있는 리스너의 사용 포트, 기본값은 1521
- SID: 오라클 인스턴스 이름으로 MySQL에서는 DB 이름으로도 불림 ex) orcl
- url, id, pwd와 같은 민감한 정보는 .properties로 관리해야 함
- DriverManager 클래스: JDBC 드라이버 설정을 관리하는 기본 서비스 제공
- static Connnection getConnection(String url, String user, String password)
주어진 DB 정보로 연결을 시도함
Connection Method
메소드 | 설명 |
---|---|
Statement createStatement() | DB로 SQL 문장을 전송하는 Statement 객체를 생성함 |
PreparedStatement prepareStatement(String sql) | DB로 매개변수를 포함한 SQL 문장을 전송하는 PreparedStatement 객체를 생성 |
java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDrive
oracle.jdbc.driver.OracleDriver 는 외장 라이브러리이기 때문에
이클립스에서 직접 불러와야 함
발생 이유
- 오타인 경우
- 드라이버를 못 찾는 경우
Oracle 10g 이후 버전에서 드라이버를 못 찾는 경우
- C:\oracle\product\11.2.0\dbhome_1\jdbc\lib 폴더에서
ojdbc6.jar파일을 이클립스에서 불러오면 됨 - Package Explorer에서 프로젝트 선택
File → Properties → Java Build Path → Libraries
→ Add External JARs → ojdbc6.jar 파일 추가 → Apply → Close - 또는 C:\jdk1.8\jre\lib\ext 폴더에 ojdbc6.jar 파일을 복사 / 붙여넣기
→ 전역으로 설정하는 것이기 때문에 이클립스에서 불러오지 않아도 됨 - 파일을 다른 경로에 저장한다면 classpath 환경 변수로 경로를 지정해 주어야 함
※ Oracle 9i → jdbc14.jar
※ oracle.jdbc.driver.OracleDriver
ojdbc6.jar 파일의 압축을 풀어보면 위의 경로에 OracleDriver가 들어있음
③ Statement 생성 및 Query 실행
Statement 인터페이스이며 SQL 문장 실행을 위해 객체로 생성 해야 함
- 인터페이스이기 때문에 스스로 객체를 생성하지 못함
Connection 인터페이스의 createStatement() 메소드 이용 - SQL 문장을 정확하게 전부 입력해야 함
- 선택 필드나 조건이 바뀌는 경우 새롭게 작성해야 함
// Statement 객체 생성
Statement stmt = conn.createStatement();
// SQL문 변수
sql = "SQL문 작성";
// SQL문 실행
stmt.executeQuery(sql); // sql이 SELECT문인 경우
stmt.executeUpdate(sql); // sql이 그 외 DML, DDL문인 경우
Statement Method
Statement 객체에서 SQL 문장을 전송하기 위해 사용하는 메소드
메소드 | 설명 |
---|---|
ResultSet executeQuery(String sql) | SELECT문 전송시 사용 쿼리 결과로 ResultSet 객체 반환 |
int executeUpdate(String sql) | INSERT, UPDATE, DELETE문 전송시 사용 처리된 로우 수를 정수형으로 반환 처리 실패시(처리 결과가 없는 경우) 0을 리턴 DDL문도 전송가능 하며 DDL문은 성공시에도 처리하는 로우가 없기 때문에 0을 리턴 |
④ PreparedStatement 생성 및 Query 실행
PreparedStatement 인터페이스이며 SQL 문장이 미리 컴파일되어 있는 객체
- Statement 인터페이스를 상속함
Statement와 마찬가지로 Connection 인터페이스의
prepareStatement(String sql) 메소드를 이용해서 객체 생성 - ?: 매개변수 부분에 작성해서 setter 메소드로 그때그때 원하는 값을 설정
sql의 '&변수명' 치환 매개변수와 동일한 역할을 함 - Statement보다 처리 속도가 빠름
// PreparedStatement 객체 생성, sql문장을 매개변수로 전달
PreparedStatement pstmt = conn.prepareStatement(sql);
// 매개변수 값 설정
pstmt.setString(parameterIndex, value);
pstmt.setInt(parameterIndex, value);
// SQL문 실행
pstmt.executeUpdate();
※ PreparedStatement 역시 매개변수 없이 사용할 수 있음
PreparedStatement Method
PreparedStatement의 매개변수에 값을 전달하는 setter 메소드
실질적인 전송을 할 때는 Statement의 SQL 문장 전송 메소드 사용
메소드 | 설명 |
---|---|
void setString(int parameterIndex, String x) | parameterIndex 번째 ?(매개변수)에 x 값 전달 첫 번째 매개변수의 parameterindex는 1 |
void setInt(int parameterIndex, int x) | parameterIndex 번째 ?에 x 값 전달 |
※ 자료형별 setter 메소드가 있기 때문에 자료형에 맞는 메소드 호출
JDBC 드라이버가 Java 자료형을 SQL 자료형에 맞게 변환함
※ SQLException 예외를 처리해야 함
⑤ ResultSet 결과 받기
ResultSet 인터페이스이며 DB에 쿼리 문장을 전송하면
일반적으로 생성되는 DB 결과 세트를 데이터 표로 나타냄
- ResultSet은 Cursor 개념의 연결 포인터
- Cursor: 데이터 표에서 데이터를 가리키는 포인터
- 기본적으로 next() 메소드를 통해 다음 로우로 이동
// Query 결과를 ResultSet 객체로 생성
ResultSet rs = pstmt.executeQuery();
ResultSet Method
메소드 | 설명 |
---|---|
boolean first() | Cursor를 ResultSet 객체의 첫 번째 로우로 이동 로우가 있다면 true, 없으면 false 반환 |
boolean next() | Cursor를 현재 로우에서 다음 로우로 이동시킴 |
boolean previous() | Cursor를 이전 로우로 이동시킴 |
boolean last() | Cursor를 마지막 로우로 이동시킴 |
String getString(String columnLabel) | columnLabel 칼럼의 로우를 문자열로 반환 |
String getString(int columnIndex) | columnIndex번째 칼럼의 로우를 문자열로 반환 |
Int getInt(String columnLabel) | columnLabel 칼럼의 로우를 정수로 반환 |
Int getInt(int columnIndex) | columnIndex 번째 칼럼의 로우를 정수로 반환 |
※ 자료형마다 label 또는 index 매개변수로 컬럼의 로우를 가져올 수 있지만
index의 경우 테이블 구조가 변화하면 값을 수정해야 하기 때문에
label 매개변수를 사용하는 것이 편리함
⑥ 연결 해제
- Connection을 close() 해주지 않으면 사용하지 않는 연결이 유지됨
DB 자원을 낭비하게 됨 - 생성된 객체의 역순으로 메모리를 해제함
ResultSet, Statement, Connection 순서 - 각 객체의 close() 메소드 이용
예외 발생 유무와 관계없이 반드시 메모리에서 해제하기 위해 finally 구문에 작성하는 것이 좋음
단, close() 메소드 역시 SQLException 예외를 처리해야 하기 때문에
try ~ catch ~ 문을 사용해야 함
finally{
try{
rs.close();
stmt.close();
conn.close();
}
catch(SQLException e){
e.printStackTrace();
}
}
자바와 데이터베이스를 연동하는 API인 JDBC와 그 사용법에 대해 알아보았습니다.
데이터베이스와 연동을 하지 않으면 어플리케이션의 정보가 프로그램을 종료할 때마다 사라지기 때문에
데이터를 저장하고 관리하기 위해서는 자바와 데이터베이스를 연동하는 것이 꼭 필요하다고 할 수 있습니다.
다음 글에서는 JDBC를 사용해서 실제로 자바와 Oracle을 연동하는 예제에 대해 살펴보겠습니다.