본문 바로가기
멀티캠퍼스 풀스택 과정/데이터베이스

데이터베이스2-1 JDBC로 JAVA와 DB의 연동(SELECT문)

by 이쟝 2022. 1. 19.

JDBC API

- Java DataBase Connectivity의 약자로 JDBC 자바 언어로 데이터베이스 프로그래밍을 하기 위한 라이브러리

- JDBC DBMS에 종속되지 않는 관련 API를 제공한다.

- JDBC API JDK에서 제공하며 JDBC 프로그래밍을 위해서는 JDBC드라이버가 필요하다!

- JDBC 드라이버는 각 DBMS 회사에서 제공하는 라이브러리 압축파일이다.

- 오라클을 사용한다면 오라클용 JDBC 드라이버가 필요하다.

 

자바 - JDBC - DBMS의 구조


JDBC를 이용한 데이터베이스 연동과정

 

 

-> JDBC 구동시 필요한것 : JDBC 드라이버 (jar파일 내장 클래스)

-> JDBC를 사용하려면 저 Driver.class 파일이 필요하다. 'mysql-conector-java-8.0.26.jar' 내의 Driver 경로는 'com.mysql.cj.jdbc.Driver' 이다. 

-> JDBC의 클래스는 java.sql.* 이다.


Java.sql Package 

java.sql.Driver DB와 연결하는 Driver class를 만들 때
반드시 implements 해야하는 interface로 JDBC와 연결되는 Interface 
java.sql.Connection 특정 데이터베이스와 연결정보를 가지는 interface
DriverManager로부터 Connection 객체를 가져온다.
java.sql.Statement SQL query문을 DB에 전송하는 방법을 정의한 interface,  Connection을 통해 가져온다.
java.sql.ResultSet  SELECT 구문 실행 결과를 조회할 수 있는 방법을 정의한 interface
java.sql.PreparedStatement Statement의 하위 interfac,  SQL문을 미리 컴파일 해 실행 속도를 높인다. 

 


데이터베이스 연동과정

 

[데이터베이스 연동하는 작업]

1. JDBC 드라이버 load

-> JDBC 드라이브를 jvm에 객체를 생성하여 등록한다.(데이터베이스 사용할 때마다)

-> DB를 받아오기 위해서 꼭 필요한 작업

 

public class SelectTest {

	public SelectTest() { // 객체 생성할 때 한 번만 실행, 생성자
		
	}
	public void start() {			
        try {  // forName은 ClassNotFoundException 예외를 생성하기 때문에 예외처리를 해주거나 예외생성해야함
            Class.forName("com.mysql.cj.jdbc.Driver");  // 폴더에 들어가서 Driver.class가 있는 파일의 경로를 적기
		} catch (ClassNotFoundException cnfe) {
			System.out.println("드라이브 로딩 실패!!!");
        }
    }    
}

 

2. CONNECTION 객체 생성(DB연결)

-> Connection : DB와 연결해주는 하나의 클래스

-> DB연동해서 DriverManager클래스의 getConnection() 메서드를 호출하면 데이터베이스를 연결해 Connection 객체를 리턴(java.sql  패키지 안에 있음)

-> DriverManager.getConnection( )의 매개변수 (mysql 서버주소, 계정, 비밀번호)

 

Connection conn = null;

String url = "jdbc:mysql://127.0.0.1/demo"; // 서버 IP주소/DB명
conn = DriverManager.getConnection(url, "root", "root1106");

 

3. Statement 객체생성 4. 쿼리문 수행

-> Statement와 PreparedStatement는 SQL 쿼리문을 실행할 수 있는 객체이다. 

 

Statement PreparedStatement
단일로 사용될 때 빠른 속도를 지닌다. 쿼리에 인자를 부여할 수 있다.
쿼리에 인자를 부여할 수 없다. 처음 프리컴파일 된 후, 이후에는 컴파일을 수행하지 않는다. (재사용 가능)
매번 컴파일을 수행해야 한다.(일회용) 여러번 수행될 때 빠른 속도를 지닌다. 

-> 쿼리를 수행할 때 동적으로 할당해야 하는 값이 있으면 PreparedStatement 객체를 사용하고, 동적으로 할당할 필요가 없으면 Statement 객체를 사용한다.

-> 보통 PreparedStatement를 많이 사용!

 

 Connection conn = null;
 PreparedStatement pstmt = null;
 
 String sql = "select empno, ename, hiredate, sal from emp order by ename asc"; 
 // 데이터베이스의 select문 그대로 사용
 // 사원명으로 오름차순한 사원번호, 사원명, 입사일, 급여를 emp테이블에서 선택한다(가져온다.)
 pstmt = conn.prepareStatement(sql);

 

-> String sql이 자바입장에는 그냥 " "문자열 이었던 것을 Connection클래스의 prepareStatement( )를 이용해 select 쿼리문으로 변환되어서 pstmt로 들어가게 된다.

-> prepareStatement( )는 Connection 클래스에 있는 메서드 이고, PreparedStatement는 Statement를 구현한 인터페이스이다. (헷갈리면 안됨!) 

 

 

