Statement와 PreparedStatement 비교
Statement와 PreparedStatement 클래스는 Java 애플리케이션에서 데이터베이스에 접근하여 SQL 쿼리를 작성하고 DB에 전달할 때 쓰는 클래스들로 다른 특성을 가지고 있다.
Statement
SQL 쿼리에서 변수를 직접 문자열로 결합하여 사용
String sql = "insert into student values(" + sno + ", '" + name + "', ...);";
st.executeUpdate(sql);
SQL 인젝션 공격에 취약하며, 매번 새롭게 SQL 구문을 컴파일하므로 성능이 떨어질 수 있다.
문자열 결합형식을 취하기 때문에 동적 쿼리 사용시 작성의 불편함이 있다.
PreparedStatement
?로 표기하는 바인딩 변수를 지원하여 쿼리의 복잡성을 줄이고, 보안과 성능을 개선한다.
String sql = "insert into student values(?, ?, ?, ...);";
PreparedStatement pst = cn.prepareStatement(sql);
pst.setInt(1, sno);
pst.setString(2, name);
pst.executeUpdate();
바인딩 변수를 사용하여 매개변수를 설정할 수 있어 가독성이 높아지고 SQL 인젝션 방지가 가능하다.
동일한 쿼리를 반복해서 사용할 때 쿼리를 캐싱하여 컴파일 비용을 절감하므로 성능이 향상된다.
따라서, 보안성과 성능 측면에서 PreparedStatement가 선호되며,
프레임워크에서도 기본적으로 이 방식을 지원하는 경우가 많다.
예시 ) PreparedStatement로 데이터 업데이트하기
public static void updatename(int sno, String name) {
String sql = "update student set name=? where sno=?";
try {
PreparedStatement pst = cn.prepareStatement(sql); // SQL 문을 전달하며 PreparedStatement 객체 생성
pst.setString(1, name); // 첫 번째 ?에 name 값 바인딩
pst.setInt(2, sno); // 두 번째 ?에 sno 값 바인딩
// SQL 실행
if (pst.executeUpdate() > 0) {
System.out.println("업데이트 성공");
} else {
System.out.println("업데이트 실패");
}
} catch (Exception e) {
System.out.println("updatename Exception: " + e.toString());
}
}
SQL 실행 메서드 정리
Statement와 PreparedStatement에는 SQL 구문을 실행하기 위한 메서드가 있다.
executeQuery()
select 구문 실행.
인자로 SQL 문자열을 넣어주면 ResultSet 객체를 반환하여 쿼리 결과를 다룸.
ResultSet rs = st.executeQuery(sql);
executeUpdate()
insert, update, delete 구문 실행.
실행된 행의 개수(int)를 반환하므로, 반환값이 0이면 실행 실패를 의미한다.
int rowsAffected = pst.executeUpdate();
PreparedStatement의 메서드
setString ,setInt ....
SQL 실행 전에 매개변수를 설정.
몇번째 물음표에 인자를 넣을것인지 셋팅.
sql = "update student set name=? where sno=?";
try {
pst=cn.prepareStatement(sql); // 생성하면서 sql문을 먼저 전달함.
pst.setString(1, name);
pst.setInt(2, sno); // 물음표 순서대로 넣을것
}
ResultSet
SQL 쿼리를 통해 조회된 결과는 ResultSet 객체에 저장되며, next() 메서드를 사용해 결과를 한 행씩 읽어들인다.
ResultSet :(결과 집합 : 레코들의 집합)→ 커서로 next 로 순회하여 읽고나면 사라짐 (1회성)
→ 가공또는 프론트단으로 보내기 위해 보관하기.
→역할별로 클래스를 나눠야 하는 구조가 나옴 : MVC모델
ResultSet의 주요 메서드
rs.getInt(columnIndex): 정수형 데이터를 열 순서로 가져옵니다.
rs.getString(columnLabel): 문자열 데이터를 열 이름으로 가져옵니다.
if (rs.next()) {
do {
System.out.print(rs.getInt(1) + " ");
System.out.print(rs.getString("name") + " ");
System.out.print(rs.getInt("age") + " ");
// 필요한 모든 열 출력
} while (rs.next());
} else {
System.out.println("데이터 없음");
}
rs.next()를 사용하여 다음 행으로 이동하며, rs.getString("name") 등의 메서드를 통해 데이터를 가져온다.
ResultSet은 일회성 객체이므로 순회가 끝나면 사라지며,
필요한 경우 데이터를 저장해 프론트엔드에 전달하거나 가공할 수 있다.
rs.getInt(1) // 상수 사용 : 컬럼의 순번 입력
rs.getString("name") // 문자열 사용 : 컬럼의 이름 , 별칭이 있는경우 별칭으로 사용.
'Developer > JAVA' 카테고리의 다른 글
JAVA , JAVA와 데이터베이스 연동을 통한 데이터 처리 (2) | 2024.10.30 |
---|---|
JAVA , 인터페이스 , 인터페이스와 추상클래스의 차이 (1) | 2024.10.28 |
JAVA , Exception의 직접 처리와 위임 처리 , 사용자 정의 Exception (0) | 2024.09.23 |
Java , 예외 처리 Exception , try-catch (0) | 2024.09.22 |
JAVA , 열거형 클래스 enum ! (1) | 2024.09.21 |