리타의 저장소

JAVA | Java에서 DB 커넥션을 얻는 방법 #1 (feat. PreparedStatement) 본문

Dev/Backend

JAVA | Java에서 DB 커넥션을 얻는 방법 #1 (feat. PreparedStatement)

ريتا 2025. 10. 11. 23:28

Java

 

DataSource vs DriverManager

1. PostgreDbcp.getDataSource().getConnection();

  • DataSource를 통해 커넥션을 얻는 방법
  • (DataSource = 커넥션 풀링(Connection Pool) 기반)

2. DriverManager.getConnection(url, user, password);

  • DriverManager를 통해 직접 커넥션을 얻는 방법
  • (매번 새로운 커넥션을 만들어서 사용)

 

차이점 요약

구분 DataSource 방식 DriverManager 방식
커넥션 생성 방식 미리 만들어진 커넥션 풀에서 "빌려옴" 매번 새로운 커넥션을 "직접 생성"
성능 빠름 (커넥션 재사용) 느림 (생성 비용 큼)
관리 커넥션 풀 관리 기능 (최대/최소 수량, idle 관리 등) 관리 기능 없음
설정 필요성 DataSource 설정 (ex. DBCP, HikariCP) 필요 url/user/pw 만 있으면 됨
실무 사용 99% 실무에서는 DataSource 학습용/간단한 테스트에서는 DriverManager

🔥 왜 이 차이가 중요한 것인고 하면...

  • DriverManager.getConnection()  DB 접속 → 인증 → 세션 생성 이 반복되니까 성능이 느리고, 부하가 크다 > 매번 DB에 직접 접속
  • DataSource.getConnection()  커넥션을 미리 만들어놓고, 필요할 때 꺼내 쓰고, 다 쓰면 풀에 반납(close()) 하는 구조. 접속/인증/세션 생성 비용이 0. ➡️ 매우 빠르고, 서버 부하를 줄여줌.

✅ 그래서 진짜 서비스 환경(실무)에서는 DataSource 방식을 쓴다.

요약

DriverManager 방식 매번 결제해서 보는 콘텐츠. 오리지널 콘텐츠는 구독자전용이라 풀릴때까지 대기해야함.
DataSource 방식 구독서비스 이용 !! 바로바로 볼 수 있고, 대기할 필요도 없다.

실제 코드 비교

(1) DriverManager 방식

String url = "jdbc:postgresql://localhost:5432/mydb";
String user = "username";
String password = "password";

Connection conn = DriverManager.getConnection(url, user, password);

  • 커넥션 매번 새로 만듦 (비효율)

(2) DataSource 방식 (예: PostgreDbcp)

DataSource ds = PostgreDbcp.getDataSource();
Connection conn = ds.getConnection();

 

 

실제 소스에는 우리회사 같은 경우 Oracle / PostgreSQL 이렇게 두 가지 DB를 사용하고 있어서 따로 클래스를 생성해서 관련 메서드를 작성해놓고, 서비스단에서 import 해서 사용하는 식으로 하고 있다.

1. ConnectionDbcp (Oracle용) & PostgreDbcp (PostgreSQL 용) 클래스 생성 및 관련 기본 셋팅
2. 실제 서비스단에서 import 해서 사용

 

순서정리

1. 커넥션 얻기 (PostgreSQL)

// 예시
connPg = PostgreDbcp.getDataSource().getConnection();
connPg.setAutoCommit(false);
  • PostgreDbcp.getDataSource() → DataSource 객체 가져옴 (커넥션 풀)
  • .getConnection() → 커넥션 풀에서 커넥션 하나 빌려옴
  • setAutoCommit(false) → 트랜잭션 수동 관리 모드로 전환

 PostgreSQL 커넥션 준비 완료


2. 커넥션 얻기 (Oracle)

// 예시
ConnectionDbcp connectionDbcp = new ConnectionDbcp();
connOra = connectionDbcp.getConnection();
  • ConnectionDbcp.getConnection() → Oracle용 DataSource에서 커넥션 가져옴.

 Oracle 커넥션 준비 완료

 

3. 커넥션을 가지고 실제 비즈니스 로직 수행

예시) 상품리스트 조회 후 조회된 데이터 처리 로직 수행

  • getGoodsList(conn, ...) → PostgreSQL 커넥션을 넘겨서 조회 작업
  • 조회한 상품데이터를 가지고 반복 처리 시작
  • 반복문(for) 안에서 insert/update 같은 DML 작업을 할 때 conn을 계속 사용
  • 특정 상황에서 에러가 나면 connRollback(conn) 호출 → rollback 처리

4. 모든 작업이 끝나면

DbUtils.closeQuietly(connPg);
DbUtils.closeQuietly(connOra);
  • connPg: PostgreSQL 커넥션을 풀에 반납
  • connOra: Oracle 커넥션도 풀에 반납
  • (DbUtils는 null 체크 + close() 예외 무시하는 유틸.)

✅ 커넥션을 닫는 게 아니라 풀에 다시 반납하는 거다! (== 재사용 가능)


순서도로 그려보면

[1] PostgreSQL DataSource에서 connPg 가져오기
    ↓
[2] conn.setAutoCommit(false) 설정
    ↓
[3] Oracle DataSource에서 connOra 가져오기
    ↓
[4] 조회(getGoodsList)
    ↓
[5] 조회된 데이터(goodsMapList) 반복 처리
       (insert/update 시 conn 사용)
    ↓
[6] 문제 발생 시 connRollback(conn)
    ↓
[7] finally 블록에서 connPg, connOra close (풀에 반납)

 

 

 

주저리..

그동안 운영해온 서비스를 기준으로 공부중인데, PreparedStatement에 대해 확인하다보니, Oracle 커넥션 맺는 쪽이랑 PostgreSQL 커넥션 맺는 쪽의 방식이 조금 다른것이 아닌가 ?!?! 

그래서 ,, 조금 더 찾아보았다.... (다음 편에 계속...)