본문 바로가기
Oracle

2022-11-12 JDBC 정리, 복습하기

by HTT 2022. 11. 12.
1. 드라이버 로딩

 

java.lang패키지의 Class라는 클래스의 forName이라는 메소드를 이용해서 오라클 드라이버의 핵심클래스를 메모리에 로딩

Class.forName("oracle.jdbc.driver.OracleDriver");

 

 

 

2. DB서버에 연결하기

 

=> java.sql패키지의 API를 이용

DriverManeger의 getConnection메소드를 이용해서 DB서버에 연결

 

1) static메소드이므로 클래스 이름으로 엑세스

static {
	Class.forName("oracle.jdbc.driver.OracleDriver");
}


2) throws하고 있는 SQLException은 Exception클래스의 하위 클래스이르모 문법적으로 Exception처리를 해야 한다.

static {  // DBUtil이 시작되는 순간 실행됨
	try {
		Class.forName("oracle.jdbc.driver.OracleDriver");
	} catch(ClassNotFoundException e) {
		e.printStackTrace();
	}
}

 

3) 매개변수

① url : 연결문자열

② user : 사용자계정(scott)
③ password : 패스워드(scott계정의 패스워드:tiger1234)

String url = "jdbc:oracle:thin:@172.30.1.37:1521:xe";
String user = "scott";
String password = "tiger1234";

 

4) 리턴타입
:  java.sql.Connection을 리턴

DriverManager클래스의 getConnection메소드는 DB서버에 연결하고 연결정보를 객체로 만들어서 리턴

Connection con = DriverManager.getConnection(url, user, password);

 

 

 

3. SQL문 실행 기능이 제공되는 객체를 생성

 

Connection객체에 정의되어 있는 preparedStatement메소드를 이용해서 생성

 

- sql문을 미리 파싱하는 방법이므로 Connection객체의 preparedStatement메소드를 이용해서 PreparedStatement객체를 만들 때 sql문을 전달해야 한다.

PreparedStatement ptmt = con.preparedStatement(sql);

 

- sql문을 작성할 때도 외부에서 입력 받아 처리할 부분은 ?로 대체하여 표시한 후 작업한다. ?에 대한 값을 셋팅해준다.

setXXX메소드는 타입과 연결해서 알맞은 setter메소드를 선택해서 작업(ResultSet의 getter메소드와 타입매칭은 동일)

ptmt.setString(1, "jang")
ptmt.setInt(2, 1000)

 

- 공통된 코드 추출해서 메소드로 만들어 작성하기

public class DBUtil {
	//1. 드라이버 로딩
	static {  // DBUtil이 시작되는 순간 실행됨
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
		} catch(ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
	// 2. DB서버 연결 - DB서버에 연결하고 커넥션객체를 리턴
	public static Connection getConnect() {
		Connection con = null;
		String url = "jdbc:oracle:thin:@172.30.1.37:1521:xe";
		String user = "scott";
		String password = "tiger1234";
		try {  //getConnection메소드를 예외처리 해줘야 함
			con = DriverManager.getConnection(url, user, password);
		}catch(SQLException e) {
			e.printStackTrace();
		}
		return con;
	}

====>

Connection con = DBUtil.getConnect();

 

 

---------------------------------------- 지금까지 정리한 내용 순서대로 작성하기 --------------------------------------

public class  test{
	public int test{
		String sql = "실행할 SQL문";
		Connection con = null;
		PreparedStatement ptmt = null;
		try {
			con = DBUtil.getConnect();      // 1. 드라이버 로딩
			ptmt = con.prepareStatement(sql);   //2. DB서버와 연결
			ptmt.setString(1, id);          //3. 값 세팅하기
			ptmt.setString(2, pass);
			ptmt.setString(3, "jang")
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

 

 

 

4. SQL문 실행하기

 

PreparedStatement를 사용. Statement메소드와 동일하게 동작하지만 PreparedStatement는 매개변수가 없다.

 

① executeUpdate

- insert, delete, update 명령문을 실행
- 매개변수에 전달된 sql문이 실행됨
- 실행결과로 몇 개의 row가 반영되었는지 리턴
  => int result = stmt.executeUpdate(sql)
        -------------
          ㄴ> 몇 개의 행이 삽입, 수정, 삭제되었는지 리턴   

      ex) if(result > 0) { sysout~~ } else { sysout~~ }
                     
② executeQuery

- select명령문을 실행
- 실행한 후 조회된 테이블을 리턴, DBMS에서 조회된 테이블을 자바에서 사용하기 위해서 만들어놓은 객체가 ResultSet이다.
- 실제로는 어떤 DBMS가 사용되었는지에 따라서 다른 ResultSet객체(ResultSet의 하위)가 리턴

ptmt.executeUpdate();
ptmt.executeQuery();
// 매개변수X

 

 

 

5. 결과처리

 

1) insert, delete, update
- 모두 int를 리턴하므로 동일한 방법으로 처리
ex) int result = stmt.executeUpdate(sql)  
        
2) select

- ResultSet 이용

- sql-plus프로그램을 이용해서 select sql문을 실행할 때 결과로 보여지는 2차원 표의 데이터를 자바에서 사용할 수 있도록 만들어 놓은 객체가 ResultSet이다.

- select문을 실행하면 ResultSet을 리턴하므로 ResultSet타입의 변수를 선언해서 결과를 참조

ResultSet rs = stmt.ececuteQuery(sql문)
ResultSet rs = ptmt.executeQuery()  <- PreparedStatement는 변수X

 

- ResultSet에 있는 테이블의 데이터를 읽기 위해 ResultSet이 제공하는 메소드를 이용해서 작업
Cursor를 다음 레코드로 이동하면서 레코드 갯수만큼 반복작업을 수행
ResultSet객체의 next()메소드를 이용하여 다음레코드로 커서를 이동. next()는 커서를 이동했을 때 레코드가 존재하면 true를 리턴하고 없으면 false를 리턴

while(rs.nest()) {  ---> true/false를 리턴하므로 반복문 중 while문을 이용하여 작업
   	
    // 레코드의 각 컬럼을 읽는다.
}
if(rs.next()){ //레코드 조회
	System.out.print("성공");
			
	}else {
		System.out.println("실패");
    }
}

 

