Java/Theory

[Java/Theory]23. JDBC

양승길 2016. 5. 31. 13:19

23. JDBC

    DB의 SQL을 자바와 연결해 주는것을 표준화 한 체계

    각 RDBMS(Vendor)마다, 다형성이 입각된 체계로서, DB와 연결하는 것.

    JDBC 내부에는 Java진영(java.sql.*)과 RDBMS를 연결해주는 Driver(Vendor)들이 있다.

    이 Driver는 Vendor마다 존재하며, JRE가 따로 설정된 classpath를 통해 Driver(jar)를 연결한다.

    JRE는 ByteCode의 Query문을 이용하여 JDBC를 통해 DB에 있는 내용을 가져온다.


  * JDBC의 절차

      1. DBMS접근 : Connection(interface)으로 Objcet Modeling. (ID, PASSWORD, URL을 Encapsulation)

      2. Query    : Statement(interface)으로 Objcet Modeling. (DML, DCL, Query를 Encapsulation)

      3. View     : ResultSet(interface)으로 Object Modeling. (Query의 결과를 Encalsulation)


  * 세부적 절차

      java.sql에 있는 Connection, Statemant, ResultSet은 Interface로 구성되어 있다.

      이들의 Method는 바로 사용 할수 없으나 RDBMS의 Driver를 이용하여 사용 할 수 있다.

      먼저 Driver의 경로에 맞게 Classpath를 설정한다.


     

      방법 1. RDBMS의 Driver를 import하여 해당 RDBMS의 Driver Instance를 생성한다.

              다형성을 입각하여, SQL API들이 Driver Instance를 참조하게 한다.


      방법 2. java.lang에 있는 Class라는 Class에 forName이라는 Static Method가 있다.

              이 Method의 역할은 Argument를 이용하여 관련된 Class나 Interface가 메모리에 적재된다.

              적재된 Class를 적용하면 방법1의 과정없이 SQL의 API를 이용할 수 있다.

              => Programming based on interface


              Ex : 

1
2
3
4
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection connect = DriverManager.getConnection(url, user, pwd);
Statment stmt = connect.createStatement();
ResultSet rs = stmt.executeQuery("select * from ~~");
cs


      DB 작업이 종료되면 관련 변수들은 모두 close()시킨다.

 

  * Method

      - Statement

        execute(String sql)

        SQL종류를 모를경우


        executeQuery(String sql)

        실행 결과를 받기 위한 Method. ResultSet형태로 반환된다.        


        executeUpdate(String sql)

        해당 Query를 수행하는데, DML의 경우 수정된 행만큼 반환된다.

        DDL같은 경우 0으로 반환된다.


  * Statement VS PreparedStatement

      Statement : 모든게 완성된 일반 Query

                  Query를 실행하는 시점에 매번 Compile

                  PreparedStatement보다 상대적으로 느림


      PreparedStatement : 변수처럼 변경될 데이터 부분은 ?로 처리

                          ?로 처리된 부분을 제외한 Query가 미리 Compile되어 실행 효율을 높인다.

                          setInt, setString으로 해당 ?의 Index와 값을 대입하여 처리한다.

                          Single Quotation과 Double Quotation의 혼란을 덜어준다.


      CollableStatement : 다른 Statement와 유사하나 PL/SQL에 확장되어 DB에 종속적인 개발을 하게된다.

                          


  * TCL(Transaction Control Language)

      특정 Query를 진행하는 도중 예기치 못한 상황이 발생되어 중단되면, 그만큼의 손실이 발생된다.

      이 Query는 원자성을 유지해야 되기 때문에 commit, rollback으로 통제하도록 한다.

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
try {
    // registering Oracle driver class
    Class.forName("oracle.jdbc.driver.OracleDriver");
 
    // getting connection
    con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl",
                                        "ankit""Oracle123");
    System.out.println("Connection established successfully!");
 
    con.setAutoCommit(false); //Now, transactions won't be committed automatically.
    stmt = con.createStatement();
 
    //Execute first update statement - update salary of employee with id=1
    stmt.executeUpdate("UPDATE EMPLOYEE set salary=14000 where id=1 ");
 
    //Let's say first update statement was executed successfully.
    //Execute second update statement - update salary of employee with id=2
    stmt.executeUpdate("UPDATE EMPLOYEE set salary=15000 where id=2 ");
 
    /*
        IF ANY THING GOES WRONG IN EXECUTING SECOND UPDATE, control will go to
        catch block, rollback() method will be called and any changes done
        by first update statement will be rolled back.
    */         
    System.out.println("Salary of both employees was updated successfully");
 
    con.commit(); //commit all the transactions
 
catch (Exception e) {
    e.printStackTrace();
    try {
        con.rollback(); //In case of Exception, rollback all the transactions
        System.out.println("Salary of employees wasn't updated, rollback done");
    } catch (SQLException e1) {
        e1.printStackTrace();
    }
finally {
    try {
        if(stmt!=null) stmt.close(); //close Statement
        
        if(con!=null) con.close(); // close connection
    
    } catch (SQLException e) {
        e.printStackTrace();
    }
}
cs