[Java] JDBC 동작 원리와 커넥션 풀 이해하기

2025. 8. 6. 22:37·공부/☕Java

✅ 1. JDBC(Java Database Connectivity) 란?

  • 자바에서 데이터베이스에 접속하고 SQL을 실행해서 결과를 가져오는 기능을 제공하는 Java API 이다.
  • 쉽게말해, 자바 애플리케이션과 데이터베이스 사이의 연결 통로 역할을 해준다고 보면 된다.
  • JDBC 는 Java API 로써, JRE에 포함이 되어있으며, 해당 인터페이스 집합들을 데이터베이스(MySQL, Oracle, PostgreSQL 등) 이 해당 자바 인터페이스를 구현해 본인의 데이터베이스에 접근 할 수 있도록 클래스를 만들어 주게 된다. 해당 클래스를 라이브러리로 받아서 이용을 하게 되면, 해당 클래스와 맞는 데이터베이스와 연결을 할 수 있게 된다.
  • 참고로 해당 API 는 java.sql 또는 javax.sql 등의 패키지로 제공이 된다.
  • 또한, 해당 패키지의 인터페이스를 구현한 클래스를 "JDBC 드라이버" 라고 부른다.

(1) JDBC 구현 및 동작

// 1. 드라이버 로딩 (MySQL인 경우)
Class.forName("com.mysql.cj.jdbc.Driver");

// 2. DB 연결
Connection conn = DriverManager.getConnection(
    "jdbc:mysql://localhost:3306/mydb", "username", "password");

// 3. 쿼리 실행
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users");

// 4. 결과 처리
while (rs.next()) {
    System.out.println(rs.getString("name"));
}
  • 위의 코드와 같이 데이터베이스 사용은 드라이버를 로딩 한 뒤 DB를 연결하여 쿼리를 실행하는 과정을 거친다.

(2) 드라이버 로딩 이유

  • Class.forName 을 통해 드라이버를 로딩하게 되면, 정적 블록의 내부 코드가 실행이 된다.
Class.forName("com.mysql.cj.jdbc.Driver");

static {
    try {
        DriverManager.registerDriver(new Driver());
    } catch (SQLException e) {
        throw new RuntimeException("Failed to register driver");
    }
}
  • JDBC 는 인터페이스 기반의 API 이기 때문에, 실제로 동작혀려면 벤더가 제공하는 구현체인 드라이버 클래스가 필요함.
  • 해당 드라이버는 우리가 JVM에 로딩시켜줘야 DriverManager 가 이를 인식하고 관리할 수 있음.
  • 즉, 드라이버 클래스 로딩은 DriverManager 에 벤더의 드라이버를 등록하기 위함임.
  • 쉽게말해, DriverManager 는 커넥션을 만들 수는 있지만, 어떤 드라이버가 들어올지 모르니까 미리 알 수도 없고, 자동으로 로딩을 못함.
  • 그래서 직접 Class.forName() 같은 방식으로 드라이버 클래스를 먼저 로딩해서, 그 안에서 DriverManager 에 등록까지 해주게 만들어야 한다는 의미임.
  • 하지만, 요즘에는 파일에 자동 로딩 정보를 적어두어 서비스 로더로 불러와서 등록을 해줌.
  • 그치만 어차피 내부에선 클래스 로딩해줘야 등록이 된다는 핵심임.

(2) DriverManager 

Connection conn = DriverManager.getConnection(
    "jdbc:mysql://localhost:3306/testdb",
    "user",
    "password"
);
  • JDBC API 내부에는 인터페이스 뿐 아니라 해당 DriverManager 와 같이 실제 클래스도 포함이 되어있음.
  • 해당 DriverManager 는 JDBC 에서 DB 연결을 생성할 때 사용하는 중앙 관리자 클래스임.
  • 쉽게 말해, 등록된 드라이버들 중 어떤 걸 써야 할지 골라주고, 연결을 위임해주는 역할을 함.
  • java.sql.DriverManager 패키지에 있으며, 정적 클래스임.

