
| 컴포넌트 | 핵심 역할 | 비고/주의 |
|---|---|---|
| DriverManager | JDBC 드라이버 로딩, DB 연결(Connection) 생성 | Class.forName() 동적 로딩, getConnection() |
| Connection | DB와의 실제 연결, SQL 실행 객체 생성 | createStatement(), prepareStatement() |
| Statement | 완성된 SQL 실행 | 매 실행 시 파싱/컴파일 발생 |
| PreparedStatement | 파라미터 바인딩( ? ) 지원, 재사용 | 빠름·안전(SQL Injection 방어) |
| ResultSet | SELECT 결과 표(테이블) 커서 | next(), getXxx(), 반드시 close() |
// 1) 드라이버 로딩 (동적 로딩)
Class.forName("com.mysql.cj.jdbc.Driver"); // ClassNotFoundException 처리
// 2) 연결 생성
Connection con = DriverManager.getConnection(
"jdbc:mysql://localhost/employee", "ohgiraffers", "ohgiraffers"); // SQLException 처리
jdbc-config.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost/employee
user=ohgiraffers
password=ohgiraffers
로드 & 연결
Properties prop = new Properties();
prop.load(new FileReader("jdbc-config.properties"));
Class.forName(prop.getProperty("driver"));
Connection con = DriverManager.getConnection(
prop.getProperty("url"),
prop.getProperty("user"),
prop.getProperty("password"));
설정을 분리하면 오타/중복/유지보수 비용을 줄일 수 있음.
public class JDBCTemplate {
public static Connection getConnection() {
// properties 로드 & DriverManager.getConnection() ..
return /* con */;
}
public static void close(Connection con) {
try { if (con != null && !con.isClosed()) con.close(); }
catch (SQLException e) { e.printStackTrace(); }
}
}
실무/과제에서는 try-with-resources가 더 깔끔.
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id, last_name FROM emp");
while (rs.next()) {
System.out.println(rs.getString("id") + ", " + rs.getString("last_name"));
}
장점
String sql = "INSERT INTO member (id, password) VALUES (?, ?)";
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
pstmt.setString(1, id); // 1-base index
pstmt.setString(2, password);
int updated = pstmt.executeUpdate(); // DML은 executeUpdate()
}
SELECT 는
executeQuery()/ INSERT·UPDATE·DELETE 는executeUpdate()를 사용.
employee-query.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="selectEmpByFamilyName">
SELECT e.* FROM employee e
WHERE e.emp_name LIKE CONCAT(?, '%')
</entry>
</properties>
로드 & 실행
Properties prop = new Properties();
prop.loadFromXML(new FileInputStream("employee-query.xml"));
String sql = prop.getProperty("selectEmpByFamilyName");
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
pstmt.setString(1, familyName);
try (ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) { /* ... */ }
}
}
next() → 다음 행 존재 시 truegetString("col"), getInt("col") 등 타입별 getXxxclose()while (rs.next()) {
String empId = rs.getString("emp_id");
String empName = rs.getString("emp_name");
System.out.println(empId + ", " + empName);
}
// 1) 드라이버 로딩
Class.forName("com.mysql.cj.jdbc.Driver");
// 2) 연결
try (Connection con = DriverManager.getConnection(url, user, password)) {
// 3) SQL 준비 (Statement or PreparedStatement)
String sql = "UPDATE emp SET last_name = ? WHERE id = ?";
try (PreparedStatement pstmt = con.prepareStatement(sql)) {
// 4) 바인딩 & 실행
pstmt.setString(1, "KIM");
pstmt.setString(2, "10000");
int result = pstmt.executeUpdate();
// 5) 결과 처리 (커밋/로직)
System.out.println("updated rows = " + result);
}
// 6) try-with-resources 덕분에 자동 close
} catch (SQLException e) {
e.printStackTrace();
}
SELECT →
executeQuery()로ResultSet처리
INSERT/UPDATE/DELETE →executeUpdate()로 영향 행 수 처리