카테고리 없음

JAVA에서 Oracle DB 연동 및 사용 하는법

WOOOOJI 2023. 1. 13. 22:17

How to connect Oracle DB with JAVA?

오늘은 자바랑 오라클 데이터베이스를 연결하여 실제로 DB에 데이터를

INSERT, SELECT, DELETE, UPDATE 를 해보는 코드를 짜보도록 하겠습니다!


계획 ⇒

  1. 서점 데이터베이스를 쿼리문을 이용해 구축한다 (ONLY TABLE)
  2. 자바에서 DB를 연결하기 위한 ORACLE JDBC를 다운받는다.
  3. 자바에서 DB를 연결시켜주는 API를 찾아서 정리해놓는다 ⇒ Class, Connection, PreparedStatement, ResultSet
  4. 사전에 준비한 테이블을 참고하여 자바에서 쿼리문을 실행할 수 있게 만든다.

코딩 순서 ⇒

  1. DB를 연결시키기 위한 클래스를 생성한다.
  2. 사전에 필요한 변수들을 미리 선언해놓는다. (단 접근제한자는 protected로)
  3. INSERT, DELETE, UPDATE, SELECT 문을 실행하는 클래스를 각각 나눠서 생성한다.
  4. 각각의 클래스가 DB연결 클래스를 상속받는다 ( 코드 중복 최소화 )
  5. 각각의 클래스들이 서로 엉키지 않게 한번에 하나의 클래스를 완성하고 나서 다음 클래스를 만든다.
  6. try catch문을 미리 사전에 생성을 해서 작성하는 메소드 내용을 포함시킨다.
  7. 모든 클래스가 완성되면, 메인메소드가 있는 DEFAULT 클래스를 생성한다.
  8. INSERT, DELETE, UPDATE, SELECT
  9. 클래스의 객체를 생성하여 접근을 하고 메소드를 호출하여 실행한다.

일단 JDBC와 Bulid Path 는 설정을 다 했다고 치고 꼭 필요한 코드 작성부터 시작하겠습니다 🙂

  1. DBConnection (DB와 JAVA를 연결시켜주는 클래스 생성)
package book_table;

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

public class DBConnection {   // DB를 자바에 연결시키기 위한 클래스 DBConnection
	
	protected Connection conn = null;
	protected PreparedStatement statement = null;
	protected ResultSet select = null;
	
	String query = null;
	String url = "jdbc:oracle:thin:@localhost:1521:xe"; 
	String username = "scott";
	String password = "tiger";
	
	
	// 필요한 변수에 대해서 미리 선언을 하고 넘어갑니다.
	/*
	 * 일단 첫번째,
	 * Connection 클래스 객체 생성 : JDBC를 활용하여 JAVA와 DB를 연결시켜줍니다.
	 * 
	 * 두번쨰,
	 * 쿼리문 작성시 데이터를 객체로 담아서 전달해주는 역할을 하는 PreaparedStatement 클래스 객체 생성
	 * 
	 * 세번째,
	 * SELECT절을 쓰기 위해서 필요한 ResultSet 클래스 객체 생성;
	 * 
	 * 모든 변수값은 null로 초기화를 시켜놓고 쿼리문 실행 클래스를 만들때 가져다가 쓸수 있게
	 * 만들어놓습니다.
	 * 
	 */
	
	

