이 글의 목적:
MySQL에 대한 스터디를 진행하다 보니 문득 우리가 사용하는 추상화된 기술들 안에서 PreparedStatement가 어떻게 동작하고 있을지 궁금해짐. 그래서 파헤쳐보기로 함
CREATE TABLE car(
car_id BIGINT NOT NULL PRIMARY KEY,
car_brand VARCHAR(20) NOT NULL,
car_name VARCHAR(20) NOT NULL,
car_type VARCHAR(10) NOT NULL
);
public class JdbcApplication {
public static void main(String[] args) {
String jdbcUrl = "jdbc:mysql://";
String id = "";
String password = "";
Connection connection = null;
Statement stmt = null;
ResultSet rs = null;
try {
**connection = DriverManager.getConnection(jdbcUrl, id, password);
// Statement 객체 획득
stmt = connection.createStatement();
// Statement 객체를 이용해 ResultSet 객체 획득
rs = stmt.executeQuery("SELECT * FROM car WHERE car_id = 1");**
while(rs.next()) {
var car = createCar(rs);
System.out.println(car);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
rs.close();
stmt.close();
connection.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}
private static Car createCar(ResultSet rs) throws SQLException {
return new Car(rs.getLong(1), rs.getString(2), rs.getString(3), rs.getString(4));
}
private record Car(
Long id,
String brand,
String name,
String type
) { }
}
Connection connection = null;
// PreparedStatement 인터페이스로 변경
PreparedStatement stmt = null;
ResultSet rs = null;
try {
**connection = DriverManager.getConnection(jdbcUrl + properties, id, password);
// prepareStatement() 메서드 실행
stmt = connection.prepareStatement("SELECT * FROM car WHERE car_id = ?");
// 쿼리에 전달할 파라미터 세팅
stmt.setLong(1, 1L);
rs = stmt.executeQuery();**
while(rs.next()) {
var car = createCar(rs);
System.out.println(car);
}
}
보통 파라미터 바인딩을 하지 않는 정적 쿼리를 사용하는 경우는 많지 않음
SQL Injection을 막기 위해 PreparedStatement를 권장함
JDBC는 이런 인터페이스들을 제공하지만 말 그대로 인터페이스만 제공하고 있기 때문에 이 인터페이스를 구현하는 구현체들에서 해당 스펙들을 구현해줘야 함 (MySQL은 제공함)
이런 스펙들은 JDBC 레이어에서 제공하는가?