5. ResultSet 객체로부터 데이터 추출

-> exceuteQuery( ): DB에 명령

-> ResultSet: 명령에 대한 반환값(SELECT의 결과를 저장하는 객체)

->  PreparedStatement의 메서드인 executeQuery( )를 통해 쿼리를 실행하면 ResultSet타입으로 반환을 해주어 결과값을 저장한다. 

-> executeQuery( ) 메서드를 호출해서 ResultSet 객체를 생성하게 되면 rs에 표(테이블) 형식으로 데이터가 들어가게 된다.

-> next( )라는 메서드를 만나면 포인터를 제일 앞에 있는 것부터 순서대로 데이터를 읽어온다.(표형식에서 맨 처음부터 데이터를 읽어온다.)

-> next( )는 읽을 데이터가 없다면 false가 리턴되어 반복문이 끝나게 된다.

 

Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;

rs = pstmt.executeQuery();

// 데이터 삽입(숫자는 String sql에 들어온 순서대로!!)
while(rs.next()) {
	int empno = rs.getInt(1);            // rs.getInt("empo")
	String ename = rs.getString(2);      // rs.getString("ebname")
	String hiredate = rs.getString(3);   // rs.getString("hiredate")
	double sal =  rs.getDouble(4);       // rs.getDouble("sal")
	System.out.printf("%6d %10s %22s %10.2f\n", empno, ename, hiredate, sal);
}

 

-> executeQuery는 SQLException 예외를 생성하기 때문에 try-catch구문으로 예외처리를 해주거나 throws SQLException 해줘야 한다. 

 

try {
	while(rs.next()) {
		int empno = rs.getInt(1);            // rs.getInt("empo")
		String ename = rs.getString(2);      // rs.getString("ebname")
		String hiredate = rs.getString(3);   // rs.getString("hiredate")
		double sal =  rs.getDouble(4);       // rs.getDouble("sal")
		System.out.printf("%6d %10s %22s %10.2f\n", empno, ename, hiredate, sal);
		}
 } catch (SQLException se) { 
 	System.out.println("DB연결 에러 발생...");
			se.printStackTrace();
 }

 

6. ResultSet 객체 Close, PreparedStatement 객체 Close, Connection 객체 Close

 

catch (SQLException se) {
		System.out.println("DB연결 에러 발생...");
		se.printStackTrace();
} finally {
	// 연결종료(마지막에 생성된 것부터 종료)
	try {
		if(rs!=null) { rs.close(); }   
		if(pstmt!=null) { pstmt.close(); }
		if(conn!=null) { conn.close(); }
	}catch(Exception e) {}
}

 

7. 마지막으로  main 메서드에서 이 SelectTest 생성자를 사용해서 start 메서드 호출!

 

public class SelectTest {
	
    public SelectTest( ) {
    }
    
    public void start( ) {
    // DB연동코드
    }
    
    public static void main(String[] args) {
 		new SelectTest().start();
	}
}

 

 

실행하면, 이렇게 자바에 DB가 연동된 것을 확인할 수 있다!!!!

 

<전체코드> 

 

import java.sql.*;

public class SelectTest {

	public SelectTest() { // 객체 생성할 때 한 번만 실행
		
	}
	public void start() {	
		// 데이터베이스 연동하는 작업
		// 1. JDBC 드라이버 load 
		try {   // (forName()를 위한 예외처리)
			Class.forName("com.mysql.cj.jdbc.Driver");  
		} catch (ClassNotFoundException cnfe) {
			System.out.println("드라이브 로딩 실패!!!"); }
		// 변수 생성
		Connection conn = null;          // 2번
		PreparedStatement pstmt = null;  // 3,4번 
		ResultSet rs = null;             // 5번
		
		try {
		// 2. DB연결(Connection 객체 생성)
		String url = "jdbc:mysql://127.0.0.1/demo";
		conn = DriverManager.getConnection(url, "root", "root1106");
		
		// 3,4. 쿼리문 작성, PrepareStatement 객체 생성
		 String sql = "select empno, ename, hiredate, sal from emp order by ename asc";
		 pstmt = conn.prepareStatement(sql);
		 
		// 5. ResultSet 객체로부터 데이터 추출
		rs = pstmt.executeQuery();  // rs에 표형식으로 데이터가 들어가 있다. 
		
		while(rs.next()) {
			int empno = rs.getInt(1);            
			String ename = rs.getString(2);  
			String hiredate = rs.getString(3);
			double sal =  rs.getDouble(4);
			System.out.printf("%6d %10s %22s %10.2f\n", empno, ename, hiredate, sal);
			}
		
		// executeQuery를 위한 예외처리
		} catch (SQLException se) {
			System.out.println("DB연결 에러 발생...");
			se.printStackTrace();
		} finally {
			// 연결종료(마지막에 생성된 것부터 종료)
			try {
				if(rs!=null) { rs.close(); }        // 다음에 들어올 데이터를 위해서
				if(pstmt!=null) { pstmt.close(); }
				if(conn!=null) { conn.close(); }
			}catch(Exception e) {}
		} 
	}
 	public static void main(String[] args) {
 		new SelectTest().start();
	}
}