Java - JDBC 개요!
JDBC 개요
Java database connectivity
약자
다양한 데이터 베이스에 연결, 작업을 하기 위한 자바 표준 인터페이스(interface
)를 뜻한다.
각종 DBMS 에 접근할 때 각기 다른 종류의 메서드가 필요할 것이다(DB 종류가 다르니까!).
하지만 JDBC interface
를 사용하면 모든 DB에 동일한 메서드로 접속해서 쿼리 조회 결과를 가져오고 전달할 수 있다.
JDBC interface
를 구현한 클래스들은 DB회사에서 jar파일로 배포한다.
접속을 원하는 DBMS 에서 구현체만 jar 로 다운받아 class path 에 저장해서 사용하면 된다.
JDBC interface
는 JDBC 프로그램을 하기 위한 API들로서 JAVA SE에서 제공하는 java.sql 패키지를 의미.
그래서 JDBC를 표준화된 인터페이스라 한다
JDBC Driver
JDBC인터페이스를 구현한 클래스 파일 모음(jar파일)을 JDBC Driver
라 한다.
실제 JDBC interface
를 구현한 클래스, DB와 연결하기위해 만들어놓은 클래스 파일들이 모여있는, DB와 연결하기 패키지를 JDBC Driver
로 보면 된다.
오라클 OracleXE112_Win64
를 설치하면 다음과 같은 jar파일을 제공한다.
위 jar파일에 JDBC interface
를 구현한 클래스들이 들어있고 JDBC Driver
라 부른다.
DBMS 별로 제공하는 JDBC Driver
클래스명은 아래와 같다.
- Oracle jar파일 패키지 구조:
oracle.JDBC.driver.OracleDriver
- MsSQL jar파일 패키지 구조:
sun.JDBC.odbc.JDBC.OdbcDriver
- MySQL jar파일 패키지 구조:
org.git.mm.mysql.Driver
그럼 JDBC Driver
를 사용할 수 있도록 jre폴더에 집어넣자.
이클립스를 사용하면 프로젝트에 build path를 추가하면 된다.
JDBC Driver Manager
JDBC Driver를 관리하는 클래스
OracleDriver
클래스를 바로 new
를 통해 생성 사용하지 않고 DriverManager
라는 클래스를 거쳐서 DB에 접속한다.
아무리 JDBC interface
를 통해 구현된 JDBC Driver
라 하더라도 DB벤더에 따라 다른부분이 있을 것 이다. (드라이버 메모리에 로딩, DB연결, sql쿼리 수행 등)
각종 JDBC Driver 클래스의 획일되지 않은 연결방법, 쿼리수행 등을 DriverManager
를 통해 똑같은 방법으로 수행할 수 있다.
프로그램 → DriverManager → JDBC인터페이스 → JDBC드라이버 → DB
추가: 사실 JDBC드라이버는 4가지 타입으로 나뉜다.
하지만 우리가 쓸건type4
하나, 중간단계 없이 바로 DBMS를 호출하는 방법을 사용한다.
여러 DB밴더들도 해당type4
방식의JDBC Driver
를 제공한다.
Connection 순서
- 드라이버 로딩
- Connection 객체 생성
- 연결 종료
드라이버 로딩
Reflection
기반으로 드라이버 클래스를 로딩
Class.forName
명령어로 JDBC Driver
를 메모리상에 올린다.
String className = "oracle.JDBC.driver.OracleDriver";
Class.forName(className);
DriverManager
가 를 통해 드라이버를 가져와야 함으로 Class.forName
을 사용한다.
인스턴스 생성과 동시에 DriberManager
에 등록하는 과정이 OracleDriver
내부에 구현되어 있다.
Connection 객체 생성
DriverManager
를 이용해서 Connection
객체를 생성한다.
String url = "JDBC:oracle:thin:@172.17.107.68:1521:xe";
// thin이 type4를 의미한다.
String user = "scott";
String password = "tiger";
Connection conn = DriverManager.getConnection(url, user, password);
System.out.println(conn);
// oracle.JDBC.driver.T4CConnection@4d76f3f8
getConnection
으로 메모리에 올라간 드라이버객체를 바인딩하고 url
, user
, password
를 파라미터로 넣어 Connection
객체를 만든다.
Connection
객체이 잘 생성되었는지 확인하기 위해 출력
연결 종료
Connection 닫기
conn.close();
DBConn 클래스 설계
DB 연결객체는 하나이상 인스턴스화 할 필요 없다.
싱글톤 방식으로 연결객체를 생성, 해제할 수 있도록 DBConn
클래스를 설계해보자.
public class DBConn {
private static Connection connection = null;
//싱글톤을 위한 생성자 프라이빗 선언
private DBConn(){ }
public static Connection getConnection() {
if(connection == null) {
String className = "oracle.JDBC.driver.OracleDriver";
String url = "JDBC:oracle:thin:@172.17.107.68:1521:xe"; // thin이 type4를 의미한다.
String user = "scott";
String password = "tiger";
try {
Class.forName(className);
connection = DriverManager.getConnection(url, user, password);
} catch (SQLException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return connection;
}
public static Connection getConnection(String className, String url, String user, String password) {
if(connection == null) {
try {
Class.forName(className);
connection = DriverManager.getConnection(url, user, password);
} catch (SQLException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return connection;
}
//항상 DBconn으로 열었으면 DBConn으로 close하자.
public static void close() {
if(connection != null) {
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
connection = null;
}
}
}
null
이라면 Connection
객체를 Class.forName
를 사용해서 메모리에 생성하고
null
이 아니라면 이미 올라간 Connection
를 반환한다.
따라서 close()
함수에선 Connection
을 null
로 꼭 바꿔 주어야 한다.
public static void main(String[] args) {
Connection conn = DBConn.getConnection();
DBConn.close(); //DBConn으로 열었다면 DBConn으로 닫자
System.out.println(conn); // oracle.JDBC.driver.T4CConnection@4d76f3f8
}
Properties로 DB연결
DB 연결정보를 propertise 파일에 저장하고 Propertise
클래스를 사용해서 DB에 접속.
Properties prop = new Properties();
String fileName = ".\\src\\days02\\prop.properties";
Reader reader = new FileReader(fileName);
prop.load(reader);
//getProperty(키 이름) 을 사용해서 해당 값을 가져오자.
System.out.println(prop.getProperty("className")); // oracle.jdbc.driver.OracleDriver
System.out.println(prop.getProperty("hostName")); // 172.17.107.68
System.out.println(prop.getProperty("sid")); // xe
System.out.println(prop.getProperty("usr")); // null
System.out.println(prop.getProperty("password")); // tiger
String url = String.format("jdbc:oracle:thin:@%s:1521:%s" , prop.getProperty("hostName"), prop.getProperty("sid"));
Connection conn = DBConn.getConnection(prop.getProperty("className"), url, prop.getProperty("user"), prop.getProperty("password"));
System.out.println(conn); // // oracle.jdbc.driver.T4CConnection@e2144e4
DBConn.close();