- 한 번에 하나의 컬럼만 읽을 수 있다.
ResultSet객체의 getXXX메소드를 이용하여 컬럼값을 읽는다. 타입에 따라 다른 메소드를 이용한다.

 

① 오라클타입이 varchar2나 char인 경우 : java의 String
getString(컬럼명) or getString(컬럼순서 index) 

 

② 오라클 타입이 number : java의 int
getInt(컬럼명) or getInt(컬럼순서 index)

 

③ 오라클 타입이 date : java의 Date
getDate(컬럼명) or getDate(컬럼순서 index)

while(rs.next()) {  -> 커서를 하나씩 다음레코드로 이동해라
	//  조회된 레코드 갯수만큼 반복해서 작업
  	 	
	sysout(rs.getString("name")) -> name이라는 컬럼명으로 정의된 컬럼을 조회
	sysout(rs.getString(3)) -> 조회된 테이블의 3번째 컬럼을 조회
 			
}

 

 

 

6. 자원반납

 

-  클라이언트가 점유해서 사용하던 자원을 반납해야 한다.
-  Connection, Statement, ResulrtSet까지 모든 자원을 반납
-  close메소드를 이용해서 처리
-  만들어진 순서가 아니라 제일 마지막에 생서된 객체부터 반납한다.

public static void close(ResultSet rs, Statement stmt, Connection con) {
	try {
		if(rs!=null)rs.close();
		if(stmt!=null)stmt.close();
		if(con!=null)con.close();
	} catch (SQLException e) {
		e.printStackTrace();
	}
}

 

 

---------------------------------------- 지금까지 정리한 내용 순서대로 작성하기 --------------------------------------

public ArrayList<CustomerDTO2> search(String job) { // 3. 직업으로 사원 검색
	String sql = "select * from emp where job = 'ANALYST'";
	ArrayList<CustomerDTO2> userlist = new ArrayList<CustomerDTO2>();
	CustomerDTO2 user = null;
	Connection con = null;
	PreparedStatement ptmt = null;
	ResultSet rs = null;
	try {
		con = DBUtil.getConnect();
		ptmt = con.prepareStatement(sql);
		rs = ptmt.executeQuery();
		System.out.println("조회된 ResultSet객체 : " + rs);
		while (rs.next()) {
			System.out.print(rs.getString("job") + "\t");
			user = new CustomerDTO2(rs.getInt(1), rs.getString(2), rs.getString(3), rs.getInt(4), rs.getDate(5),
					rs.getInt(6), rs.getInt(7), rs.getInt(8));
				userlist.add(user);
		}
		System.out.println("리스트 사이즈 : " + userlist.size());
	} catch (SQLException e) {
		e.printStackTrace();
	} finally {
		DBUtil.close(rs, ptmt, con);
	}
	return userlist;
}

 

=> try문 안에 변수를 정의하면 멤버변수가 되기 때문에 밖에서 null로 초기화를 해준다.

sql문이 select처리를 하므로 CustomerDTO2타입을 리턴한다. CustomerDTO2타입 변수 user에 ResultSet으로 조회된 정보들을 순서대로 담고 CustomerDTO2타입의 ArrayList에 넣어 리턴해준다.

 

댓글