티스토리 뷰

Java/JDBC

JDBC 기본코드의 이해

GrapeMilk 2020. 4. 27. 17:45

Goal 

 - JDBC의 구동 절차 및 명령어에 대해 알아본다 (Oracle을 예시로)

 - 실제 코드를 통해 JDBC를 사용해본다.

 

사용자의 요청에 따라 데이터베이스에 쿼리작업을 할 때 JDBC라이브러리를 이용한다.

JDBC는 실제 Oracle 데이터베이스와 연결해주기만 할 뿐 실질적인 기능은 데이터베이스가 갖고 있다.

따라서 JDBC를 통해 데이터베이스와 Java프로젝트를 연결한 뒤 Oracle 데이터베이스 드라이버를 로드해야 사용자가 데이터베이스에 정보를 저장할 수 있는 기반을 마련했다고 할 수 있다.

 

위의 과정이 잘 이해가 안되시는 분들은 (JDBC란?) 포스트를 참고하시기 바랍니다.

 

1. JDBC 구동 절차 및 명령어

1-1 JDBC 드라이버 로드 

 - Class.forName("oracle.jdbc.driver.OracleDriver"); : Class.forName : 오라클 드라이버를 로드하는 메서드. 인자값으로 받는 OracleDriver클래스는 oracle.jdbc.driver 패키지에 있다. forName메서드를 통해 OracleDriver 클래스를 인스턴스화 하는 것이 드라이버 로드이다. 드라이버를 로드하면 해당 인스턴스가 메모리에 잡히게 된다.

( * Class.forName이란? )

 

1-2 Connextion con = DriverManager.getConnextion(...);

 - 드라이버 로드가 완료됐다면 연결 객체를 얻는다.

 

1-3 Statement st= con.createStatement();

 - 연결이 완료 됐다면 실행도구를 생성한다.

 

1-4 ResultSet rs = st.executeQuery(sql);

 - 쿼리를 실행 한 뒤 결과를 rs 변수에 얻는다(패치).

 

1-5 rs.next();

 - rs에 담긴 자료들을 Before of FIle 부터 End of FIle을 가르킬 때 까지 순차적으로 가르키면서 자료를 사용할 준비를 한다.

 - re.next();를 수행 한 이후 가져온 자료(레코드)의 속성값을 get하여 Java 코드에 저장한다.

 ex) String title = rs.getString("title");

 

총 4개의 인스턴스가 생성된다. 각 단계마다 절차가 있기 때문에 각기 다른 데이터 타입의 인스턴스가 생성된다. 

 왜나하면 먼저 드라이버가 로드되어야 연결을할 수 있고, 연결이 되어야 실행도구를 생성하며, 실행도구가 있어야 실행을 하고 결과를 저장할 수 있기 때문이다.

 

2. 코드 동작 시뮬레이션

드라이버 로드 -> 드라이버 인스턴스가 메모리에 올라감 -> 연결 실행 후 연결이 완료되면 객체의 결과를 정상적으로 con 변수에 반환함 -> 연결된 객체를 베이스로하여 Statement st 인스턴스 생성 (st 인스턴스 : 사용자의 쿼리를 수행함) -> st.executeQuery(sql)을 통해 쿼리를 실행하면 서버쪽에서는 결과(레코드) 집합이 만들어지고, 서버에서는 사용자에게 레코드 한줄 씩 반환할 작업을 ResultSet에 담아 완료한다. (결과를 하나씩 반환하기 위해 Before of File부터 End of File까지 결과를 가르키는 커서가 있는데, 레코드를 가르키는 포인터 또는 커서라고 함) -> 즉, ResultSet에 값을 받았다는 것은, 쿼리를 실행한 결과를 전부 가져왔다라는 의미가아닌 한줄씩 결과를 이용할 수 있는 상태가 된 것 -> 그런 하나의 자료를 이용하기 위해서는 빈 그릇을 만들어야 하는데 그 빈그릇을 통해 가져오는 명령문(패치)이 rs.next();이다. -> 자료를 가져온 뒤 rs.getString("title")과 같은 명령어를 통해 Java 코드에 담아서 사용한다.

3. 쿼리 실행하기 실습

3-1 JDBC를 사용할때 필수 코드

Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con = DriverManager.getConnection(url, "newlec", "****");
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(sql);


rs.close();
st.close();
con.close(); //집을 나오면 문을 닫는 것처럼 자원의 반납을 위해 close

3-2 추가적인 코드

 - 어느 서버(url)에 , 어떤 DB에 어떤 사용자가 접근해서 어떤 명령어(sql)를 실행하려는지 정보가 필요함

 - String url = "jdbc:oracle:thin:@localhost:1521/xepdb1"; url에는 내 로컬에 저장된 oracle db정보를 입력

 - String sql = "SELECT * FROM NOTECE"; sql에는 쿼리문을 작성

 - rs.next(); : 가져온 DB정보에서 첫번쨰 레코드부터 rs에 담김. rs에 담긴 값은 컬럼, 속성단위로 데이터를 꺼내옴

 - String name = rs.getString("TITLE"); 속성의 데이터타입에 따라 rs에 담긴 레코드의 정보를 Java 변수에 저장.

 

3-3 실행 코드 

package ex1;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Program {

    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        
        String url = "jdbc:oracle:thin:@localhost:1521/xepdb1";
        String sql = "SELECT * FROM NOTICE";
        Class.forName("oracle.jdbc.driver.OracleDriver");
        Connection con = DriverManager.getConnection(url, "newlec", "zktmxl12");
        Statement st = con.createStatement();
        ResultSet rs = st.executeQuery(sql);
        
        if(rs.next()) {
            String title = rs.getString("TITLE");
            System.out.println(title);
        }

        rs.close();
        st.close();
        con.close(); 
        

    }

}

 

* Data data = rs.getDate();

 - rs 객체는 DB에서 자료를 가져올 때 사용할 수 있는 getter가 존재한다. Data 타입의 객체는 보통 getDate를 통해 가져온다

 

* EOF에러

 - 마지막 행을 가르키고 있다, 즉 가져올 데이터가 없다는의미

Exception in thread "main" java.sql.SQLException: 마지막 행 다음의 결과 집합
at oracle.jdbc.driver.GeneratedScrollableResultSet.getString(GeneratedScrollableResultSet.java:373)
at oracle.jdbc.driver.GeneratedResultSet.getString(GeneratedResultSet.java:594)
at ex1.Program.main(Program.java:21)

 

 

'Java > JDBC' 카테고리의 다른 글

JDBC란?  (0) 2020.04.27
댓글