본문 바로가기

MySql

[JDBC] JDBC Driver 한 방 정리

 


 

JDBC

정의

JDBC(Java Database Connectivity)는 자바 애플리케이션에서 데이터베이스에 접근할 수 있도록 하는 API입니다. JDBC 드라이버는 이 API를 구현하여, 자바 애플리케이션과 특정 데이터베이스 간의 연결을 가능하게 합니다.

 

타입

  1. Type 1 : JDBC-ODBC Bridge Driver
  2. Type 2 : Native API, Partly Java Driver
  3. Type 3 : Net Protocol, Pure Java Driver
  4. Type 4 : Native Protocol, Pure Java Driver
    • 데이터베이스의 네이티브 프로토콜을 사용하여 직접 데이터베이스에 접근합니다.
    • 순수 Java로 구현되어 드라이버가 플랫폼에 종속되지 않고, 성능이 가장 좋습니다. 현재 가장 많이 사용되는 타입입니다.
      • Java의 JVM 특징 : 운영체제에 종류와 상관없이 독립적으로 돌아갑니다. 

 


 

JDBC Driver

정의

애플리케이션이 특정 데이터베이스 시스템과 통신할 수 있도록 하는 소프트웨어 부품입니다.

 

역할

  1. 중개자 역할 : 애플리케이션과 데이터베이스 시스템 간의 통신을 가능하게 해줍니다.
  2. 규칙 준수 : 데이터베이스 시스템마다 통신 방식이 다르기 때문에, 드라이버는 해당 데이터베이스 시스템에 맞는 규칙(프로토콜)을 준수하여 통신을 처리합니다.
  3. 추상화 : 애플리케이션은 드라이버를 통해 데이터베이스 시스템의 종류에 관계없이 동일한 방식으로 데이터를 다룰 수 있습니다.

 

종류

데이터베이스 시스템마다 호환되는 다양한 Driver가 있습니다. 예를 들어, Oracle, MySQL, PostgreSQL 등 각 데이터베이스 제품에 맞는 특정 JDBC Driver가 필요합니다.

Java 의 데이터베이스별 Driver

 

 


 

Driver 동작 방식

  1. 연결 초기화
    • 요청 수신 : 애플리케이션은 데이터베이스 작업을 시작하기 위해 드라이버에 연결을 요청합니다.
    • 연결 설정 : 드라이버는 데이터베이스 서버에 로그인하고 필요한 설정을 수행하여 연결을 완료합니다.
      • 이 과정을 통해 네트워크 정보, 인증 자격 증명 등을 사용하여 이루어집니다.
  2. SQL 전송 및 실행
    • SQL 명령 변환 : 애플리케이션에서 발송된 SQL 명령을 받은 드라이버는 해당 명령을 데이터베이스가 이해할 수 있는 형태로 변환합니다.
    • 명령 처리 : 변환된 명령은 데이터베이스 서버로 전송되어 실행됩니다. 데이터베이스는 쿼리를 처리하고, 요구된 데이터를 검색하거나 데이터에 변화를 줍니다.
  3. 결과 처리
    • 결과 수신 : 데이터베이스에서 작업의 결과를 보내면, 드라이버는 이 결과를 받아 애플리케이션에서 해석할 수 있는 형태로 변환합니다.
    • 결과 전달 : 최종적으로, 드라이버는 이 결과를 애플리케이션에 전달합니다. 애플리케이션은 이 정보를 사용자에게 표시하거나 다음 작업을 진행합니다.
  4. 연결 종료
    • 연결 해제 : 작업이 완료되면, 드라이버는 데이터베이스 서버와의 연결을 종료합니다. 자원을 정리하고 다음 세션을 위해 시스템을 초기화합니다.

 

더보기

💡 `JDBC Driver Manager`는 애플리케이션이 실행되고 있는 런타임 시점에

  • Connection(연결) 생성 : 등록된 Driver 목록에서 요청된 연결 URL에 맞는 Driver를 찾아 연결을 생성합니다.
    • 연결을 완료하면 `Connection` 객체를 반환합니다.
  • Statement(상태) 를 생성하여 쿼리를 요청하게 해주고
  • ResultSet(결과셋) 을 생성해 쿼리 결과를 받아올 수 있게 해줍니다.

 

 

 

 

예제 코드

// JdbcApplication.java

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class JdbcApplication {

	public static void main(String[] args) throws SQLException {
		// 어플리케이션 실행 컨텍스트 생성
		SpringApplication.run(JdbcApplication.class, args);

		// 데이터베이스 연결정보
		String url = "jdbc:h2:mem:test"; 	// spring.datasource.url
		String username = "sa";				// spring.datasource.username

		// connection 얻어오기
		try (Connection connection = DriverManager.getConnection(url, username, null)) {
			try {
				// 테이블 생성 (statement 생성)
				String creatSql = "CREATE TABLE USERS (id SERIAL, username varchar(255))";
				try (PreparedStatement statement = connection.prepareStatement(creatSql)) {
					statement.execute();
				}

				// 데이터 추가 (statement 생성)
				String insertSql = "INSERT INTO USERS (username) VALUES ('teasun kim')";
				try (PreparedStatement statement = connection.prepareStatement(insertSql)) {
					statement.execute();
				}

				// 데이터 조회 (statement 생성 후 rs = resultSet 수신 & next() 조회)
				String selectSql = "SELECT * FROM USERS";
				try (PreparedStatement statement = connection.prepareStatement(selectSql)) {
					var rs = statement.executeQuery();
					while (rs.next()) {
						System.out.printf("%d, %s", rs.getInt("id"), rs.getString("username"));
					}
				}
			} catch (SQLException e) {
				if (e.getMessage().equals("ERROR: relation \"account\" already exists")) {
					System.out.println("USERS 테이블이 이미 존재합니다.");
				} else {
					throw new RuntimeException();
				}
			}
		}
	}
}