JDBC란?
1. JDBC(Java Database Connectivity)란?
JDBC는 자바 애플리케이션이 데이터베이스에 접근하여 SQL 문을 실행할 수 있도록 자바 표준 스펙(JDK)에서 제공하는 인터페이스 기반의 API입니다.
자바스크립트가 브라우저 종류(크롬, 사파리 등)와 상관없이 표준 DOM API를 통해 화면을 제어하듯, 자바 개발자 역시 어떤 데이터베이스 엔진(MySQL, Oracle 등)을 쓰든 상관없이 동일한 자바 코드(Connection, Statement, ResultSet)로 DB를 제어할 수 있도록 추상화된 규칙(룰 베이스)을 제공하는 역할을 합니다.
2. JDBC 연결을 위한 라이브러리(Lib)와 DB 엔진
JDBC는 껍데기(인터페이스)일 뿐이므로, 실제 특정 DB 엔진과 통신하려면 그 엔진의 언어로 번역해 줄 수 있는 드라이버 라이브러리(Jar) 파일이 필요합니다.
- JDBC DB 엔진: 실제 데이터가 저장되고 SQL이 실행되는 서버 소프트웨어입니다. (예: MySQL, Oracle, PostgreSQL, H2 등)
- 연결 라이브러리(JDBC Driver): 자바와 DB 엔진 사이의 통신 규약을 맞추기 위해 벤더사들이 제공하는 구체적인 구현체입니다.
3. JDBC 엔진(커넥션)을 관리하는 툴
기본적으로 자바 내장 API에는 드라이버를 로드하고 연결을 맺어주는 DriverManager가 존재합니다. 하지만 실무 환경에서 DriverManager를 직접 쓰면 쿼리를 날릴 때마다 네트워크 커넥션을 새로 맺고 끊어야 하므로 비용이 엄청나게 발생합니다.
이러한 로우레벨 커넥션 생성 메커니즘을 효율적인 규칙으로 통제하기 위해 사용하는 커넥션 관리 툴이 바로 Connection Pool(대표적으로 HikariCP)입니다.
1) HikariCP(커넥션 풀)를 사용하면 좋은 점
- 압도적인 성능 향상: 미리 일정 개수의 DB 커넥션을 메모리에 생성해 두고(Pool), 필요할 때마다 대여하고 반납하는 방식을 취하므로 커넥션 생성 오버헤드가 제로에 가까워집니다.
- 시스템 과부하 방지: 동시 사용자가 폭증해도 무한정 커넥션을 늘리지 않고 정해진 풀 크기 내에서 대기시키므로, DB 엔진이 리소스 고갈로 다운되는 대참사를 방지합니다.
- 커넥션 유효성 검사: 백그라운드에서 죽은 커넥션을 자동으로 정리하고 다시 살려주는 관리를 대행합니다.
2) 세팅 방식 (Spring Boot / application.yml 예시)
현대적인 자바 백엔드 환경에서는 스프링 부트가 기본 커넥션 풀로 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: MyHikariPool4. 네이티브 JDBC 연결 소스 코드 예시
전통적인 자바 코드로 커넥션 풀 없이 연결할 때는 자원 누수(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();
}
}
}5. 커넥션 풀(Pool)이 없을 때 발생하는 아키텍처적 한계
하이레벨 관리 영역에서 네이티브 방식을 실무 대규모 서비스에 도입하지 않는 이유는 명확합니다. 매 요청마다 위의 3, 4번 단계(TCP 연결 및 인증)를 반복하기 때문입니다.
- 네트워크 오버헤드 폭발: 웹 서비스에 1초에 1,000명의 사용자가 동시 접속한다면, 1,000번의 TCP 핸드셰이크와 1,000번의 DB 인증 처리가 동시에 일어나면서 서버와 DB 엔진의 CPU 리소스가 순식간에 고갈됩니다.
- 연결 유실 및 관리 불가능: 간혹 네트워크 불안정으로 끊어진 연결이 메모리에 고스트 소켓으로 남아있거나, 개발자가 실수로
close()를 누락하면 DB 엔진의 최대 연결 수(max_connections) 제한에 걸려 시스템 전체가 마비될 수 있습니다.
6. 구동 메커니즘 흐름

댓글
GitHub 계정으로 의견이나 질문을 남길 수 있습니다.