sun cloud

전 글에 이어서 jdbc 설계 방식에 대해 알아보겠습니다.

SELECT INSERT, DELETE , UPDATE
1. JDBC Driver loading 1. JDBC Driver loading
2. Connection 2. Connection
3. PreparedStatement 3. PreparedStatement
4. SQL 실행 : executeQuery() 4. SQL 실행 : executeUpdate()
5. ResultSet 5. close
6. close  

전 글에서 첫 공통 단계인 JDBC Driver loading에 대해 알아봤습니다.
이번에는 두번째 공통 단계인 Connection에 대해 알아보겠습니다.

image

Driver인터페이스와 마찬가지로 Connection인터페이스 역시 java.sql패키지에 포함되어 있습니다.

Connection은 특정 데이터베이스와 연결 정보를 가집니다. DriverManager로부터 Connection객체를 가져오는데 메소드는 다음과 같습니다.
DriverManager.getConnection(url, “user” , “pass”);
해당 메소드로 Connection객체를 가져오고 Connection 클래스의 참조변수를 만들어서 객체를 저장하면 연결 정보를 사용할 수 있게 됩니다. 그리고 JDBC Connection은 기본적으로 쿼리 전송 시 자동 커밋이 이루어집니다.
(매번 드라이버를 로딩하고, 커넥션 객체를 생성해서 받아오고 종료하는 과정이 비효율적일수 있기에 커넥션풀(DBCP)을 사용한다고도 하는데 이에 대한 내용은 추후 다뤄보도록 하겠습니다.)

1
Connection con = DriverManager.getConnection(url,"scott","tiger");


sun cloud


image

세번째 공통 단계인 PreparedStatement에 대해 알아보겠습니다. Statement인터페이스를 상속하며 미리 컴파일된 SQL구문을 나타냅니다. Statement인터페이스는 SQL query문을 DB에 전송하는 방법을 정의한 인터페이스로 Connection을 통해 가져오게 됩니다.PreparedStatement의 객체에는 미리 컴파일된 SQL구문이 저장되는데 여러 번 사용되는 경우 효과적으로 사용할 수 있습니다. CreateStatement와 비교되기도 하는데 보안성과 성능의 이유로 대체로PreparedStatement를 사용한다고 합니다. 전자의 경우 보안이 취약해 sql injection에 걸리기 쉽습니다.

해당 객체를 생성할 때에는 먼저 SQL 구문을 정의하고, 변경이 필요한 경우 치환문자(?)를 이용해 쿼리 전송 전에 값을 설정합니다. 아래의 예제는 Update하는 예제인데 SALARY 값을 변경하고 WHERE조건문으로 ID값을 지정해서 해당 영역에서만 변경할 수 있도록 제한합니다. 2번, 3번라인을 보시면 첫번째 인자값이 변경할 값이고 두번째 인자값이 변경이 필요한 행의ID값입니다.

1
2
3
PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES SET SALARY = ? WHERE ID = ?");
pstmt.setBigDecimal(1, 153833.00);
pstmt.setInt(2, 110592);


sun cloud


네번째 단계에서는 약간의 차이를 보입니다. SQL을 실행하는데 Select의 경우 executeQuery()를 사용하고 그 외 Insert, Update, Delete의 경우 executeUpdate()메서드를 사용합니다. 가장 큰 차이점은 결과값을 반환해야 하는 Select만이 executeQuery()를 사용한다는 것입니다. 다른 구문 모두 반환값을 받을 수 있지만 Query 실행 후 반영된 record개수만을 반환받습니다. 그렇기 때문에 다음 단계에서 Select를 사용하는 경우 결과값을 ResultSet 타입으로 반환받은 후 사용한 자원들을 닫아주고 그 외에는 바로 사용한 자원들을 닫아주며 마칩니다.

ResultSet인터페이스는 SELECT 구문 실행 결과를 조회할 수 있는 방법을 정의한 인터페이스입니다. ResultSet 객체는 커서를 최근 데이터 열의 위에 위치하도록 상태를 유지합니다. 하지만 처음에는 커서가 첫번째 열이 아닌 그 위에 위치해 있기 때문에 next메서드를 사용해서 커서가 첫번째 열에 위치하도록 커서를 아래로 이동시켜줍니다. 결과가 여러 개일 경우 while문을 사용하고 결과가 한 개일 경우 if문을 사용합니다.

1
2
3
4
5
6
7
8
9
10
rs : ResultSet
//1. while문 사용
while(rs.next()) { // Cursor를 한 행씩 내립니다.
String str = rs.getString(1); // 그 행의 특정 Column의 값을 가져옵니다.
int i = rs.getInt(field_name); // Column 값을 가져옵니다.
}
//2. if문 사용
if(rs.next()) {
String str = rs.getString(1);
}


sun cloud


아래에는 member 테이블이 존재한다고 가정했을 때 데이터를 조회하는 예제입니다. 지금까지 배운 설계방식을 사용해서 코드를 작성하도록 하겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestJDBC1 {
	public static void main(String[] args) {
		String driver="oracle.jdbc.OracleDriver";
		try {
			//oracle jdbc 드라이버 로딩
			Class.forName(driver);
			System.out.println("jdbc driver loading");

			//oracle database와 연결
			String url="jdbc:oracle:thin:@127.0.0.1:1521:xe";
			Connection con=DriverManager.getConnection(url,"scott","tiger");
			System.out.println("oracle db와 connection :"+con);

            //sql구문 작성
			String sql="select id,password,name,address from member";
            //sql문을 미리 컴파일해서 실행 속도를 높임. 보안성도 뛰어남
			PreparedStatement pstmt=con.prepareStatement(sql);
            //sql 실행. select 결과를 Result 타입 참조변수 rs에 저장
			ResultSet rs=pstmt.executeQuery();
			while(rs.next()) { // 조회 결과 행이 존재하면 true 한 행씩 결과 출력
				// sql문에서 세팅한 순서대로 rs에 저장된 각 컬럼의 데이터를 가져옴
                System.out.println(rs.getString(1)+" "+rs.getString(2)+" "+rs.getString(3)+" "+rs.getString(4));
			}
            //사용한 자원을 닫아줌
			rs.close();
			pstmt.close();
			con.close();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

Database 카테고리 내 다른 글 보러가기

댓글남기기