유디의 공간정보·개발일기

H5-5. 0723_ Prepared Statement로 질의하기, JDBC Test(계속) 본문

JDBC

H5-5. 0723_ Prepared Statement로 질의하기, JDBC Test(계속)

55yudi 2021. 10. 31. 16:10

Prepared Statement

- SQL문은 동일하고 변수의 값만 다른 경우에 사용한다.

  매번 동일한 sql문을 반복적으로 사용해야 할 경우에 유용한 인터페이스이다.

- Connection으로부터 PreparedStatement를 생성한다.

con.prepareStatement(sql)

- 일반 statement보다 효율적이고 처리 속도가 빠르다.

- 수행될 SQL문을 매개변수로 전달하며, 이 때 설정될 값은 ? 로 지정한다.

 

- ? 로 표현된 변수에 값을 binding한다.

- PreparedStatement의 setㅇㅇㅇ(변수순번, 바인딩값) 메서드를 이용한다.

- SQL문을 실행 메서드의 인자로 전달하지 않는다.

- pstmt.executeQuery() : 수행결과를 ResultSet에 담아서 리턴한다.

- pstmt.executeUpdate() : sql문의 영향을 받은 row수를 리턴한다.

- 재실행 시 DBMS에서는 이미 파싱(parsing)된 sql문에 변수만 바인딩해서 사용한다.

 

 

[JDBCExam2]

package myjdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;

public class JDBCExam2 { //Statement - Prepared Statement를 사용해보려고 한다.

	public static void main(String[] args) throws Exception {
		Scanner scan = new Scanner(System.in);
		System.out.println("조회할 이름을 입력하세요.");
		String name = scan.nextLine();
		System.out.println(name);
		//사용자가 아무것도 입력하지 않고 엔터치면 프로그램이 종료되게 하기
		//while문 등으로 반복하기
		EmpDAO2 empDAO = new EmpDAO2();
		while(name != null && name.length() != 0) {
			empDAO.printEmployee(name); //오류: 호출안되는 이유 : Class가 달라서 안불러와진다.
									//--> 객체를 생성해서 호출하면 된다.
			System.out.println("조회할 이름을 입력하세요.");
			name = scan.nextLine();
		}
		System.out.println("프로그램을 종료합니다.");
	}

}

class EmpDAO2 {
	public void printEmployee(String name) throws Exception {
		//이 부분을 작성하시오.
		//전달받은 이름을 활용하여 데이터베이스에서 데이터를 가져와 화면에 출력합니다.
		Class.forName("oracle.jdbc.driver.OracleDriver");
		Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
		//String sql = "select * from employees where first_name = '" + name + "'"; //
		String sql = "select * from employees where first_name = ? "; //preparedstatement만드는중
		//Statement stmt = con.createStatement();
		
		PreparedStatement pstmt = con.prepareStatement(sql);
		//인터페이스					connection안에 있는 메서드
		pstmt.setString(1, name);
		//ResultSet rs = stmt.executeQuery(sql);
		ResultSet rs = pstmt.executeQuery();
		if(rs.next()) { //if문으로 하고 가져올 정보의 열(컬럼) 번호를 가져오거나 이름을 직접 가져와도 된다.
			//String lastName = rs.getString("last_name"); 이렇게도 가능!
			String lastName = rs.getString(3);
			String firstName = rs.getString(2);
			int empId = rs.getInt(1);
			System.out.printf("empId: %d, first_name: %s, last_name: %s\n", empId, firstName, lastName);
		}
//		rs.close();
		con.close(); //커넥션 자체를 종료하는게 더 좋기도 하다.
	}
}

 


[JDBCTest4] & [EmpVO]

package myjdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;

//ArrayList, interface 개념 정립하기

public class JDBCTest4 {

	public static void main(String[] args) throws Exception {
		//사용자에게 출력
		//사용자에게 입력
		//데이터베이스 접속 -쿼리
		int empId = 100;
		//getEmpById 라는 메소드 쓰기
//		EmployeeDAO employeeDAO = new EmployeeDAO(); //1. 클래스를 불러오기
//		employeeDAO.getEmpById(empId);
		EmpVO1 emp = EmployeeDAO.getEmpById(empId);
		System.out.printf("id:%d, first_name:%s", emp.empId, emp.firstName);
	}
}

class EmployeeDAO { //사원과 관련된 데이터를 액세스하려고 한다.
	//'부서번호를 전달받아서 부서원의 정보를 리턴'하는 메서드를 만들려고 한다.
	//이름, 매개변수, 리턴타입, 내부에서 수행할 명령문들을 로직구성
	//이름 : getEmpListByDeptId
	//매개변수 : int deptId (부서번호를 받을거니까)
	//리턴타입 : ArrayList (부서원의 정보가 여러명의 정보이기 때문)
	public static ArrayList<EmpVO1> getEmpListByDeptId(int deptId) {
		//ArrayList는 인터페이스가 아니고, List는 인터페이스라서 List가 적절하다.
		return null;
	}
	
	//사번을 입력받아서 그 사원의 정보를 리턴함.
	//이름, 매개변수, 리턴타입
	//이름 : getEmpById
	//매개변수 : int empId
	//리턴타입 : EmpVO (위에 만들어져있으니까 가져온건가..?)
	public static EmpVO1 getEmpById(int empId) throws Exception { //--> EmpVO class따로 만들어주고 옴 (Car과제랑 비슷한 원리(?))
		EmpVO1 result = new EmpVO1(); //객체 생성해서 result에 넣을거고 마지막에 result를 출력할거임
		Class.forName("oracle.jdbc.driver.OracleDriver");
		Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
		//Connection:인터페이스 --> 인터페이스는 객체화가 안된다. 객체생성을 못함
		System.out.println(con.getClass().getName());
		String sql = "select * from employees where employee_id = ?";
		PreparedStatement stmt = con.prepareStatement(sql);
		stmt.setInt(1, empId);
		ResultSet rs = stmt.executeQuery();
		if(rs.next()) {
			result.empId = rs.getInt("employee_id");
			result.firstName = rs.getString("first_name");
			result.lastName = rs.getString("last_name");
		}
//		String result = rs.getString(3);
//		System.out.println(result);
		//EmpVO객체를 생성한다.
		//DB에서 조회하여 조회된 데이터로 객체변수 설정
		//생성된 객체를 리턴한다.
		
		return result;
	}
	
	
}
//클래스 : 동사형으로 시작, 소문자로 시작
//인터페이스 : 명사형으로 시작, 대문자로 시작

 

package myjdbc;

public class EmpVO1 { //데이터를 담고있는 클래스

	public int empId;
	public String firstName;
	public String lastName;

}

 


클래스

- 동사형, 소문자로 시작

- 예) executeQuery, prepareStatement, getString, getInt 등

 

인터페이스

 - 명사형, 대문자로 시작

 - 예) Connection, Statement, PreparedStatement, ResultSet 등