JDBC 프로그램 (JAVA를 이용하여 DBMS에 접속해 SQL 명령을 전달하여 실행하기 위한 기능)

woom·2022년 11월 1일
0

JDBC

목록 보기
1/4
post-thumbnail

🌼 JDBC (Java Database Connectivity)

  • JAVA를 이용하여 DBMS에 접속해 SQL 명령을 전달하여 실행하기 위한 기능의 클래스 또는 인터페이스

    • 자바가 DB에 접근하는 프로그램을 시도할 때 DBMS의 종류가 다양하고(ORACLE, MYSQL 등) 구조와 특징이 다르다는 문제점을 해결하기 위해 모든 DBMS에서 공통적으로 사용할 수 있는 인터페이스와 클래스로 구성하는 JDBC를 개발하게 되었고,
      실제 구현은 DBMS의 벤더에게 구현하도록 했다.
  • java.sql 패키지 : JDBC 기능을 제공하는 (클래스) 또는 인터페이스가 선언된 패키지

    • JDBC 기능은 대부분 인터페이스로 제공 (DBMS의 종류가 다양하므로 클래스로 제공 불가능)
    • DBMS 회사의 웹사이트에서 JDBC 기능의 클래스(Driver)를 배포하여 제공
    • JDBC 드라이버가 포함된 라이브러리를 다운로드 받아 프로젝트에 빌드 처리해야만 JDBC 프로그램 작성 가능
  • JDBC 구조

    • 응용프로그램에서 SQL문 작성하여 JDBC 인테페이스의 추상메소드를 통해 전송하면 실제 구현 클래스인 드라이버에 있는 클래스가 DBMS에 메소드 전송, DBMS에서 실행

📌 JDBC 실행 환경설정

  • Oralce DBMS를 사용한 JDBC 프로그램 작성을 위한 환경설정
  1. ORACLE JDBC DRIVER 관련 라이브러리 파일 다운로드

    • https://www.oracle.com 사이트 접속 → PRODUCT → Hardware And Software → Oracle Database → 좌측 Application development→ JAVA → JDBC DOWNLOAD → Oracle JDBC driver → ojdbc11.jar, ucp11.jar (CONNECTION POOL할때 사용 예정) 다운로드
    • Oracle JDBC Driver 관련 라이브러리 파일 : ojdbc11.jar - JDK 버전 참조
  2. Oracle JDBC Driver 관련 라이브러리 파일(ojdbc11.jar)을 프로젝트의 폴더에 붙여넣기

    • 프로젝트 안에 파일 생성 : 프로젝트 → new → folder → name 작성 후 finish
  3. 프로젝트의 폴더에 저장된 라이브러리 파일(라이브러리의 클래스(인터페이스))을 프로젝트에서 사용할 수 있도록 연결 - 빌드(Build) 처리

    • 프로젝트(마우스 오른쪽 버튼) → Properties(속성) → java build path(메뉴) → libraries 탭(클릭) → classpath → Add JARs... → 프로젝트의 jar 파일 선택 → Apply And Close → Referenced Libraries 생성됨 (라이브러리로 클래스 사용 가능)

💡 메소드 호출 과정

  1. ClassLoader 프로그램에 의해 클래스(Class 파일)를 읽어 메모리(Method 영역)에 저장 - 자동(1번)

  2. new 연산자가 메모리에 저장된 클래스 (Class 객체 - Clazz) 의 생성자 (Constructor)를 호출하여 객체(Object - Instance) 생성

    • Heap 영역의 메모리에 객체 생성
  3. 생성된 객체의 메모리 주소(HashCode)를 전달받아 참조변수(Stack 영역)를 생성하여 저장

    • ex. StaticBlock sb=new StaticBlock();
  4. 참조변수에 저장된 객체를 참조하여 메소드 호출 - 기능 구현

    • ex. sb.display();
  • 정적영역(Static Block) : 클래스가 메모리에 저장된 후 자동 실행될 명령을 작성하는 영역
    → 정적영역에 작성된 명령은 프로그램에서 한번만 실행

💡 Class 객체를 수동으로 제공받는 방법

  1. Class.forName(String className) 메소드를 호출하는 방법
    • Class.forName(String className) : 문자열로 표현된 패키지가 포함된 클래스를 전달받아 ClassLoader 프로그램을 사용하여 해당 위치의 클래스를 읽어 메모리에 저장한 후 Class 객체를 반환하는 메소드 - 수동(1번)
    • ClassNotFoundException 발생 (일반 예외이므로 반드시 예외처리해야만 에러 미발생)
    • ex. Class.forName("xyz.itwill.jdbc.StaticBlock");
      → staticblock 클래스 정적 영역에서 객체가 만들어져 메소드 호출
      → 객체를 하나만 만들어 (불필요한 작업을 최소화)
  1. Object.getClass() 메소드를 호출하는 방법 (현재 사용하는 클래스에 대한 Class 객체 반환)

  2. [클래스명.class] 형식으로 표현하는 방법


