JDBC/JDBC 수업

#28. PreparedStatement

열하나요 2023. 8. 9. 10:22

PreparedStatement : Connection객체가 가지고 있는 연결정보 DB에 SQL문을 전달하고 실행하고 결과도 받아오는 객체

 

- Statement(부모)와 PreparedStatement(자식) 관계
 ** PreparedStatement의 특징 : SQL문을 바로 실행하지 않고 잠시 보관하는 개념
  미완성된 SQL문을 먼저 전달하고 실행하기 전에 완성형태로 만든 후 실행만 함
  미완성된 SQL문에 사용자가 입력한 값들이 들어갈 수 있는 공간을
  ?(위치홀더)로 확보
  
- 차이점
 1) Statement는 완성된 SQL문, PreparedStatement는 미완성된 SQL문
 2) 객체 생성 시 Statement == conn.createStatement();
    PreparedStatement == conn.prepareStatement();
 3) SQL문 실행 시 Statement == stmt.executeXXX(sql);
  PreparedStatement == pstmt.executeXXX();
  

보통 Statement는 단일행 SQL을 사용하거나, SELECT ~ FROM 테이블명 을 쓸 때 사용한다.

PreparedStatement는 따옴표가 붙기 때문!


  ?위치홀더를 실제 값으로 채워준 뒤 실행한다.
  pstmt.setString();
  pstmt.setInt();
  
 ** JDBC 처리 순서
 1) JDBC Driver등록 : 해당 DBMS에서 제공하는 클래스 등록
 2) Connection 객체 생성 : 접속하고자 하는 DB의 정보를 입력해서 DB에 접속하면서 생성(url, 계정명, PW)
 3_1) PreparedStatement 객체 생성 : Connection객체를 이용해서 생성(미완성된 SQL문을 담아서)

pstmt = conn.prepareStatement(sql);


 3_2) 현재 미완성된 SQL문을 완성형태로 만들어주기
  => 미완성된 경우에만 해당 / 완성된 경우에는 생략이 가능

pstmt.setString(1, m.getUserId());
pstmt.setString(2, m.getUserPwd());
pstmt.setString(3, m.getUserName());
pstmt.setString(4, m.getGender());
pstmt.setInt(5, m.getAge());
pstmt.setString(6, m.getEmail());
pstmt.setString(7, m.getPhone());
pstmt.setString(8, m.getAddress());
pstmt.setString(9, m.getHobby());

PreparedStatement의 메소드 setXXX()는 (?가 있는 순서, 들어갈 값)을 인자로 갖는데,

들어갈 값은 홑따옴표(')가 양옆에 자동으로 붙는다.


 4) SQL문 실행 : executeXXX() => SQL인자값을 전달하지 않음!! *****절대로!!
  > SELECT : executeQuery()
  > DML : executeUpdate()

result = pstmt.executeUpdate();

(차이 : Statement는 여기서 SQL인자값을 전달했음)
 5) 결과받기 :
  SELECT문의 경우 : ResultSet객체(조회된 데이터들이 담겨있음)로 받기 => 6_1
  DML문의 경우 : int형(처리된 행의 개수)으로 받기 => 6_2
 6_1) ResultSet에 담겨있는 데이터들을 하나씩 뽑아서 VO객체에 담기(행이 많을 경우 ArrayList로 관리)
 6_2) 트랜잭션처리(성공하면 COMMIT, 실패하면 ROLLBACK)
 7) 사용이 끝난 JDBC용 객체들은 반드시 자원 반납(close()) => 생성된 순서의 역순으로
 8) 결과반환(Controller)
  SELECT문의 경우  > 6_1에서 만들어진 결과
  DML문의 경우 > 처리된 행의 개수

 

+

View 에서 화면 조회 처리 시,

각각의 구현된 메소드마다 결과 처리 화면을 조금씩 다르게 하고 싶다면

Controller에서 View에게 인자값으로 결과를 전해주고

if(result > 0) { // 성공했을 경우
			new MemberView().displaySuccess("회원추가 ");
		} else { // 실패했을 경우
			new MemberView().displayFail("회원추가 ");
		}

View에서 매개변수로 받은 값을 응답화면에 나타낸다.

public void displaySuccess(String str) {
		System.out.println("\n서비스 요청 성공!!");
		System.out.println(str + "성공!!!");
	}
	
	public void displayFail(String result) {
		System.out.println("\n서비스 요청 실패 ㅠㅠ..");
		System.out.println(result + "실패...");
	}

이렇게 하면, 각각 메소드마다 성공/실패에 같은 View객체의 메소드를 호출하여 다른 값을 출력할 수 있다.