JDBC
Java 프로그램에서 DB 서버를 접속하여 데이터를 처리하는 기능을 구현하고자 할 때 사용되는 Java 기술
구성: JDBC API / JDBC Driver
JDBC Driver
- 특징: DB 서버마다 달라짐
- 구성: 대부분 인터페이스로 구성 (DB마다 다르게 구현해야 하기 때문)
- 배경: 여러 DB 서버에 알맞게 구현해줘야 하는데, 이 일을 개발자가 직접 하기 어려움
- 해결 방안: 드라이버가 대신해 줌 → 자식 클래스를 만들어 객체를 대신 생성하여 사용할 팩토리 메서드가 모두 정의되어 있음
- 결론: API로 구성된 JAVA와 달리, JDBC는 드라이버가 꼭 필요함
- 사용법 및 주의사항:
- API에서 제공되는 메서드 호출
- 예외처리 필수! → SQLException (try-catch 또는 throws)
- 커넥션 반환 필수: 수행이 끝날 때 close()로 DB와 연결을 끊어야 함 (안 그러면 DB 접속 세션이 소진됨)
- 기본적으로 AUTO COMMIT 됨
JDBC API
- 특징: 공통적임 (모든 DB 서버에 대해)
- 구성: 인터페이스와 클래스
- JDBC 클래스: DriverManager, Date, Time, TimeStamp
JDBC 인터페이스 종류와 각각의 메서드

Connection
: DB와 Java를 연결하는 역할
- createStatement(): Statement 객체 생성 (팩토리 메서드)
- getMetadata()
Statement(정적)
: DB 서버에 SQL을 전달하여 수행
- executeQuery("쿼리문")
- SELECT문만 받음 → ResultSet 객체 리턴 (결과가 있든 없든)
- ex) 회원가입 등 중복 검사할 때 조회 후 결과가 비었는지 확인함
- executeUpdate("쿼리문")
- SELECT문을 제외한 쿼리문
- 쿼리문의 결과: 변화된 행의 수를 정수로 반환
- INSERT: 1 반환 (1개 행 추가했기에)
- DELETE: 삭제된 행의 개수
- UPDATE: 수정된 행의 개수
- DDL: 0
- 리턴된 정수는 주로 UPDATE, DELETE 시 사용함 (추가/삭제된 행의 수를 알기 위해)
PreparedStatement(동적)
: 객체 생성 시 SQL문 등록
- PreparedStatement가 좋을 때: 같은 SQL문을 여러 번 사용하며 데이터만 동적으로 변경할 때
- 동적 파라미터 ?: 숫자, 문자열뿐만 아니라 바이너리 타입도 가능해서 이미지도 가능
- 장점: 속도가 빠름 (미리 SQL문을 해석함), 값을 넣을 때 복잡한 따옴표(') 작성을 안 해도 됨
- Statement가 좋을 때: 다양한 SQL문을 사용하고 데이터가 정적일 때
[코드 비교: Statement VS PreparedStatement]
String name = "꾸";
int age = 12;
// Statement
Statement stmt; // 객체 생성 생략
stmt.executeUpdate("insert into student values ('" + name + "', " + age + ")");
// PreparedStatement
PreparedStatement pstmt = conn.prepareStatement("insert into student values(?, ?)");
pstmt.setString(1, name);
pstmt.setString(2, name);
pstmt.executeUpdate();
ResultSet
: SELECT문 결과를 Set으로 저장
- next()
- 다음 행으로 읽기 위해 포인터를 옮김 → 옮기는 것을 성공 시 true 반환 (while문과 함께 사용)
- 주의: ResultSet이 처음엔 0번째 행을 가리키기에 처음부터 .next()를 붙여서 사용해야 1번째부터 시작할 수 있음
- getXXX()
- 추출할 데이터의 타입명으로 작성 ex) getString(), getInt(), …
- 매개변수: "컬럼명", "별칭"(별칭 지정했을 때는 꼭 별칭으로 적용), 순서에 맞는 숫자
JDBC 객체 생성과 활용
동작 원리
- Connection, Statement, ResultSet은 자바(java.sql)에서 제공하는 인터페이스
- 실제로 코드가 실행될 때는 연결된 DB(MySQL) 드라이버가 제공하는 실제 구현체(자식 클래스)가 다형성에 의해 할당되어 동작함
[인터페이스 → 실제 할당되는 자식 클래스 객체 (MySQL 기준)]
- Connection → com.mysql.cj.jdbc.ConnectionImpl
- Statement → com.mysql.cj.jdbc.StatementImpl
- ResultSet → com.mysql.cj.jdbc.result.ResultSetImpl
[활용 코드]
// 1. DB 연결 (Connection 객체 생성)
Connection conn = DriverManager.getConnection(url, user, passwd);
// 2. 쿼리 실행 도구 준비 (Statement 객체 생성)
Statement stmt = conn.createStatement();
// 3. 쿼리 실행 및 결과 참조 (ResultSet 객체 반환)
String sql = "SELECT ename, job, format(sal, 0) sal, deptno FROM emp";
ResultSet rs = stmt.executeQuery(sql);
// 4. 결과 데이터 순차적 읽기
while (rs.next()) {
System.out.printf(
"%10s %10s %10s원 %10d\n",
rs.getString("ename"),
rs.getString("job"),
rs.getString("sal"),
rs.getInt("deptno")
);
}
ResultSet에 크기나 길이를 구하는 메서드가 없는 이유
자바의 List나 Array와 달리, JDBC의 ResultSet은 데이터의 전체 개수를 미리 알려주지 않음
- 이유: 데이터베이스 서버의 동작 방식과 메모리 효율성
- 동작 원리: DB 서버는 SELECT 문의 결과를 모두 메모리에 쌓아두지 않음 (버퍼링 X) → 한 행씩 순차적으로 읽고 넘기는 스트림 형태의 읽기 전용 방식을 사용함
- ResultSet의 역할: DB 서버에 있는 결과 데이터의 현재 위치를 가리키는 참조자 역할만 수행. 따라서, 결과 데이터들을 모두 가지고 있는 것이 아니기에 전체 길이를 미리 알 수 없는 것.
- 빈 데이터(Empty) 확인 방법: rs.next()를 처음 호출했을 때의 반환값
- 데이터가 없으면 바로 false를 반환하므로, 길이를 몰라도 빈 값인지 확인 가능함
'Java' 카테고리의 다른 글
| [Spring Boot] 조회와 수정의 분리(같이 했을 때 문제점과 리팩토링) (0) | 2026.05.17 |
|---|---|
| [Java] JVM 메모리 구조로 보는 자바의 본질 / 객체지향의 특성별 예시 (0) | 2026.04.06 |
| [Java] 배열 / 2차원 배열 / 가변 배열 (0) | 2026.03.20 |
| [Java] println(char[ ] 배열명)에서 주소 값이 아닌 텍스트가 나오는 이유 (0) | 2026.03.19 |
| [Java] 자바의 원칙 vs 편의성: 철학을 깬 복합 대입 연산자, char 배열 출력과 철학을 지킨 for-each문 (0) | 2026.03.19 |