📌 용어정리

  • JDBC Driver : DriverManager 클래스에 등록된 다수의 Driver 객체(오라클, mysql 등)

  • Driver 객체 : DBMS 서버에 접속하여 SQL명령을 전달하기 위한 기능을 제공하는 객체

  • DriverManager 클래스 : Driver 객체를 관리하기 위한 기능을 제공하는 클래스

  • Connection 객체 : DBMS 서버에 접속된 정보를 저장하기 위한 객체

  • URL(Uniform Resource Locator) : 인터넷에 존재하는 자원의 위치를 표현하는 주소
  • Statement 객체 : SQL 명령을 접속 DBMS 서버에 전달하여 실행하기 위한 객체
  • ResultSet 객체 : 검색결과를 테이블 형식(2차원 배열)의 객체로 저장하여 표현한 객체

🌼 JDBC 프로그램 작성 방법


(1). OracleDriver 클래스를 객체로 생성하여 DriverManager 클래스의 JDBC Driver 객체로 등록

  • 접속 URL 주소의 프로토콜을 이용하여 특정 DBMS 서버에 접속하여 SQL 명령 전달
  • DriverManager.registerDriver(Driver driver) : Driver 객체를 전달받아 DriverManager 클래스가 관리할 수 있는 JDBC Driver로 등록하는 메소드 (sqldeveloper 만드는 것과 똑같아)
    • 동일한 Driver 객체가 DriverManager 클래스에 등록 가능 (불필요한 객체 존재)
  • ex. DriverManager.registerDriver(new OracleDriver());
    → 권장하지 않음

📙 1. Class.forName

1. Class.forName(String className) 메소드 호출

  • ClassLoader 프로그램을 수동으로 실행하여 OracleDriver 클래스를 읽어 메모리에 저장하면 OracleDriver 클래스의 정적영역에서 OracleDriver 클래스로 객체를 생성

  • DriverManager 클래스의 registerDriver() 메소드를 호출하여 OracleDriver 객체를 JDBC Driver로 등록 처리

    • 프로그램에서 한번만 실행
  		 Class.forName("oracle.jdbc.driver.OracleDriver");
   
   
   
   

📙 2. Connection 객체

  1. DriverManager 클래스에 등록된 JDBC Driver 객체를 이용하여 DBMS 서버에 접속하여 Connection 객체를 반환받아 저장

    • Connection 객체 : DBMS 서버에 접속된 정보를 저장하기 위한 객체
  • DriverManager.getConnection(String url, String username, String password)

    • DriverManager 클래스에 등록된 JDBC Driver 객체를 사용하여 DBMS 서버에 접속하는 메소드 (메소드 호출해서 서버에 접속)
  • 접속된 DBMS 서버의 정보가 저장된 Connection 객체 반환

    • 접속 URL 주소의 프로토콜을 이용하여 특정 DBMS 서버에 접속하여 SQL 명령 전달
    • URL(Uniform Resource Locator) : 인터넷에 존재하는 자원의 위치를 표현하는 주소
  • oracle DBMS 서버에 접속하여 데이터베이스를 사용하기 위한 URL주소

    • 형식) jdbc : oracle : thin : @ServerName : Port : SID
      (jdbc : 메인 프로토콜 / oracle:thin : 서브 프로토콜 / thin : 간단하게 접속하겠다 )
      (@ServerName : 서버 이름 없으면 IP주소 localhost는 내컴퓨터)
      (SID : 데이터베이스 식별자는 xe)
    • ex. String url="jdbc:oracle:thin:@localhost:1521:xe";
  • JDBC 관련 클래스의 메소드를 호출하면 반드시 SQLExeption 발생
    • SQLExeption : DBMS 서버 관련 문제(SQL 명령)가 있는 경우 발생되는 예외
    • SQLExeption은 일반 예외이므로 반드시 예외처리를 해야만 에러 미발생
			String url="jdbc:oracle:thin:@localhost:1521:xe";
			String username="scott";
			String password="tiger";
			con=DriverManager.getConnection(url, username, password);