[1] DriverManager 내부 동작

  • DriverManager.getConnection() 메서드가 호출이 되면, 드라이버 매니저 내부에서 등록된 드라이버 목록을 순회한다.
  • 등록된 드라이버 목록은 보통 위의 드라이버 로딩 과정의 static 블록에서 자동으로 등록이 됨.
  • 몇개가 있을진 모르겠지만, 각 드라이버에게 URL을 넘겨 acceptsURL(String url) 메서드로 검사를 함.
  • 예시로는 "jdbc:mysql://..." url 로 등록이 되어있다면, 해당 MySQL 드라이버가 선택이 됨.
  • 선택된 드라이버 구현체의 connect() 메서드 호출
  • 이  connect() 메서드 호출 시점에 벤더 구현체가 직접 동작을 하며, 내부의 네트워크 및 다양한 로직이 수행 됨.
  • 벤더 내부에선 TCP 소켓 열기, DB 주소 포트로 접속 시도, 로그인 인증, 프로토콜 핸드셰이크, 커넥션 객체 생성 등 작업을 함.

✅ 2. JDBC & DB 통신 원리

(1) JDBC는 네트워크 소켓 기반 통신을 사용함

  • JDBC 드라이버는 TCP/IP 기반의 소켓 통신을 이용해 DB와 연결을 함.
  • 즉, 결국 JDBC <-> DB 서버는 네트워크 소켓을 통해 데이터를 주고 받는다는 의미임.
  • JDBC Driver 즉, 벤더 로직 내부 로직에는 DB 통신 로직이 들어가 있어, 통신이 되며 SQL 을 패킷 형태로 주고 받음

(2) 상세 동작 원리

Java 애플리케이션
       ↓
[JDBC API 호출]
       ↓
JDBC Driver (DB 회사가 제공한 구현체)
       ↓
[TCP/IP 소켓 열기 → DB 서버와 연결 시도]
       ↓
DB 서버 (예: MySQL, Oracle 등)
       ↓
[SQL 처리 → 응답 생성]
       ↑
[응답 결과 소켓으로 전송]
       ↑
JDBC Driver가 결과를 자바 객체로 변환
       ↑
Java 애플리케이션에서 ResultSet 등으로 결과 확인
  • DriverManager.getConnection() 을 호출하면 connect() 벤더 구현체의 메서드 connect() 메서드가 가 호출이 됨.
  • 이후엔, JDBC 드라이버가 내부적으로 Socket 을 열고 데이터베이스 포트에 맞게 패킷을 주고 받으며 통신을 진행함.
  • 이후엔, SQL을 실행하면 드라이버가 SQL 문장을 MySQL 프로토콜 형식의 바이너리 패킷으로 바꿔 전송을 함.
  • 이후엔, MySQL 서버가 이걸 읽어 SQL 실행 후 결과를 다시 패킷으로 응답을 하게 된다.

(3) 로컬 DB인 경우

  • 로컬의 경우에도 Driver 클래스의 connect() 메서드 호출 순간 내부에서 소켓을 만들어서 DB 서버와 TCP 통신을 시작함.
  • DB가 같은 컴퓨터인 Localhost 에 있어도, 결국에는 네트워크 스택을 통해서 TCP/IP 통신을 함.
  • 하지만 같은 OS 내에서 통신이므로 매우 빠름.

✅ 3. 커넥션 풀 (Connection Pool)

  • Connection 객체를 미리 만들어두어 저장하는 풀을 의미하며, 이것은 라이브러리로 제공이 된다.
  • 쉽게말해, 해당 라이브러리는 미리 만들어둔 커넥션을 풀에서 가져다가 사용하게 되는 원리이다.
  • 즉, DB와 연결된 소켓이 생성되어 있는 상태의 Connection 객체를 미리 풀에 만들어두게 되는 것이다.
  • JDBC Driver 는 단순히 Java 코드와 DB를 연결해주는 기능이라 커넥션 풀이 기본적으로 내장이 되어있지 않음.
  • 참고: SpringBoot 에는 HikariCP 라는 커넥션 풀 라이브러리가 내장이 되어있음.

