231 lines
7.5 KiB
Markdown
231 lines
7.5 KiB
Markdown
# **JDBC (Java Database Connectivity) 쉽게 배우기**
|
|
|
|
## **1. JDBC란?**
|
|
JDBC는 **자바에서 데이터베이스와 연결**하여 **SQL을 실행하고 결과를 처리**하는 API이다.
|
|
MySQL, PostgreSQL, Oracle 등 **다양한 DBMS에서 공통적으로 사용**할 수 있음.
|
|
|
|
✔ **주요 기능**
|
|
- 데이터베이스 연결 (`Connection`)
|
|
- SQL 실행 (`Statement`, `PreparedStatement`)
|
|
- 결과 가져오기 (`ResultSet`)
|
|
- 트랜잭션 처리
|
|
|
|
---
|
|
|
|
## **2. 주요 클래스 및 메서드 정리**
|
|
|
|
### **📌 JDBC 연결 관련 클래스**
|
|
| 클래스 | 설명 |
|
|
|--------|------|
|
|
| `DriverManager` | 데이터베이스 연결을 관리하는 클래스 |
|
|
| `Connection` | 데이터베이스와의 연결을 나타내는 객체 |
|
|
|
|
| 메서드 | 설명 |
|
|
|--------|------|
|
|
| `DriverManager.getConnection(url, user, password)` | DB 연결 생성 |
|
|
| `Connection.close()` | DB 연결 종료 |
|
|
| `Connection.setAutoCommit(boolean autoCommit)` | 자동 커밋 설정 |
|
|
| `Connection.commit()` | 트랜잭션 커밋 |
|
|
| `Connection.rollback()` | 트랜잭션 롤백 |
|
|
|
|
---
|
|
|
|
### **📌 SQL 실행 관련 클래스**
|
|
| 클래스 | 설명 |
|
|
|--------|------|
|
|
| `Statement` | SQL 쿼리를 실행하는 객체 (단순 SQL 실행) |
|
|
| `PreparedStatement` | SQL 쿼리를 실행하는 객체 (파라미터 지원) |
|
|
| `CallableStatement` | 저장 프로시저(Stored Procedure) 호출 객체 |
|
|
|
|
| 메서드 | 설명 |
|
|
|--------|------|
|
|
| `Statement.executeQuery(String sql)` | SELECT 실행 후 `ResultSet` 반환 |
|
|
| `Statement.executeUpdate(String sql)` | INSERT, UPDATE, DELETE 실행 |
|
|
| `PreparedStatement.setXXX(int index, value)` | SQL의 `?`에 값 바인딩 |
|
|
| `PreparedStatement.executeQuery()` | SELECT 실행 후 `ResultSet` 반환 |
|
|
| `PreparedStatement.executeUpdate()` | INSERT, UPDATE, DELETE 실행 |
|
|
| `Statement.close()` | Statement 종료 |
|
|
|
|
---
|
|
|
|
### **📌 결과 조회 관련 클래스**
|
|
| 클래스 | 설명 |
|
|
|--------|------|
|
|
| `ResultSet` | SQL 실행 결과를 저장하는 객체 |
|
|
|
|
| 메서드 | 설명 |
|
|
|--------|------|
|
|
| `ResultSet.next()` | 다음 행으로 이동 |
|
|
| `ResultSet.getString("column")` | 문자열 값 가져오기 |
|
|
| `ResultSet.getInt("column")` | 정수 값 가져오기 |
|
|
| `ResultSet.close()` | 결과 집합 종료 |
|
|
|
|
---
|
|
|
|
## **3. JDBC 기본 사용 예제**
|
|
|
|
### **✔ 데이터베이스 연결 및 SELECT 예제**
|
|
아래 코드는 **JDBC를 이용하여 MySQL에 연결하고, 데이터를 조회하는 예제**이다.
|
|
|
|
```java
|
|
import java.sql.*;
|
|
|
|
public class JdbcExample {
|
|
public static void main(String[] args) {
|
|
// 1. DB 연결 정보 설정
|
|
String url = "jdbc:mysql://localhost:3306/mydb";
|
|
String user = "root";
|
|
String password = "1234";
|
|
|
|
// 2. JDBC를 이용한 DB 연결 및 데이터 조회
|
|
try {
|
|
// 3. 데이터베이스 연결
|
|
Connection conn = DriverManager.getConnection(url, user, password);
|
|
System.out.println("DB 연결 성공!");
|
|
|
|
// 4. SQL 실행
|
|
String sql = "SELECT id, name, age FROM users";
|
|
Statement stmt = conn.createStatement();
|
|
ResultSet rs = stmt.executeQuery(sql);
|
|
|
|
// 5. 결과 출력
|
|
while (rs.next()) {
|
|
int id = rs.getInt("id");
|
|
String name = rs.getString("name");
|
|
int age = rs.getInt("age");
|
|
System.out.println("ID: " + id + ", 이름: " + name + ", 나이: " + age);
|
|
}
|
|
|
|
// 6. 리소스 해제
|
|
rs.close();
|
|
stmt.close();
|
|
conn.close();
|
|
|
|
} catch (SQLException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**🔹 실행 결과**
|
|
```
|
|
DB 연결 성공!
|
|
ID: 1, 이름: 홍길동, 나이: 30
|
|
ID: 2, 이름: 이몽룡, 나이: 25
|
|
```
|
|
|
|
✅ `DriverManager.getConnection(url, user, password)`을 이용해 DB 연결
|
|
✅ `Statement.executeQuery(sql)`을 이용해 SELECT 실행
|
|
✅ `ResultSet.getInt()`, `getString()`을 이용해 결과 가져오기
|
|
|
|
---
|
|
|
|
## **4. PreparedStatement 사용 (SQL Injection 방지)**
|
|
|
|
`PreparedStatement`는 **SQL에 `?`를 사용하여 값을 안전하게 전달**할 수 있음.
|
|
**SQL Injection을 방지**하고 **반복 실행 시 성능 최적화** 가능.
|
|
|
|
```java
|
|
import java.sql.*;
|
|
|
|
public class PreparedStatementExample {
|
|
public static void main(String[] args) {
|
|
String url = "jdbc:mysql://localhost:3306/mydb";
|
|
String user = "root";
|
|
String password = "1234";
|
|
|
|
try {
|
|
Connection conn = DriverManager.getConnection(url, user, password);
|
|
|
|
// SQL에 ?를 사용하여 값 바인딩
|
|
String sql = "INSERT INTO users (name, age) VALUES (?, ?)";
|
|
PreparedStatement pstmt = conn.prepareStatement(sql);
|
|
pstmt.setString(1, "김철수"); // 첫 번째 ?에 값 설정
|
|
pstmt.setInt(2, 28); // 두 번째 ?에 값 설정
|
|
|
|
int rows = pstmt.executeUpdate();
|
|
System.out.println(rows + "개의 행이 삽입됨!");
|
|
|
|
pstmt.close();
|
|
conn.close();
|
|
|
|
} catch (SQLException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**🔹 실행 결과**
|
|
```
|
|
1개의 행이 삽입됨!
|
|
```
|
|
|
|
✅ `PreparedStatement.setString(1, "김철수")`로 안전한 데이터 전달
|
|
✅ `executeUpdate()`를 사용하여 INSERT 실행
|
|
|
|
---
|
|
|
|
## **5. 트랜잭션 처리 예제**
|
|
기본적으로 **JDBC는 자동 커밋 모드**이므로, 수동으로 커밋하려면 `setAutoCommit(false)`를 설정해야 함.
|
|
|
|
```java
|
|
import java.sql.*;
|
|
|
|
public class TransactionExample {
|
|
public static void main(String[] args) {
|
|
String url = "jdbc:mysql://localhost:3306/mydb";
|
|
String user = "root";
|
|
String password = "1234";
|
|
|
|
try {
|
|
Connection conn = DriverManager.getConnection(url, user, password);
|
|
conn.setAutoCommit(false); // 자동 커밋 해제
|
|
|
|
// 1. 첫 번째 INSERT 실행
|
|
PreparedStatement pstmt1 = conn.prepareStatement("INSERT INTO users (name, age) VALUES (?, ?)");
|
|
pstmt1.setString(1, "박영희");
|
|
pstmt1.setInt(2, 27);
|
|
pstmt1.executeUpdate();
|
|
|
|
// 2. 일부러 오류 발생시키기 (age 컬럼에 문자 입력)
|
|
PreparedStatement pstmt2 = conn.prepareStatement("INSERT INTO users (name, age) VALUES (?, ?)");
|
|
pstmt2.setString(1, "오류발생");
|
|
pstmt2.setString(2, "문자"); // 오류 발생
|
|
pstmt2.executeUpdate();
|
|
|
|
conn.commit(); // 커밋 (이 코드까지 실행되면 모든 변경이 적용됨)
|
|
|
|
} catch (SQLException e) {
|
|
e.printStackTrace();
|
|
try {
|
|
System.out.println("롤백 실행");
|
|
conn.rollback(); // 오류 발생 시 롤백
|
|
} catch (SQLException rollbackEx) {
|
|
rollbackEx.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
**🔹 실행 결과**
|
|
```
|
|
롤백 실행
|
|
```
|
|
|
|
✅ `setAutoCommit(false)`를 설정하여 수동 커밋 모드로 변경
|
|
✅ `commit()`이 실행되기 전에 오류가 발생하면 `rollback()`으로 변경 사항 취소
|
|
|
|
---
|
|
|
|
## **6. 정리**
|
|
✔ **JDBC는 자바에서 DB와 상호작용하는 API**
|
|
✔ `DriverManager.getConnection()`을 사용하여 DB 연결
|
|
✔ `Statement`와 `PreparedStatement`를 사용하여 SQL 실행
|
|
✔ `ResultSet`을 사용하여 데이터 조회
|
|
✔ **트랜잭션 관리 (`commit()`, `rollback()`)를 활용하여 데이터 정합성 유지**
|
|
|
|
✅ **SQL 실행이 많다면 `PreparedStatement`를 사용하자!**
|
|
✅ **트랜잭션 처리를 위해 `setAutoCommit(false)`를 활용하자!** |