	//1, 2. JDBC 드라이버를 CLASS로 만들어서 사용할 수 있게 해주는 CLASS API를 사용하여 생성을 합니다.
	//      Connection 클래스를 이용하여 생성한 객체로 DriverManager 메소드를 이용하여 DB와 연결을 시도합니다.
	// 	    앞에서 만든 url, username, password을 이용하여 접근이 가능합니다.
	public void DBstart() {
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			conn = DriverManager.getConnection(url, username, password);
		} catch (ClassNotFoundException e) {
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	
	
	// 
	public void DBstop() {   // 만약 쿼리문을 정상적으로 다 실행을 했다면 사용하였던 클래스 객체들을 close 해줍니다.
		try {
			if(select != null) {
				select.close();
			}
			if(statement != null) {
				statement.close();
			}
			if(conn != null) {
				conn.close();
			}
			
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	
	
	
	

}

DBstart 메소드 안에 바로 앞에 Class.forname( )을 통하여 드라이버를 로딩해줍니다. 무엇보다 제일 먼저 실행이 되야 하기 때문입니다. 구현할 때 해당 경로에서 드라이버를 찾지 못하는 예외 발생을 대비해 try catch문을 사용합니다.

여기서 유의깊게 봐야하는 것은 바로

Connection 클래스

PreparedStatement 클래스

ResultSet 클래스

입니다.

Connection :

DriverManager.getConnection() 를 Connection 객체를 통해 호출하고 getConnection() 의 매개변수로

연결하고자 하는 DB의 url, user, password를 선언합니다.

그렇게 되면 DB와 JAVA의 연결을 구축하는 시스템은 끝입니다.


PreparedStatement :

데이터베이스 관리 시스템(DBMS)에서 동일하거나 비슷한 쿼리문을 높은 효율성으로 반복적으로 실행하기 위해 사용되는 기능을 말합니다.

보통 Statement 와 PreparedStatement 두개를 사용을 하는데,

Statement를 사용하면 매번 쿼리를 수행할 때마다 4단계를 거치게 되고(계속 단계를 거치면서 수행)

PreparedStatement는 처음 한 번만 세 단계를 거친 후 캐시에 담아 재사용을 한다는 것이다. 만약 동일한 쿼리를 반복적으로 수행한다면 PreparedStatment가 DB에 훨씬 적은 부하를 주며, 성능도 좋습니다.

그래서 저는 PreparedStatement 를 사용하였습니다.

실행할 SQL문을 변수에 저장하고 이를 PreparedStatement의 메서드를 통해 실행한다. 이때 SQL문이 SELECT⇒ executeQuery()

INSERT, UPDATE, DELETE 등 DCL 문이면

executeUpdate() 를 사용합니다.


ResultSet :

PreparedStatement를 사용하여 SQL문 실행시 출력되는 데이터베이스 결과 값을 나타내는 테이블

.next() 와 같은 메소드를 이용하여 객체에 담긴 데이터를 차례대로 가져올 수 있습니다.

한마디로 SELECT 문의 역할을 하는것이죠.


INSERT 클래스 구현 ⇒

package book_table;

import java.sql.SQLException;
import java.util.Scanner;

public class InsertBookInfo extends DBConnection {

	public InsertBookInfo() {
		// TODO Auto-generated constructor stub
	}
	
	
	public void insertInfo() {
		Scanner sc = new Scanner(System.in);
		//1. DB연결하기.
		DBstart();
		
		//2. 데이터 입력받기.
		System.out.println("===== 추가하실 데이터를 입력해주세요 =====");
		System.out.println("== 나중에 입력하실 데이터는 ENTER를 눌러주세요");
		System.out.println();
		
		System.out.print("책 고유코드 : ");
		int isbn=sc.nextInt();
		System.out.println();
		
		sc.nextLine();
		
		System.out.print("책 이름 : ");
		String book_name =sc.nextLine();
		System.out.println();
		
		System.out.print("정가 : ");
		int price = sc.nextInt();       // 각 컬럼에 해당되는 자료형 타입의 변수에 입력받은 데이터를 저장합니다.
		System.out.println();
		
		sc.nextLine();
		
		System.out.print("장르 : ");
		String genre = sc.nextLine();
		System.out.println();
		
		System.out.print("출판일 : ");
		String first_pub = sc.nextLine();
		System.out.println();
		
		System.out.println("총 페이지 수 : ");
		int pages = sc.nextInt();
		System.out.println();
		
		System.out.print("작가 코드 : ");
		int author_code = sc.nextInt();
		System.out.println();
		
		System.out.print("출판사 코드 : ");
		int pub_code = sc.nextInt();
		System.out.println();
		
		
		
		query = "INSERT INTO book_tbl(isbn,book_name,price,genre,first_pub, pages, author_code, pub_code) values(?,?,?,?,?,?,?,?)";
		try {     // INSERT INTO 쿼리문을 작성하여 데이터를 넣을 컬럼을 선택합니다.
			statement = conn.prepareStatement(query);
							// PreparedStatement 객체를 생성하여 connection 객체를 통하여 쿼리문을 입력 받고 실행시킵니다.
			statement.setInt(1, isbn);
			statement.setString(2, book_name);
			statement.setInt(3, price);
			statement.setString(4, genre);    // 여기서 숫자는 위에 작성한 쿼리문의 테이블 컬럼 순서대로입니다.
			statement.setString(5, first_pub);
			statement.setInt(6, pages);
			statement.setInt(7, author_code);
			statement.setInt(8, pub_code);
			
			
			int result = statement.executeUpdate();  // preparedStatement 객체는 성공하면 입력한 열만큼 숫자가 표현됩니        
			if(result>0) {                           // 만약 실패헀다면 -1을 반환합니다.
				System.out.println("정상적으로 등록되었습니다.");
			}else {
				System.out.println("등록이 실패하였습니다. 데이터를 확인해주세요.");
			}
			
			
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			DBstop();     // 실행이 끝났다면 무조건 DB연결도 끝내줍니다.
		}
		
		
	}

}

DELETE 클래스 구현 ⇒

package book_table;

import java.sql.SQLException;
import java.util.Scanner;

public class DeleteBookInfo extends DBConnection{

	public DeleteBookInfo() {
		// TODO Auto-generated constructor stub
	}
	
	public void Delete() {
		DBstart();
		
		Scanner sc = new Scanner(System.in);
		
		try {
			System.out.println("삭제하실 책 고유코드를 입력해주세요 : ");
			int isbn = sc.nextInt();
			
			query = "DELETE FROM book_tbl WHERE isbn=?";
			statement = conn.prepareStatement(query);
			
			
			
			statement.setInt(1, isbn);
			
			int result = statement.executeUpdate();
			if(result>0) {
				System.out.println("정상적으로 삭제 되었습니다.");
			}else {
				System.out.println("책 고유코드가 잘못입력되었습니다.");
			}
			
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			DBstop();
		}
		
		
		
	}
}

UPDATE 클래스 구현 ⇒

package book_table;

import java.util.Scanner;

public class UpdateBookInfo extends DBConnection {

	public UpdateBookInfo() {
		// TODO Auto-generated constructor stub
	}

	public void Update() {
		DBstart();
		Scanner sc = new Scanner(System.in);
		
		SelectBookInfo book = new SelectBookInfo();  // 수정하기 편하게 현제 테이블의 데이터 목록을 보여줍니다.
		book.select();
		
		try {
		System.out.print("수정할 책 고유 코드를 입력해주세요 : ");
		int isbn = sc.nextInt();
		System.out.println();
		
		sc.nextLine();
			
		System.out.print("수정할 이름을 입력해주세요 : ");
		String book_name = sc.nextLine();
		System.out.println();
		
		System.out.print("수정할 가격을 입력해주세요 : ");
		int price = sc.nextInt();
		System.out.println();
		
		query = "UPDATE book_tbl SET book_name=?, price=? WHERE isbn=?";
		statement = conn.prepareStatement(query);
		
		statement.setString(1, book_name);
		statement.setInt(2, price);
		statement.setInt(3, isbn);
		
		int result = statement.executeUpdate();
		if(result>0) {
			System.out.println("정상적으로 수정되었습니다.");
		}else {
			System.out.println("수정실패 : 데이터를 확인해주세요.");
		}
			
			
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			DBstop();	
		}
	}
	
}

SELECT 클래스 구현 ⇒

package book_table;

import java.sql.SQLException;

public class SelectBookInfo extends DBConnection{

	public SelectBookInfo() {
		// TODO Auto-generated constructor stub
	}
	
	String a = "책 고유코드";
	String b = "책 이름";
	String c = "가격";
	String d = "장르";    // 출력문에 컬럼명을 표시하기 위한 변수들.
	String e = "출판일";
	String f = "총 페이지";
	String g = "작가 코드";
	String h = "출판사 코드";
	String i = "등록일";
	
	
	
	public void select() {
		DBstart();
		
		
		try {
			query = "SELECT isbn, book_name, price, genre, TO_CHAR(first_pub,'YYYY-MM-DD'), pages, author_code, pub_code, TO_CHAR(writedate,'YYYY-MM-DD') FROM book_tbl";
			statement = conn.prepareStatement(query);
			
			select = statement.executeQuery();
			
			while(select.next()) {
				int isbn=select.getInt(1);
				String book_name = select.getString(2);
				int price = select.getInt(3);
				String genre = select.getString(4);
				String first_pub = select.getString(5);
				int pages = select.getInt(6);
				int author_code = select.getInt(7);
				int pub_code = select.getInt(8);
				String writedate = select.getString(9);
				
				System.out.printf("%15s %15s %15s %15s %15s %15s %15s %15s %15s \\n",a,b,c,d,e,f,g,h,i);
				System.out.printf("%14d %18s %16d원 %12s %17s %14d %17d %15d %23s \\n",isbn,book_name,price,genre,first_pub,pages,author_code, pub_code, writedate);
				System.out.println();
			}
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {	
			DBstop();
		}
		
	}

}

Main Method for Working

import java.util.Scanner;

import book_table.DeleteBookInfo;
import book_table.InsertBookInfo;
import book_table.SelectBookInfo;
import book_table.UpdateBookInfo;

public class BookMain {

	public BookMain() {
		
	}
	
	public static void StartDB_Book() {
		Scanner sc = new Scanner(System.in);
		
		while(true) {
			System.out.println();
			System.out.println("== 안녕하세요 교보문고 DB 시스템입니다 ==");
			System.out.println("==        1. 책 목록 확인하기      ==");
			System.out.println("==        2. 책 정보 수정하기      ==");
			System.out.println("==        3. 책 정보 추가하기      ==");
			System.out.println("==        4. 책 정보 삭제하기      ==");
			System.out.println("==        5.    종료 하기         ==");
			System.out.println();
			
			int menuNum = sc.nextInt();
			
			switch(menuNum) {. // 메뉴 생성을 하고 switch case문으로 접근

			case 1:
				SelectBookInfo s = new SelectBookInfo();
				s.select();
				break;
			case 2:
				UpdateBookInfo u = new UpdateBookInfo();
				u.Update();
				break;
			case 3:
				InsertBookInfo i = new InsertBookInfo();  // 각각의 항목에 맞게 객체 생성 및 메소드 호출
				i.insertInfo();
				break;
			case 4:
				DeleteBookInfo d = new DeleteBookInfo();
				d.Delete();
				break;
			case 5:
				System.out.println("!    교보문고 DB 시스템을 종료합니다   !");
				System.exit(0);
				
			default :
				System.out.println("==   메뉴 번호를 다시 입력하세요   ==");
				break;
			}
			
		}
	}
	

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		StartDB_Book();                        //실제로 실행을 하는 메인 메소드 영역

		
	}

}

실행결과 : (사진이 삭제 됬네요 ㅠ...)

실행해본 결과 모든 쿼리문이 이상없이 잘 작동하고 있습니다.

위에 테이블에 있는 데이터들은 자바에서 INSERT 한 것입니다 🙂

다만 좀 아쉬웠던건 SELECT 문을 콘솔에서 좀 예쁘게 나타내고 싶었는데 자바에서는 가운데정렬이 없다는 사실을

뒤늦게 알고 난후 어떻게든 시도를 해봤지만 각각의 문자열의 길이가 다르다보니 해결하지 못하였습니다…

다음번에는 콘솔에서도 정갈된 모습으로 출력할 수 있게 연구해서 돌아오겠습니다 ! ㅠ…..

728x90