📙 3. Statement 객체

  1. Connection 객체로부터 SQL 명령을 전달 할 수 있는 Statement 객체를 반환받아 저장
  • Connection.createStatement( ) : SQL 명령을 전달할 수 있는 Statement 객체를 생성하여 반환하는 메소드
    • Statement 객체 : SQL 명령을 접속 DBMS 서버에 전달하여 실행하기 위한 객체
			stmt=con.createStatement();





📙 4. SQL 명령을 전달

  1. Statement 객체를 이용하여 SQL 명령을 전달하여 실행하고 실행결과를 반환받아 저장
  • Statement.executeUpdate(String sql) : DML 명령 또는 DDL명령을 전달하여 실행하기 위한 메소드
    • 실행결과로 조작행의 갯수를 정수값(int)으로 반환
  • Statement.executeQuery(String sql) : SELECT 명령을 전달하여 실행하기 위한 메소드
    • 실행결과로 검색행이 저장된 ResultSet 객체 반환
    • ResultSet 객체 : 검색결과를 테이블 형식의 객체로 저장하여 표현한 객체
    • ResultSet 객체에 저장된 검색행을 행단위로 처리하기 위해 내부적인 커서 제공
      → ResultSet 커서는 최초 BOF(Before Of File) 영역에 위치
    • ResultSet.next() : ResultSet 커서를 다음행으로 이동하는 메소드 - boolean
      → false 반환 : ResultSet 커서 위치에 처리행이 없는 경우의 반환값 - EOF
      → true 반환 : ResultSet 커서 위치에 처리행이 있는 경우의 반환값
    • ResultSet.getXXX(int Index) 또는 ResultSet.getXXX(String Label)
      → ResultSet 커서가 위치한 처리행의 컬럼값을 반환하는 메소드

	String sql="insert into student values(3000,'홍','735-2130','인천','12-11')";
	int rows=stmt.executeUpdate(sql);
	ResultSet rs=stmt.executeQuery(sql);



📙 5. SQL 명령 출력

  1. 반환받은 SQL 명령의 실행결과를 이용하여 출력 (sysout)
    • JDBC 기능을 메소드로 작성할 경우 실행에 대한 결과값 반환

📙 6. Close

  1. JDBC 관련 객체의 close( ) 메소드를 호출하여 객체 제거
  • JDBC 관련 객체 생성의 반대 순서로 제거
  • Statement.close() : Statement 객체 제거
  • Connection.close() : Connection 객체 제거 (DBMS 서버 접속 종료)



🐣 예제1 - INSERT



public class InsertStudentApp {
	public static void main(String[] args) {
		//JDBC 관련 객체를 저장하기 위한 참조변수는 try 영역 외부에서 선언
		// => try 영역을 포함한 모든 영역에서 참조변수를 이용해 객체 사용 가능
		Connection con=null;
		Statement stmt=null;
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			//1. OracleDriver 클래스로 객체를 생성
            
			String url="jdbc:oracle:thin:@localhost:1521:xe";
            //oracle DBMS 서버 주소
			String username="scott";
			String password="tiger";
			con=DriverManager.getConnection(url, username, password);
			//2. JDBC Driver 객체를 사용하여 DBMS 서버에 접속
            
            //3. SQL 명령을 전달할 수 있는 Statement 객체를 생성
			stmt=con.createStatement();
			
            //4. SQL 명령을 전달하여 실행
			String sql="insert into student values(3000,'전우치','017-8741-2130',
            '인천시 상당구','1998-12-11')";
			int rows=stmt.executeUpdate(sql);
			
            //5. SQL 명령의 실행결과 출력
			System.out.println("[메세지]"+rows+"명의 학생정보를 삽입 하였습니다.");
		} catch (ClassNotFoundException e) { 
			System.out.println("[에러]OracleDriver 클래스를 찾을 수 없습니다.");
		} catch (SQLException e) {
			System.out.println("[에러]JDBC 관련 오류 = "+e.getMessage());
		} finally {//예외와 상관없이 무조건 실행될 명령을 작성하는 영역
			//6.JDBC 관련 객체의 close() 메소드를 호출하여 객체 제거
			try {
				//if 구문을 이용하여 참조변수에 객체가 저장되어 있는 경우에만 close() 
				//메소드 호출 - NullPointerExcetion 발생 방지
				//NullPointerExcetion : 참조변수에 null이 저장된 상태에서 메소드를
                //호출한 경우 발생되는 예외
				if(stmt!=null) stmt.close();//Statement.close() : Statement 객체 제거
				//Connection.close() : Connection 객체 제거 - DBMS 서버 접속 종료
				if(con!=null) con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}		
		
	}
}





🐣 예제2 - UPDATE



