이론을 싫어!

[JDBC] 실제 데이터베이스에서 데이터 꺼내보기!(statement preparedstatement 차이) 본문

JDBC

[JDBC] 실제 데이터베이스에서 데이터 꺼내보기!(statement preparedstatement 차이)

이론을 싫어! 2023. 3. 6. 17:07
반응형

저번 시간에는 단순히 자바와 데이터 베이스 연동 하는 법을 배워봤는데 

 

요번에는 실제로 데이터베이스에 있는 데이터를 꺼내보도록 할게요.

 

시작 하기전 필요한 준비물 !!! ( SQL문법 기초 이해 , 데이터베이스 테이블 생성 및 데이터 저장,) 

테이블 정보

 

그러면 바로 실습을 진행해 보도록 하겠습니다 . 

 

(예시1)(Statement)

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import java.sql.*;
 
public class DBTest {
    public static void main(String[] args)  {
 
        //1. Ip(domain) 2. port  3. 계정 4. 패스워드 5. 인스턴스
 
        String url="jdbc:mariadb://[ip]:[port]/[테이블 명]";
        String dbUserId="[계정]";
        String dbPassword="[패스워드]";
 
        //1. 드라이버 로드
      Connection connection=null;
      Statement statement=null;
      ResultSet rs=null;
 
        try {
            Class.forName("org.mariadb.jdbc.Driver");
        } catch (ClassNotFoundException e) {
           e.printStackTrace();
        }
         //2 . 커넥션 객체 생성
        try {
            connection= DriverManager.getConnection(url,dbUserId,dbPassword);
            //3. 스테이트먼트 객체 생성
            statement=connection.createStatement();
 
            //4. 쿼리 실행
            String sql="select member_type ,user_id ,password ,name  from member" +
                    " where member_type ='email' ";
            rs= statement.executeQuery(sql);
 
             //5.결과 수행
            while(rs.next()){
               String memberType= rs.getString("member_type");
               String userId=rs.getString("user_id");
               String password=rs.getString("password");
               String name=rs.getString("name");
 
                System.out.println(memberType+", "+userId+", "+password+", "+name);
            }
        } catch (SQLException e) {
           e.printStackTrace();
        //6. 객체 연결 해제
    } finally {
            try {
                if(rs!=null &&!rs.isClosed()){
                    rs.close();
                }
                if(statement!=null &&!statement.isClosed()){
                    statement.close();
                }
                if(connection!=null && !connection.isClosed()){
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
 
        }
        }
 }
cs

위의 (예시1)을 보게 되면 기존에 그냥 자바와 데이터베스 연동하는 코드보다 조금 더 길어졌는데 

 

추가된 부분을 좀 설명을 한다고 하면 

 

Statement 는 SQL을 실행시키기 위한 객체라고 합니다 .

 

본인 스스론 SQL문을 해석하지못하기 때문에 전달하는 역할을 합니다.

 

executeQuery는 데이터베이스에 명령을 내는 것입니다. 

 

ResultSet은 결과값을 받아주는 역할을 한다고 생각하시면 됩니다.

 

그리고 사용한 클래스의 객체들은 무조건 닫아줘야합니다.

 

만약에 닫아주지 않게 되면 Connetion 같은 객체들은 고갈이 되면서 에러를 발생하게 됩니다. 

 

즉, 화장실에 가고 싶어도 화장실안에 모든 곳이 사용중이라면 화장실 가고 싶어도 가지 못하는 상황이랑 비슷한 상황이라고 

 

생각하면 됩니다. 

 

그러한 에러 또는 자원이 마르지 않도록 항상 사용이 끝내면 .close() 로 닫아주는 것이 좋습니다.

 

 

 

실행을 하게 되면 테이블의 있는 데이터의 값을 SQL문법을 통해서 원하는 데이터를 꺼내왔다는 것을 알수 있습니다 .

 

 

 

자 여기서 또 다른 하나의 코드를 보도록 하죠 

 

(예시2)(PreparedStatement)

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import java.sql.*;
 
public class DBTestPreparedStatement {
    public static void main(String[] args)  {
 
        //1. Ip(domain) 2. port  3. 계정 4. 패스워드 5. 인스턴스
 
        String url="jdbc:mariadb://[ip]:[port]/[테이블 명]";
        String dbUserId="[계정]";
        String dbPassword="[password]";
 
 
      Connection connection=null;
      PreparedStatement preparedStatement=null;
      ResultSet rs=null;
 
 
        try {
            Class.forName("org.mariadb.jdbc.Driver");
        } catch (ClassNotFoundException e) {
           e.printStackTrace();
        }
 
        try {
            connection= DriverManager.getConnection(url,dbUserId,dbPassword);
 
 
            String sql="select member_type ,user_id ,password ,name  from member" +
                    " where member_type = ?  ";
 
            preparedStatement=connection.prepareStatement(sql);
           preparedStatement.setString(1,"email");
           rs=preparedStatement.executeQuery();
 
            while(rs.next()){
               String memberType= rs.getString("member_type");
               String userId=rs.getString("user_id");
               String password=rs.getString("password");
               String name=rs.getString("name");
 
                System.out.println(memberType+", "+userId+", "+password+", "+name);
            }
        } catch (SQLException e) {
           e.printStackTrace();
 
    } finally {
            try {
                if(rs!=null &&!rs.isClosed()){
                    rs.close();
                }
                if( preparedStatement!=null &&!preparedStatement.isClosed()){
                    preparedStatement.close();
                }
                if(connection!=null && !connection.isClosed()){
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
 
        }
        }
}
cs

 

예시1 과 결과값은 똑같이 나온다. 하지만 

 

예시1번과 차이점이 보이시나요??

 

Statement 클래스가 PreparedStatement 으로 변경 되었다는 것이랑 SQL에 ? 가 들어가있다는 점. 

 

그리고 setString(1,"email"); 추가되었다는 점 

 

 

여기서 statement / preparedstatement 차이점을 좀 알아보면 

 

statement 

- 단일로 사용할 때 속도가 빠르다.

- 쿼리에 인자를 부여할수가 없다.

- 매번 컴파일 해야된다.

 

쿼리문에 파라미터 값을 넣을수 없고 executeQuery(sql) 메소드에 쿼리를 넣고 있어서 실행하기 전까지는 

 

무슨 쿼리를 실행하는지 알수가 없다. 그러다보니 쿼리문을 실행할때마다 새성하며 반복 되는 경우는 속도가 느려질수 밖에 없다.

 

 

Preparedstatement

- 여러번 수행될 때 빠른 속도를 가지고 있다.

- 쿼리에 인자를 부여할 수 있다.

- 처음 컴파일 하고난 뒤에 컴파일을 수행하지 않는다.

 

connection.preparedStatement(sql) 쿼리문을 미리 생성하고 

 

실행할 때도 prepardstatement.executeQuery() 메소드에 파라미터를 넣지 않는것을 볼수 있다.

 

그러다 보니 실행할때 생성하는것이 아닌 미리 생성을 하고 있기떄문에 반복 실행할때 속도가 statement보다 빠르다는 것을 알수있다.