SQL에서 사용자의 입력값을 변수처럼 지정하여 쿼리 실행 시 값만 바꿔가며 재사용할 수 있도록 해주는 개념
성능 개선
SQL 문이 매번 새로 파싱되지 않음
동일한 SQL 구조는 한 번만 파싱해서 공유
→ 파싱 비용 감소 + 캐시 재사용
보안 강화 (SQL Injection 방지)
값이 아닌 변수로 입력받기 때문에 문자열 조작 공격 차단
public void loginCheck() {
String id = t_id.getText(); // 텍스트필드에서 ID 가져오기
String pwd = new String(t_pwd.getPassword()); // 패스워드필드에서 문자열로 변환
//✅여기 주목!
String sql = "SELECT * FROM admin WHERE id=? AND pwd=?"; // ✅ 바인드 변수 사용
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = con.prepareStatement(sql); // con은 DB 연결 객체(Connection)
pstmt.setString(1, id); // 첫 번째 바인드 변수에 ID 설정
pstmt.setString(2, pwd); // 두 번째 바인드 변수에 PWD 설정
rs = pstmt.executeQuery(); // 쿼리 실행
if (rs.next()) {
System.out.println("로그인 성공!");
} else {
System.out.println("로그인 실패!");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (rs != null) rs.close();
if (pstmt != null) pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
구문 | 설명 |
---|---|
? | 바인드 변수 자리 표시자 |
pstmt.setString(1, id) | 첫 번째 ? 자리에 id 삽입 |
pstmt.setString(2, pwd) | 두 번째 ? 자리에 pwd 삽입 |
?
는 SQL 문장 안에 있지만
단순한 "문자열"로 쓰인 게 아니라 "데이터 자리를 나타내는 기호"
이걸 처리하려면 Statement가 아니라 PreparedStatement
가 필요
PreparedStatement
는 ?
자리에 값을 타입에 맞게 바인딩
?
자리에 값을 넣기 위해 쓰는
PreparedStatement
의set...()
메서드
메서드 예시 바인딩 타입 setString()
문자열 setInt()
정수 setDouble()
실수 setDate()
날짜