JDBC는 자바 애플리케이션이 데이터베이스에 접근하여 SQL 문을 실행할 수 있도록 자바 표준 스펙(JDK)에서 제공하는 인터페이스 기반의 API입니다.
자바스크립트가 브라우저 종류(크롬, 사파리 등)와 상관없이 표준 DOM API를 통해 화면을 제어하듯, 자바 개발자 역시 어떤 데이터베이스 엔진(MySQL, Oracle 등)을 쓰든 상관없이 동일한 자바 코드(Connection, Statement, ResultSet)로 DB를 제어할 수 있도록 추상화된 규칙(룰 베이스)을 제공하는 역할을 합니다.
JDBC는 껍데기(인터페이스)일 뿐이므로, 실제 특정 DB 엔진과 통신하려면 그 엔진의 언어로 번역해 줄 수 있는 드라이버 라이브러리(Jar) 파일이 필요합니다.
기본적으로 자바 내장 API에는 드라이버를 로드하고 연결을 맺어주는 DriverManager가 존재합니다. 하지만 실무 환경에서 DriverManager를 직접 쓰면 쿼리를 날릴 때마다 네트워크 커넥션을 새로 맺고 끊어야 하므로 비용이 엄청나게 발생합니다.
이러한 로우레벨 커넥션 생성 메커니즘을 효율적인 규칙으로 통제하기 위해 사용하는 커넥션 관리 툴이 바로 Connection Pool(대표적으로 HikariCP)입니다.
현대적인 자바 백엔드 환경에서는 스프링 부트가 기본 커넥션 풀로 HikariCP를 채택하고 있으므로, 설정 파일에 아래와 같은 규칙성 있는 데이터(설정값)만 주입해 주면 엔진이 알아서 구동됩니다.
spring:
datasource:
# 1. 사용할 DB 엔진의 드라이버 규칙 지정
driver-class-name: com.mysql.cj.jdbc.Driver
# 2. DB 엔진 주소 및 프로토콜
url: jdbc:mysql://localhost:3306/my_database?serverTimezone=Asia/Seoul
username: admin
password: password123
# 3. HikariCP 커넥션 풀 세팅 관리
hikari:
maximum-pool-size: 10 # 최대 유지할 커넥션 개수
minimum-idle: 10 # 유휴 상태로 대기시킬 최소 커넥션 개수
connection-timeout: 30000 # 커넥션을 얻기 위해 대기하는 최대 시간 (30초)
pool-name: MyHikariPool전통적인 자바 코드로 커넥션 풀 없이 연결할 때는 자원 누수(Memory/Socket Leak)를 막기 위해 반드시 try-with-resources 문법을 사용하여 사용이 끝난 연결을 확실하게 닫아주어야 합니다.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class NativeJdbcExample{
public static void main(String[] args){
// 1. DB 엔진 주소 및 계정 정보 설정
String url = "jdbc:mysql://localhost:3306/my_database?serverTimezone=Asia/Seoul";
String username = "admin";
String password = "password123";
String sql = "SELECT user_name FROM users WHERE user_id = ?";
// 2. try-with-resources 구조로 Connection 직접 생성 및 자동 반환 설정
try {
// (선택사항) 과거 버전의 드라이버 호환성을 위해 드라이버 클래스 로드
Class.forName("com.mysql.cj.jdbc.Driver");
// 매 요청마다 DriverManager가 직접 DB 엔진과 물리적 소켓 연결을 맺음
try (Connection conn = DriverManager.getConnection(url, username, password);
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, 101);
try (ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
System.out.println("사용자 이름: " + rs.getString("user_name"));
}
}
} // 이 중괄호를 벗어나는 순간 conn.close()가 호출되어 물리 소켓이 닫힘
} catch (ClassNotFoundException e) {
System.err.println("JDBC 드라이버를 찾을 수 없습니다.");
e.printStackTrace();
} catch (SQLException e) {
System.err.println("DB 연결 중 에러가 발생했습니다.");
e.printStackTrace();
}
}
}하이레벨 관리 영역에서 네이티브 방식을 실무 대규모 서비스에 도입하지 않는 이유는 명확합니다. 매 요청마다 위의 3, 4번 단계(TCP 연결 및 인증)를 반복하기 때문입니다.
close()를 누락하면 DB 엔진의 최대 연결 수(max_connections) 제한에 걸려 시스템 전체가 마비될 수 있습니다.
댓글
GitHub 계정으로 의견이나 질문을 남길 수 있습니다.