//STUDENT 테이블에 저장된 학생정보 중 학번이 [2000]인 학생의 이름을 [임걱정]으로 변경하고
//주소를 [부천시 원미구]로 변경하는 JDBC 프로그램 작성
public class UpdateStudentApp {
	public static void main(String[] args) {
		Connection con=null;
		Statement stmt=null;
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			String url="jdbc:oracle:thin:@localhost:1521:xe";
			String username="scott";
			String password="tiger";
			con=DriverManager.getConnection(url, username, password);
			
			stmt=con.createStatement();
			
			String sql="update student set name='임걱정',address='부천시 원미구'
            where no=2000";
			int rows=stmt.executeUpdate(sql);
			
			System.out.println("[메세지]"+rows+"명의 학생정보를 변경 하였습니다.");
		} catch (ClassNotFoundException e) {
			System.out.println("[에러]OracleDriver 클래스를 찾을 수 없습니다.");
		} catch (SQLException e) {
			System.out.println("[에러]JDBC 관련 오류 = "+e.getMessage());
		} finally {
			try {
				if(stmt!=null) stmt.close();
				if(con!=null) con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}







🐣 예제3 - SELECT1


//STUDENT 테이블에 저장된 모든 학생정보를 검색하여 출력하는 JDBC 프로그램 작성	
public class SelectStudentApp {	
	public static void main(String[] args) {
		Connection con=null;
		Statement stmt=null;
		ResultSet rs=null;
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			String url="jdbc:oracle:thin:@localhost:1521:xe";
			String username="scott";
			String password="tiger";
			con=DriverManager.getConnection(url, username, password);
			
			stmt=con.createStatement();
			
			String sql="select * from student order by no";
			//Statement.executeQuery(String sql) : SELECT 명령을 실행하기 위한 메소드
			// → SELECT 명령의 실행결과를 ResultSet 객체로 반환
			//ResultSet 객체 : 검색결과를 테이블 형식의 객체로 저장하여 표현한 객체
			rs=stmt.executeQuery(sql);
			
			//ResultSet 객체에 저장된 검색행을 행단위로 처리하기 위해 내부적인 커서 제공
			// → ResultSet 커서는 최초 BOF(Before Of File) 영역에 위치
			//ResultSet.next() : ResultSet 커서를 다음행으로 이동하는 메소드 - boolean
			// → false 반환 : ResultSet 커서 위치에 처리행이 없는 경우의 반환값 - EOF
			// => true 반환 :ResultSet 커서 위치에 처리행이 있는 경우의 반환값
			if(rs.next()) {//ResultSet 커서를 다음행으로 이동하여 처리행이 존재하는 경우
				//System.out.println("[메세지]검색된 학생정보가 있습니다.");
				
				//검색된 다수의 학생정보를 저장한 ResultSet 객체를 처리하기 위한 반복문
				// → ResultSet 객체에 저장된 학생정보의 갯수가 불확실하므로 while 반복문 사용
				//첫 행 처리 후 ResultSet 커서를 다음행으로 이동하기 위해 do~while 반복문 사용
				do {
					//ResultSet 커서가 위치한 처리행의 컬럼값을 반환받아 저장
					//ResultSet.getX(int Index) 또는 ResultSet.getX(String Label)
					// → ResultSet 커서가 위치한 처리행의 컬럼값을 반환하는 메소드
					// → X는 컬럼값을 반환받기 위한 Java 자료형을 표현
					// → columnIndex : 검색대상의 첨자(1부터 1씩 증가)로  컬럼값 표현
					// → columnLabel : 검색대상의 이름(컬럼명 또는 별칭)으로  컬럼값 표현
					//int no=rs.getInt(1);
					int no=rs.getInt("no");
					String name=rs.getString("name");
					String phone=rs.getString("phone");
					String address=rs.getString("address");
					//Date birthday=rs.getDate("birthday");
					//처리행의 컬럼값은 오라클 자료형에 상관없이 getString() 
                    //메소드를 호출하여 문자열(String 객체)로 반환 가능
					String birthday=rs.getString("birthday");
					
					System.out.println("학번 = "+no);
					System.out.println("이름 = "+name);
					System.out.println("전화번호 = "+phone);
					System.out.println("주소 = "+address);
					//System.out.println("생년월일 = "+birthday);
					System.out.println("생년월일 = "+birthday.substring(0,10));
					System.out.println("=======================================");
				} while(rs.next());//ResultSet 커서 위치에 처리행이 있는 경우 반복문 실행
			} else {//ResultSet 커서를 다음행으로 이동하여 처리행이 존재하지 않는 경우
				System.out.println("[메세지]검색된 학생정보가 없습니다.");
			}
		} catch (ClassNotFoundException e) {
			System.out.println("[에러]OracleDriver 클래스를 찾을 수 없습니다.");
		} catch (SQLException e) {
			System.out.println("[에러]JDBC 관련 오류 = "+e.getMessage());
		} finally {
			try {
				if(rs!=null) rs.close();
				if(stmt!=null) stmt.close();
				if(con!=null) con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}








🐣 예제4 - SELECT2


//EMP 테이블에 저장된 모든 사원정보의 사원번호,사원이름,급여를 급여로 내림차순 정렬되도록
//검색하여 출력하는 JDBC 프로그램
public class SelectEmpApp {
	public static void main(String[] args) {
		Connection con=null;
		Statement stmt=null;
		ResultSet rs=null;
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			String url="jdbc:oracle:thin:@localhost:1521:xe";
			String username="scott";
			String password="tiger";
			con=DriverManager.getConnection(url, username, password);
			
			stmt=con.createStatement();
			
			String sql="select empno,ename,sal from emp order by sal desc";
			rs=stmt.executeQuery(sql);
			
			while(rs.next()) {
				System.out.println("사원번호 = "+rs.getInt("empno")
					+", 사원이름 = "+rs.getString("ename")+", 급여 = "+rs.getInt("sal"));
			}
		} catch (ClassNotFoundException e) {
			System.out.println("[에러]OracleDriver 클래스를 찾을 수 없습니다.");
		} catch (SQLException e) {
			System.out.println("[에러]JDBC 관련 오류 = "+e.getMessage());
		} finally {
			try {
				if(rs!=null) rs.close();
				if(stmt!=null) stmt.close();
				if(con!=null) con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} 
		
	}
}






🐣 예제5 - DELETE


//STUDENT 테이블에 저장된 학생정보 중 학번이 [3000]인 학생정보를 삭제하는 JDBC 프로그램 작성 
public class DeleteStudentApp {
	public static void main(String[] args) {
		Connection con=null;
		Statement stmt=null;
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			String url="jdbc:oracle:thin:@localhost:1521:xe";
			String username="scott";
			String password="tiger";
			con=DriverManager.getConnection(url, username, password);
			
			stmt=con.createStatement();
			
			String sql="delete from student where no=3000";
			int rows=stmt.executeUpdate(sql);
			
			System.out.println("[메세지]"+rows+"명의 학생정보를 삭제 하였습니다.");
		} catch (ClassNotFoundException e) {
			System.out.println("[에러]OracleDriver 클래스를 찾을 수 없습니다.");
		} catch (SQLException e) {
			System.out.println("[에러]JDBC 관련 오류 = "+e.getMessage());
		} finally {
			try {
				if(stmt!=null) stmt.close();
				if(con!=null) con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}






📌 TRANSACTION 처리

  • JDBC 프로그램은 기본적으로 AutoCommit 기능이 활성화 처리되어 있어 SQL 명령(DML)이 전달되어 실행되면 자동으로 커밋 처리

    • 프로그램 실행시 예외가 발생한 경우 예외 발생전에 전달되어 실행된 SQL 명령에 대한 롤백 처리 불가능
  • JDBC 프로그램에서 AutoCommit 기능을 비활성화 처리하여 예외 발생 없이 프로그램이 정상적으로 실행된 경우 커밋하고 예외가 발생된 경우 롤백 처리하는 것을 권장

  • Connection.setAutoCommit (boolean autoCommit) : AutoCommit 기능의 사용여부를 변경하는 메소드
    (false : AutoCommit 기능 비활성화, true : AutoCommit 기능 활성화(기본))

  • Connection.commit() : Connection 객체에 의해 전달된 SQL 명령에 커밋 처리 메소드

  • Connection.rollback() : Connection 객체에 의해 전달된 모든 SQL 명령 롤백 처리 메소드

🐣 예제

//STUDENT 테이블에 저장된 학생정보 중 학번이 [2000]인 학생의 이름을 
//[임꺽정]으로 변경하는 JDBC 프로그램 작성
public class TransactionControlApp {
	public static void main(String[] args) {
		Connection con=null;
		Statement stmt=null;
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			String url="jdbc:oracle:thin:@localhost:1521:xe";
			String username="scott";
			String password="tiger";
			con=DriverManager.getConnection(url, username, password);
			
			//Connection.setAutoCommit(boolean autoCommit) 
            //: AutoCommit 기능의 사용여부를 변경하는 메소드
			//false : AutoCommit 기능 비활성화, true : AutoCommit 기능 활성화(기본)
			con.setAutoCommit(false);
			
			stmt=con.createStatement();
			
			String sql="update student set name='임꺽정' where no=2000";
			int rows=stmt.executeUpdate(sql);
			
			//if(con!=null) throw new Exception();//무조건 예외 발생 
			
			if(rows>0) {//조작된 행이 있는 경우
				System.out.println("[메세지]"+rows+"명의 학생정보를 변경 하였습니다.");
			} else {//조작된 행이 없는 경우
				System.out.println("[메세지]해당 학번의 학생정보를 찾을 수 없습니다.");
			}
			
			//Connection.commit() : Connection 객체에 의해 전달된 SQL 명령에 커밋 처리
			con.commit();
		} catch (ClassNotFoundException e) {
			System.out.println("[에러]OracleDriver 클래스를 찾을 수 없습니다.");
		} catch (SQLException e) {
			System.out.println("[에러]JDBC 관련 오류 = "+e.getMessage());
		} catch (Exception e) {
			System.out.println("[에러]프로그램에 예기치 못한 오류가 발생 하였습니다.");
			try {
				//Connection.rollback() 
                //: Connection 객체에 의해 전달된 모든 SQL 명령 롤백 처리 메소드
				con.rollback();
			} catch (SQLException e1) { }
		} finally {
			try {
				if(stmt!=null) stmt.close();
				if(con!=null) con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		} 
	}
}





🌻 Connection Factory

  • Connection 객체를 생성하여 반환하거나 JDBC 관련 객체를 전달받아 제거하는 기능을 제공하는 클래스
    • JDBC 프로그램 작성에 필요한 공통적인 명령들을 메소드로 제공
    • 프로그램의 생산성이 향상되고 유지보수의 효율성 증가

public class ConnectionFactory {
	//Connection 객체를 생성하여 반환하는 메소드
	public static Connection getConnection() {
		Connection con=null;
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			String url="jdbc:oracle:thin:@localhost:1521:xe";
			String username="scott";
			String password="tiger";
			con=DriverManager.getConnection(url, username, password);
		} catch (Exception e) {
			System.out.println("[에러]Connection 객체를 생성할 수 없습니다.");
		}
		return con;
	}
    
    
	
	//JDBC 관련 객체를 전달받아 제거하는 메소드 - 오버로드 선언
	public static void close(Connection con) {
		try {
			if(con!=null) con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public static void close(Connection con, Statement stmt) {
		try {
			if(stmt!=null) stmt.close();
			if(con!=null) con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public static void close(Connection con, Statement stmt, ResultSet rs) {
		try {
			if(rs!=null) rs.close();
			if(stmt!=null) stmt.close();
			if(con!=null) con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}





🐣 예제

  • ConnectionFactory 클래스의 메소드 호출하여 JDBC 프로그램 작성

DEPT 테이블에 저장된 모든 부서정보를 검색하여 출력하는 JDBC 프로그램 작성
public class ConnectionFactoryApp {
	public static void main(String[] args) {
		Connection con=null;
		Statement stmt=null;
		ResultSet rs=null;
		try {//ConnectionFactory 클래스의 getConnection 메소드 실행
        	//DBMS 서버에 접속
			con=ConnectionFactory.getConnection();
		
			stmt=con.createStatement();
			
			String sql="select * from dept order by deptno";
			rs=stmt.executeQuery(sql);
			
			while(rs.next()) {
				System.out.println("부서번호 = "+rs.getInt("deptno")+", 부서이름 = "
                +rs.getString("dname")+", 부서위치 = "+rs.getString("loc"));
			}
		} catch (SQLException e) {
			System.out.println("[에러]JDBC 관련 오류 = "+e.getMessage());
		} finally {
        	//ConnectionFactory 클래스의 close 메소드 실행
			ConnectionFactory.close(con, stmt, rs);
		}
	}
}






🌻 ResultSetMetaData

  • ResultSet.getMetaData() : 검색결과(ResultSet 객체)에 대한 부가적인 정보를 저장하는 ResultSetMetaData 객체를 반환하는 메소드

  • ResultSetMetaData.getColumnCount() : 검색행의 컬럼갯수를 반환하는 메소드

  • ResultSetMetaData.getColumnLabel(int columnIndex) : columnIndex 위치의 컬럼명을 반환하는 메소드

  • ResultSetMetaData.isNullable(int columnIndex) : columnIndex 위치의 컬럼에 대한 NULL 허용 유무값(0 또는 1)을 반환하는 메소드

  • ResultSetMetaData.columnNoNulls : NULL을 허용하지 않는 값을 표현하는 상수(Constant)

    • 정수값 : 0
  • ResultSetMetaData.getColumnTypeName(int columnIndex) : columnIndex 위치의 컬럼에 대한 오라클 자료형을 반환하는 메소드

  • ResultSetMetaData.getColumnDisplaySize(int columnIndex) : columnIndex 위치의 컬럼에 대한 출력크기를 반환하는 메소드



🐣 예제

//STUDENT 테이블에 저장된 모든 학생정보를 검색하여 출력하는 JDBC 프로그램 작성
public class ResultSetMetaDataApp {
	public static void main(String[] args) throws SQLException {
		Connection con=ConnectionFactory.getConnection();
		
		Statement stmt=con.createStatement();
		
		String sql="select * from student order by no";
		ResultSet rs=stmt.executeQuery(sql);
		
		while(rs.next()) {
			System.out.println("학번="+rs.getInt("no")+", 이름="+rs.getString("name"));
		}
		System.out.println("====================================================");
        
		//ResultSet.getMetaData() : 검색행(ResultSet 객체)에 대한 부가적인 정보를 저장하는
		//ResultSetMetaData 객체를 반환하는 메소드
		ResultSetMetaData rsmd=rs.getMetaData();
		
		//ResultSetMetaData.getColumnCount() : 검색행의 컬럼 갯수를 반환하는 메소드
		int columnCount=rsmd.getColumnCount();
		System.out.println("검색행의 컬럼 갯수 = "+columnCount);//5
		System.out.println("=====================================================");
        
		for(int i=1;i<=columnCount;i++) {
			//ResultSetMetaData.getColumnLabel(int columnIndex) 
            //: columnIndex 위치의 컬럼명을 반환하는 메소드
			String columnLabel=rsmd.getColumnLabel(i);
			
            
			//ResultSetMetaData.isNullable(int columnIndex) : columnIndex 위치의
            //컬럼에 대한 NULL 허용 유무값(0 또는 1)을 반환하는 메소드
			int isNull=rsmd.isNullable(i);//isNull에 0 또는 1이 반환됨
            
			String nullResult="NULL";
			//ResultSetMetaData.columnNoNulls : NULL를 허용하지 않는 값을 표현하는 상수 
            // → 정수값 : 0
			if(isNull==ResultSetMetaData.columnNoNulls) {
				nullResult="NOT NULL";
			}
			
            
			//ResultSetMetaData.getColumnTypeName(int columnIndex) 
            // : columnIndex 위치의 컬럼에 대한 오라클 자료형을 반환하는 메소드
			String columnTypeName=rsmd.getColumnTypeName(i);
			
            
			//ResultSetMetaData.getColumnDisplaySize(int columnIndex) 
            // : columnIndex 위치의 컬럼에 대한 출력크기를 반환하는 메소드
			int columnDisplaySize=rsmd.getColumnDisplaySize(i);
			
            
			System.out.println("컬럼명 = "+columnLabel);//no,name,...
			System.out.println("NULL 허용 유무 = "+nullResult);//not null,null,...
			System.out.println("컬럼 자료형 = "+columnTypeName);//number, varchar2,..
			System.out.println("컬럼 출력크기 = "+columnDisplaySize);//5,50,...
			System.out.println("==================================================");
		
		ConnectionFactory.close(con, stmt, rs);
	}
}





🌻 Execute 메소드

  • Statement.Execute(String sql) : SQL 명령을 전달하여 실행하는 메소드 (boolean 반환)

    • false 반환 : DML 명령(INSERT, UPDATE, DELETE) 또는 DDL 명령(CREATE,DROP)을 전달하여 실행한 경우의 반환값
    • true 반환 : SELECT 명령을 전달하여 실행한 경우의 반환값
  • Statement.getResultSet() : Statement 객체로 전달되어 실행된 SELECT 명령에 대한 검색결과를 저장한 ResultSet 객체를 반환하는 메소드

  • Statement.getUpdateCount() : Statement 객체로 전달되어 실행된 DML 명령에 대한 조작행의 갯수를 정수값으로 반환하는 메소드 (DDL 명령은 0을 반환)


🐣 예제

public class ExecuteApp {
	public static void main(String[] args) throws SQLException {
		Connection con=ConnectionFactory.getConnection();//서버접속
		Statement stmt=con.createStatement();//statement 객체생성
		
		int choice=1;
		String sql="";
        
		if(choice==1) {
			sql="update student set name='임꺽정' where no=2000";
		} else {
			sql="select * from student order by no";
		}

		boolean result=stmt.execute(sql);
		
		if(result) {//SELECT 명령을 전달하여 실행한 경우
			//Statement.getResultSet() : Statement 객체로 전달되어 실행된 SELECT 명령에 대한
			//검색결과를 저장한 ResultSet 객체를 반환하는 메소드
			ResultSet rs=stmt.getResultSet();
			
			while(rs.next()) {
				System.out.println("학번="+rs.getInt("no")+",이름="+rs.getString("name"));
			}
			ConnectionFactory.close(con, stmt, rs);
            
		} else {//DML 명령 또는 DDL 명령을 전달하여 실행한 경우
			//Statement.getUpdateCount() : Statement 객체로 전달되어 실행된 DML 명령에 대한
			//조작행의 갯수를 정수값으로 반환하는 메소드 - DDL 명령은 0을 반환
			int rows=stmt.getUpdateCount();
			
			System.out.println("[결과]"+rows+"명의 학생정보를 변경 하였습니다.");

			ConnectionFactory.close(con, stmt);
		}
		
	}
}



🎀 연습문제 - JDBC 프로그램

  • 키보드로 SQL 명령을 입력받아 DBMS 서버에 전달하여 실행하고 결과를 출력하는 JDBC 프로그램 작성
    • 키보드로 입력 가능한 SQL 명령은 INSERT, UPDATE, DELETE, SELECT 명령만 가능하도록 작성
    • SQL 명령을 반복적으로 입력받아 실행되도록 작성
    • SQL 명령 대신 [EXIT]를 입력하면 프로그램 종료 (대소문자 미구분)
    • 키보드로 입력한 SQL 명령이 잘못된 경우 에러 메세지 출력
public class SqlMinusApp {
	public static void main(String[] args) throws Exception {
		//키보드로 SQL 명령(문자열)을 입력받기 위한 입력스트림 생성
		BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
		
		Connection con=ConnectionFactory.getConnection();
		Statement stmt=con.createStatement();
		ResultSet rs=null;
		
		System.out.println("SQLMinus 프로그램을 실행합니다.(종료 : exit)");
		
		while(true) {
			//키보드로 SQL 명령을 입력받아 저장
			System.out.print("SQL> ");
			String sql=in.readLine().trim();
            //키보드로 입력받은 문자열의 앞과 뒤의 모든 공백 제거
		
			//키보드 입력값이 없는 경우 반복문을 처음부터 다시 실행
			if(sql==null || sql.equals("")) continue;
						
			//키보드 입력값이 [EXIT]인 경우 반복문 종료 - 프로그램 종료
			if(sql.equalsIgnoreCase("exit")) break;//대소문자 미구분
			
			try {
				if(stmt.execute(sql)) {//SELECT 명령을 전달하여 실행한 경우
					rs=stmt.getResultSet();//ResultSet객체에 명령에 대한 검색결과 저장
					
					if(rs.next()) {//검색행이 있는 경우
						ResultSetMetaData rsmd=rs.getMetaData();
						//SELECT 명령에 대한 검색대상의 갯수를 반환받아 저장
						int columnCount=rsmd.getColumnCount();
						
						System.out.println("===================================");
						//SELECT 명령에 대한 검색대상의 이름을 반환받아 출력
						for(int i=1;i<=columnCount;i++) {
							System.out.print(rsmd.getColumnLabel(i)+"\t");
						}
						System.out.println();
						System.out.println("===================================");
						//반복문을 사용하여 검색행의 컬럼값을 반환받아 저장
						do {
							for(int i=1;i<=columnCount;i++) {
								String columnValue=rs.getString(i);//컬럼값 반환
								//컬럼의 오라클 자료형이 [DATE]인 경우
								if(rsmd.getColumnTypeName(i).equals("DATE")) {
									columnValue=columnValue.substring(0,10);
								}
								//컬럼값이 없는 경우
								if(columnValue==null) {
									columnValue="  ";
								}
								//컬럼값 출력
								System.out.print(columnValue+"\t");
							}
							System.out.println();
						} while(rs.next());
					} else {//검색행이 없는 경우
						System.out.println("검색된 결과가 없습니다.");
					}
				} else {//INSERT,UPDATE,DELETE 명령을 전달하여 실행한 경우
					int rows=stmt.getUpdateCount();//조작행의 갯수 반환 
					System.out.println(rows+"개의 행을 "
                    +sql.substring(0,6).toUpperCase()+" 하였습니다.");
				}
				
				System.out.println();
			} catch (SQLException e) {
				//키보드로 입력받아 실행된 SQL 명령에 문제가 있는 경우 SQLException 발생
				System.out.println("SQL 오류 = "+e.getMessage());
			}
		}
				
		ConnectionFactory.close(con, stmt, rs);
		System.out.println("[메세지]SQLMinus 프로그램을 종료합니다.");
	}
}






profile
Study Log 📂

0개의 댓글