(1) 커넥션 풀 동작 원리

  • 이 커넥션 풀은 JDBC 드라이버를 감싸서 효율적으로 재사용하도록 만들어진 추가 계층이다.
  • JDBC 에서 데이터베이스와 통신하려면 Connection 객체가 필요함
  • 이 Connection 객체는 내부적으로 DB 서버와 TCP 소켓을 열고, 로그인(인증) 절차를 거쳐 연결 상태를 유지함.
  • Heap 영역에 여러 개의 Connection 객체를 만들어 DB와 연결을 해둠.

(2) 커넥션 풀 사용 이유

  • DB 접근 및 SQL 실행을 위한 Connection 객체는 연결 과정에서 TCP 소켓, 로그인 절차를 거치는데 과정이 매우 무겁고 느림
  • 이걸 해결하기 위해 커넥션 풀을 활용하여, Connection 객체를 미리 만들어두고 재활용하는 방식을 이용하는 것임.
  • 그러면 속도가 증가하며, 리소스 낭비도 적고, 동시 처리 성능도 좋아진다는 장점이 있음.

'공부 > ☕Java' 카테고리의 다른 글

[Java] 프록시 패턴, 정적 프록시, 동적 프록시: Spring 사례 중심 설명  (1) 2025.07.09
[Java] 멀티 스레드 프로그래밍  (2) 2025.06.04
[Java] 자바 스트림(Stream) 개념 + 예제 총정리 📚  (2) 2025.06.03
[Java] 컬렉션 프레임워크 정리: List, Set, Map 인터페이스와 대표 구현체 총정리  (0) 2025.05.30
[Java] java.nio 사용법 | Path, Files, FileChannel 예제 모음  (3) 2025.05.30
'공부/☕Java' 카테고리의 다른 글
  • [Java] 프록시 패턴, 정적 프록시, 동적 프록시: Spring 사례 중심 설명
  • [Java] 멀티 스레드 프로그래밍
  • [Java] 자바 스트림(Stream) 개념 + 예제 총정리 📚
  • [Java] 컬렉션 프레임워크 정리: List, Set, Map 인터페이스와 대표 구현체 총정리
junbin2
junbin2
java.lang.NullPointerException
  • junbin2
    bin's Development Diary
    junbin2
  • 전체
    오늘
    어제
    • 전체보기 (233)
      • 방송통신대학교 (87)
        • ⚙️컴퓨터의 이해 (11)
        • 💻컴퓨터과학 개론 (15)
        • 🔢자료구조 (14)
        • 🧬알고리즘 (10)
        • ⚙️운영체제 (14)
        • 🕸️이산수학 (11)
        • 🌍유비쿼터스 컴퓨팅 (11)
        • 🖥️컴퓨터과학과 (1)
      • 공부 (72)
        • 📚백엔드 공부 (6)
        • ☕Java (23)
        • 🌳Spring (13)
        • ⚙️C (12)
        • ⚡Python (15)
        • JavaScript (1)
        • 🛢️Database (0)
        • Algorithm Problem Solving (2)
      • 네트워크 (7)
        • 📜HTTP (7)
      • 스파르타코딩클럽 (64)
      • 정보 (2)
      • 정리가 필요한 글 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    유비쿼터스
    함수
    컴퓨터의 이해
    알고리즘
    방통대
    운영체제
    방송통신대학교
    spring
    컴퓨터과학과
    Python
    그래프
    C언어
    배열
    컴퓨터과학 개론
    Java
    방송대
    자료구조
    자바
    이산수학
    파이썬
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
junbin2
[Java] JDBC 동작 원리와 커넥션 풀 이해하기
상단으로

티스토리툴바