F-LAB JAVA · 6주차 · Phase 3 · JDBC 표준화의 등장
💾 Part B 시작 — DB 접근의 진화 (6주차의 정점)
이 Unit을 끝내면 다음을 답할 수 있어야 한다.
JDBC 등장 전에는 각 DB 마다 고유 API 가 있어 DB 를 바꾸면 모든 DB 코드를 다시 작성해야 했고, 심하면 DB 의 바이너리 프로토콜을 소켓으로 직접 다뤄야 했는데, 이는 5주차의 OCP 위반 (구체에 강결합) 과 똑같은 문제다.
JDBC 등장 전에는 각 DB 마다 고유 API (Oracle 용, MySQL 용 등) 가 따로 있어, 개발자가 각 DB 의 사용법을 새로 배워야 했다.
데이터베이스를 변경하면 그 DB 에 의존한 모든 코드를 다시 작성 해야 했다.
더 심하게는 DB 의 바이너리 프로토콜을 소켓으로 직접 다뤄야 하는 경우도 있어, 개발자가 DB 프로토콜까지 알아야 하는 지옥이었다.
이는 5주차에서 본 OCP 위반 (구체 클래스에 강하게 결합) 과 똑같은 문제 — 구체적인 DB 에 직접 의존하니 DB 가 바뀌면 코드 전체가 영향을 받는, 추상화의 부재 문제다.
JDBC 없던 시절 = 나라마다 다른 콘센트:
각 DB 고유 API (다른 콘센트):
- 한국: A 타입
- 미국: B 타입
- 유럽: C 타입
- DB 마다 사용법 다름
DB 변경 = 나라 이동:
- 미국 가면 모든 기기 (코드) 바꿈
- 플러그 (API) 전부 교체
- 재작성
직접 프로토콜 = 전선 직접 연결:
- 어댑터 없이 전선을 벽에 직접
- 전압/주파수 직접 맞춤
- 위험, 지옥 (바이너리 프로토콜)
OCP 위반:
- 특정 콘센트에 강결합
- 콘센트 바뀌면 기기 못 씀
해결 (JDBC):
- 만능 어댑터 (표준)
- 다음 Unit
→ JDBC 전 = DB마다 고유 API (강결합, 재작성), 프로토콜 직접 (지옥), OCP 위반.
1. JDBC 등장 전 상황
2. 각 DB 고유 API
3. DB 변경 시 재작성
4. DB 프로토콜 직접 통신
5. 소켓 통신의 어려움
6. Oracle 마이그레이션 고통
7. 5주차 OCP 위반과 닮음
8. 표준 부재의 문제
9. 면접 + 자기 점검
JDBC 등장 전:
DB 접근 표준 없음:
- 각 DB 고유 방식
- 통일 X
- 개발자 부담
고통의 핵심:
1. DB 마다 다른 API
2. DB 변경 = 재작성
3. 프로토콜 직접 (심한 경우)
4. 학습 부담
강한 결합:
애플리케이션:
- 특정 DB 에 강결합
- DB 바뀌면 영향
- 유연성 X
JDBC 전이었다면 (ILIC 가정):
ILIC 102 테이블:
- MySQL 고유 API 로 작성
- 만약 Oracle 변경?
- → 102 테이블 코드 전부 재작성
고객사마다 다른 DB:
- DB 별로 코드 따로
- 유지보수 불가능
→ JDBC 없으면 ILIC 불가능
JDBC 등장 전의 고통은?
답:
1. 표준 부재:
고통:
결합:
부담:
각 DB 고유 API:
Oracle 용 API:
- Oracle 만의 함수/방식
MySQL 용 API:
- MySQL 만의 함수/방식
→ 서로 다름
학습 부담:
DB 마다:
- 새 API 학습
- 다른 사용법
- 다른 예외 처리
→ 개발자 부담 ↑
코드 분산:
여러 DB 지원:
- DB 별 코드
- 중복
- 분기 지옥
각 DB 고유 API (개념)
만약 표준 없었다면:
// Oracle 전용
OracleConnection oc = new OracleConnection(...);
OracleStatement os = oc.createOracleStatement();
// Oracle 만의 방식
// MySQL 전용
MySQLConnection mc = new MySQLConnection(...);
MySQLQuery mq = mc.createMySQLQuery();
// MySQL 만의 방식 (전혀 다름)
→ ILIC 가 두 DB 지원하려면
→ 코드 두 벌 (지옥)
각 DB 마다 고유 API 문제는?
답:
1. 고유 API:
학습 부담:
코드 분산:
분기:
DB 변경 = 재작성:
DB 바꾸면:
- 모든 DB 코드 변경
- 새 API 로 재작성
- 전체 영향
변경 범위:
애플리케이션 전체:
- DB 접근 코드 모두
- 산재
- 누락 위험
재작성 비용:
- 시간 (전체 재작성)
- 버그 위험
- 테스트 재실행
- 학습 (새 DB)
DB 변경 재작성 (개념)
JDBC 없을 때 ILIC 가 MySQL → Oracle:
1. 102 테이블 접근 코드 모두
2. MySQL API → Oracle API
3. 431 API 의 DB 부분 전부
4. 예외 처리 변경
5. 전체 테스트
→ 사실상 재개발
→ 비현실적
JDBC 있으면:
- URL/드라이버만 변경 (다음 Unit)
DB 변경 시 코드 재작성 문제는?
답:
1. 재작성:
범위:
비용:
현실:
DB 프로토콜 직접:
최악의 경우:
- DB 바이너리 프로토콜
- 직접 구현
- 소켓 통신
바이너리 프로토콜:
DB 통신 규약:
- 바이트 단위
- DB 마다 다름
- 복잡한 핸드셰이크
// JDBC 없을 때 (소켓 직접)
Socket socket = new Socket("localhost", 3306);
DataOutputStream out = new DataOutputStream(
socket.getOutputStream());
// MySQL 바이너리 프로토콜 직접 작성
out.writeUTF("Handshake request to MySQL server");
// 바이트 단위로 프로토콜 구현 (지옥)
개발자 부담:
알아야 할 것:
- DB 프로토콜 명세
- 바이트 순서
- 핸드셰이크
- 패킷 구조
→ DB 내부까지
프로토콜 직접 (지옥 가정)
만약 JDBC 없고 소켓 직접:
// ILIC 가 MySQL 통신
Socket socket = new Socket("localhost", 3306);
// 1. MySQL 핸드셰이크 패킷 파싱
// 2. 인증 패킷 작성 (바이트)
// 3. 쿼리 패킷 (바이너리)
// 4. 결과 패킷 파싱
// → 비즈니스 로직 전에 프로토콜 구현
431 API 마다 이걸?
→ 불가능
JDBC:
- 프로토콜은 드라이버가 (다음 Unit)
- 개발자는 SQL 만
DB 프로토콜 직접 통신의 의미는?
답:
1. 프로토콜 직접:
바이너리:
예시:
부담:
소켓 통신:
저수준 네트워크:
- TCP 소켓
- 바이트 스트림
- 직접 읽기/쓰기
어려움:
- 프로토콜 명세 이해
- 바이트 인코딩
- 에러 처리
- 연결 관리
- 버전 호환
비즈니스 무관:
프로토콜 코드:
- 비즈니스 로직 X
- 인프라 코드
- 핵심 가치 X
→ 본질 아닌 곳에 시간
유지보수:
DB 버전 업:
- 프로토콜 변경 가능
- 코드 수정
→ 지속적 부담
소켓 통신 어려움 (가정)
직접 소켓이면 ILIC:
관심사:
- 비즈니스: 배송/예약/운임
- 인프라: DB 프로토콜 (소켓)
소켓 직접:
- 인프라에 시간 낭비
- 비즈니스 집중 X
- 작은 팀(2-3명)엔 치명적
JDBC + JdbcTemplate:
- 인프라 추상화
- 비즈니스 집중 (배송 도메인)
→ 관심사 분리 (5주차)
소켓으로 DB 통신의 어려움은?
답:
1. 소켓 통신:
어려움:
비즈니스 무관:
유지보수:
마이그레이션 고통:
MySQL → Oracle:
- 모든 DB 코드 재작성
- 새 API 학습
- 새 프로토콜 (소켓 시)
재작성 항목:
- 연결 코드
- 쿼리 실행
- 결과 처리
- 예외 처리
- 자원 관리
→ 전부
마이그레이션 위험:
- 누락 (일부 안 바꿈)
- 버그 (새 API 미숙)
- 동작 차이
- 테스트 부담
현실적 불가:
대규모 시스템:
- 마이그레이션 = 재개발
- 비용 폭증
- DB 종속 (lock-in)
→ DB 못 바꿈
Oracle 마이그레이션 (JDBC 없을 때 가정)
ILIC MySQL → Oracle (JDBC 없으면):
1. 102 테이블 연결 코드
- MySQL API → Oracle API
2. 431 API 의 쿼리 실행
- 전부 변경
3. 결과 처리
- Oracle 방식
4. 예외
- Oracle 예외
5. (소켓이면) 프로토콜
- Oracle 프로토콜
→ 수개월 재개발
→ 사실상 불가능
JDBC 있으면:
- 드라이버 + URL 변경
- SQL 일부 (방언) 조정
→ 훨씬 수월 (다음 Unit)
Oracle 마이그레이션의 고통은?
답:
1. 마이그레이션:
항목:
위험:
현실:
5주차 OCP 위반과 닮음:
JDBC 전:
- 구체 DB 에 강결합
- DB 바뀌면 코드 변경
= OCP 위반
OCP 위반 (5주차):
"확장 열림, 변경 닫힘" 위반:
- 구체 의존
- 변경 전파
- 수정 필요
닮은 점:
JDBC 전:
- new OracleConnection() (구체)
- DB 변경 → 코드 변경
5주차 DAO 전:
- new NConnectionMaker() (구체)
- 변경 → 코드 변경
→ 같은 강결합 문제
해결 방향 (동일):
5주차:
- 인터페이스 (ConnectionMaker)
- 추상화
JDBC:
- 표준 API (인터페이스)
- 추상화
→ 추상화로 OCP 달성
// JDBC 전 = OCP 위반 (5주차와 동일 구조)
// ❌ JDBC 전 (구체 강결합, OCP 위반)
public class ShipmentDaoBad {
public void add(Shipment s) {
OracleConnection oc = new OracleConnection(...); // 구체
// Oracle 전용 코드
// DB 변경 → 전부 수정 (OCP 위반)
}
}
// ✓ JDBC (표준 인터페이스, OCP 준수)
public class ShipmentDao {
public void add(Shipment s) throws Exception {
Connection c = DriverManager.getConnection(url); // 인터페이스
// 표준 JDBC (DB 무관)
// DB 변경 → URL 만 (OCP 준수)
}
}
// 5주차 ConnectionMaker 인터페이스 = JDBC 의 Connection 인터페이스
// 같은 추상화 정신
class OracleConnection { OracleConnection(Object o) {} }
class Shipment {}
이 문제와 5주차 OCP 위반의 닮음은?
답:
1. 같은 문제:
OCP 위반:
닮음:
해결:
표준 부재:
공통 규약 없음:
- 각자 방식
- 호환 X
- 파편화
파편화 비용:
- 학습 (DB 마다)
- 코드 중복
- 이식성 X
- 종속 (lock-in)
표준의 가치:
공통 규약:
- 한 번 배우면 모든 DB
- 코드 재사용
- 이식성
- 자유 (교체)
JDBC 등장:
자바 DB 표준:
- 통일 API
- DB 독립
- 다음 Unit (3.2)
표준 부재 vs JDBC (ILIC)
표준 없으면:
- ILIC 가 MySQL 종속
- 고객사 다른 DB → 불가
- 작은 팀 부담
JDBC 표준:
- DB 독립 코드
- 고객사 DB 유연 (5주차 연결)
- 한 번 배운 JDBC 로 모든 DB
- ILIC 의 멀티 DB 가능성
→ 표준이 ILIC 를 가능하게
표준 부재가 주는 문제는?
답:
1. 표준 부재:
파편화:
표준 가치:
JDBC:
| Q | 핵심 답변 |
|---|---|
| JDBC 전 고통? | DB 고유 API, 재작성 |
| 고유 API? | DB 별 다른 방식 |
| DB 변경? | 모든 코드 재작성 |
| 프로토콜 직접? | 바이너리 소켓 |
| 소켓 어려움? | 저수준, 비즈니스 무관 |
| 마이그레이션? | 사실상 재개발 |
| OCP 위반? | 구체 강결합 |
| 표준 부재? | 파편화, 종속 |
| 해결? | 추상화 (JDBC) |
| 5주차 연결? | 인터페이스 정신 |
답:
답:
답:
답:
답:
1. JDBC 전 고통
2. 마이그레이션 불가
3. 5주차 OCP 위반과 동일
이번 Unit에서 JDBC 전 고통을 봤다면, 다음은 JDBC 표준화 효과.
💾 Phase 3 — JDBC 표준화의 등장
✅ Unit 3.1 JDBC 없던 시절의 고통 ← 여기
⏭ Unit 3.2 JDBC의 표준화 효과
⏭ Unit 3.3 JDBC가 해결하지 않는 것
🧪 Part A — 학습 도구와 환경 (9 Unit) ✅
💾 Part B — DB 접근의 진화
Phase 3 — JDBC (1/3 진행)
총: 10/28 Unit
💾 Part B 시작 — DB 접근의 진화