티스토리 뷰
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)
- 20200421
- 20200330
- 20200413
- chapter8
- 20200503
- 20200415
- chapter7
- 20200804
- 생활코딩리눅스
- 백준
- 20200428
- 20200510
- 20200502
- 20200624
- 20200622
- 20200512
- 20200504
- 20200427
- 20200317
- likelion
- 20201204
- 20200417
- 20200403
- 20200424
- 20200406
- 20200425
- 20200423
- 20200420
- 20200429
- 20200319
- Total
- Today
- Yesterday