JDBC 1

웃음인·2025년 4월 21일

Java

목록 보기
26/37
post-thumbnail

JDBC(Java DataBase Connectivity)

Java에서 DB에 접근할 수 있게 해주는 Java Programming API

  • API (Application Programming Interface)
    운영체제나 프로그래밍 언어가 제공하는 기능을 사용할 수 있도록 하는 인터페이스

OJDBC란?

오라클에서 제공하는 오라클 DB와 자바가 연결하기 위한 라이브러리
Oracle JDBC Driver 제공

-  메이븐 레파지토리에서 다운로드( https://mvnrepository.com/ )
   ojdbc11.jar( JDK11 ~ 17포함)
   ojdbc8.jar( JDK8 ~ 15포함)

   (알맞은 버전을 검색해서 다운로드)



▶ Library 등록 방법

Java Project → Properties → Java Build Path → Libraries → Add External JARs...

  • OJDBC Library 등록 확인

    * package Explorer에 Referenced Libraries가 생기고 ojdbc6.jar가 생성됨


▶ JDBC 사용 객체

  • DriverManager
    • 데이터 원본에 JDBC드라이버를 통하여 커넥션을 만드는 역할
      Class.forName() 메소드를 통해 생성되며 반드시 예외처리를 해야 함
      직접 객체 생성이 불가능하고 getConnection() 메소드를 사용하여 객체 생성 가능

  • Connection
    • 특정 데이터 원본과 연결된 커넥션을 나타내며 Statement객체를 생성할 때도
      Connection객체를 사용하여 createStatement() 메소드를 호출하여 생성
      SQL문장을 실행시키기 전에 우선 Connection객체가 있어야 함

  • Statement
    • Connection객체에 의해 프로그램에 리턴되는 객체에 의해 구현되는 일종의 메소드 집합 정의. Connection클래스의 createStatement() 메소드를 호출하여 얻어지며
      생성된 Statement객체로 질의문장을 String객체에 담아 인자로 전달하여
      executeQuery() 메소드를 호출하여 SQL질의 수행
try{
	String query = “SELECT ID, LAST_NAME FROM EMP”;
	stmt = conn.createStatement();
	rset = stmt.executeQuery(query);
} catch(SQLException e){
	e.printStackTrace();
}

자바가 원하는 데이터를 DB한테 얻어올 때
통로 안에서 그냥 SQL을 보내는 게 아니라 Statement라는 버스에 실어서 보냄


  • PreparedStatement
    • Connection객체의 preparedStatement() 메소드를 사용하여 객체 생성
      SQL문장이 미리 컴파일 되고 실행 시간동안 인수 값을 위한 공간을 확보한다는 점에서 Statement와 다름
      각각의 인수에 대해 위치 홀더(?)를 사용하여 SQL문장을 정의할 수 있게 함
try{
	String query = “INSERT INTO MEMBER VALUES(?, ?)”;
	pstmt = conn.preparedStatement(query);
	pstmt.setString(1, id);
	pstmt.setString(2, password);
} catch(SQLException e){
	e.printStackTrace();
}

위치홀더에 들어갈 값도 같이 실어서 보냄


  • ResultSet
    • SELECT문을 사용한 질의 성공 시 Result Set 반환
      SQL질의에 의해 생성된 테이블을 담고 있으며 커서(cursor)로
      특정 행에 대한 참조 조작




▶ JDBC 코딩 절차

1. DriverManager에 해당 DBMS Driver 등록

★ 반드시 ClassNotFoundException 처리를 해야 함


2. 해당 Driver로부터 Connection instance 획득

★ 반드시 SQLException 처리를 해야 함


3. Connection instance로부터 Statement instance 획득

★ 반드시 SQLException 처리를 해야 함


4. tatement method를 이용하여 SQL문 실행
   실행결과를 ResultSet(Select) 혹은 int형 변수(DML)로 받아서 처리

★ 반드시 SQLException 처리를 해야 함


5. DB로 부터 획득한 instance 들을 획득한 역순으로 반환

★ 반드시 SQLException 처리를 해야 함




소스코드


🔹 JDBC 기본 흐름 예제(DB 연결부터 조회까지)

package edu.kh.jdbc;

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

// ctrl + r11 실행
public class JDBCExample1 {

	public static void main(String[] args) {
		
		/*
		 * JDBC(Java DataBase Connectivity) 
		 * 
		 * - Java에서 DB에 연결할 수 있게 해주는
		 *   Java API (Java에서 제공하는 코드) 
		 *  -> java.sql 패키지에 존재함
		 * 
		 * */
		
		
		// Java 코드를 이용해
		// EMPLOYEE 테이블에서 
		// 사번, 이름, 부서코드, 직급코드, 급여, 입사일 조회 후
		// 이클립스 콘솔에 출력
		
		
		/* 1. JDBC 객체 참조용 변수 선언 */
		
		// java.sql.Connection
		// -> 특정 DBMS와 연결하기 위한 정보를 저장한 객체
		// 즉, DBeaver에서 사용하는 DB 연결과 같은 역할의 객체이다
		//     (DB 서버주소, 포트번호, DB이름, 계정명, 비밀번호) 
		Connection conn = null;
		
		// java.sql.Statement
		// - 1) SQL을 java에서 DB에 전달
		// - 2) DB에서 SQL 수행 결과를 반환 받아옴 (DB -> Java) 
		Statement stmt = null;
		
		// java.sql.ResultSet
		// - SELECT(조회) 결과를 저장하는 객체
		ResultSet  rs = null;
		
		try {
			
			/* 2. DriverManager 객체를 이용해서 Connection 객체 생성하기 */
			
			// java.sql.DriverManager
			// - DB 연결 정보와 JDBC 드라이버를 이용해서
			//   원하는 DB와 연결할 수 있는 Connection 객체를 생성하는 객체
			
			// 2-1 ) Oracle JDBC Driver 객체를 메모리에 로드(적재)하기
			Class.forName("oracle.jdbc.driver.OracleDriver"); 
			
			// Class.forName("패키지명 + 클래스명");
			// - 해당 클래스를 읽어 메모리에 적재
			// -> JVM이 프로그램 동작에 사용할 객체를 생성하는 구문
			
			// oracle.jdbc.driver.OracleDriver
			// - Oracle DBMS 연결 시 필요한 코드가 담겨있는 클래스
			//   Oracle 에서 만들어서 준 클래스
			
			
			// 2-2 ) DB 연결 정보 작성
			String type = "jdbc:oracle:thin:@"; // 드라이버의 종류
			
			String host = "localhost"; // DB 서버 컴픁의 IP 또는 도메인 주소
                                       // localhost == 현재 컴퓨터
			
			String port = ":1521"; // 프로그램 연결을 위한 port 번호
			
			String dbName = ":XE"; // DBMS 이름(XE = eXpress Edition) 
			
			// --> jdbc:oracle:thin:@localhost:1521:XE
			
			String userName = "kh_wsm"; // 사용자 게정명
			
			String password = "kh1234"; // 계정 비밀번호
			
			
			
			
			// 2-3 ) DB 연결 정보와 DriverManager를 이용해서 Connection 객체 생성
			conn = DriverManager.getConnection(type + host + port + dbName,  
										userName,
										password); 
			 
			// Connection 객체가 잘 생성되었는지 확인 (객체 주소 반환)
			// == DB 연결 정보에 오타가 없는지 확인
			// -> DB 연결 정보가 잘못되거나 객체 생성에 문제가 생기면 SQLException 발생
			System.out.println(conn); // oracle.jdbc.driver.T4CConnection@397fbdb
			                          //   ㄴ Connection 통로 생성!
			
			
			/* 3. SQL 작성 */
			
			// !! 주의사항 !!
			// -> 1. JDBC 코드에서 SQL 작성 시
			// 	     세미콜론(;)을 작성하면 안 된다 !!!
			//      -> 작성 시 "sql 명령어가 올바르게 종료되지 않았습니다" 예외 발생
			
			// EMPLOYEE 테이블에서 
			// 사번, 이름, 부서코드, 직급코드, 급여, 입사일 조회 
			String sql = "SELECT EMP_ID, EMP_NAME, DEPT_CODE, JOB_CODE, "
						+ "SALARY, HIRE_DATE FROM EMPLOYEE";
			// -> 2. 줄 길어서 내릴 때 컬럼 사이사이에 적절한 공백 있는지 잘 확인하기!!!
			
			
			
			/* 4. Statement 객체 생성 */
			stmt = conn.createStatement(); 
			// 연결된 DB에 SQL을 전달하고 결과를 반환받을
			// Statement 객체를 생성
			
			
			
			/* 5. Statement 객체를 이용해서 SQL 수행 후 결과 반환 받기 */
			
			// 1) ResultSet Statement.executeQuery(sql);
			//   -> sql이 SELECT 문일 때 결과로 java.sql.ResultSet 반환
            // Select -> executeQuery(sql)
                                   // 전달된 sql (Select)
                      // 반환값: ResultSet
			
			// 2) int Statement.executeUpdate(sql);
			// -> DML(INSERT, UPDATE, DELETE) 실행 메서드
			//    결과로 int 반환(삽입, 수정, 삭제된 행의 개수) 
            // DML -> executeUpdate(sql)
                                 // 전달된 sql (INSERT, UPDATE, DELETE)
                   // 반환값: Int

			
			
			rs = stmt.executeQuery(sql); 
			
			
			/*  6. 조회 결과가 담겨있는 ResultSet을
			 *    커서(Cursor)를 이용해 
			 *    1행씩 접근해 각 행에 작성된 컬럼 값 얻어오기
			 *    
			 *  */
			
			// rs.next() : 커서를 다음 행으로 이동시킨 후 
			//             이동된 행에 값이 있으면 true, 없으면 false 반환
			// 			   맨 처음 호출 시 1행부터 시작
			while(rs.next()) {
				// 200	선동일	D9	J1	8000000	1990-02-06 00:00:00.000
				
				// rs.get자료형(컬럼명 || 순서);
				// - 현재 행에서 지정된 컬럼의 값을 얻어와 반환
				// - 지정된 자료형 형태로 값이 반환됨
				// -> (자료형을 잘못 지정하면 예외 발생)
				
				
				// [java]            [db]
				// String            CHAR, VARCHAR2
				// int, long         NUMBER (정수만 저장된 컬럼) 
				// float, double     NUMBER (정수 + 실수)  
				// java.sql.Date     DATE 
				
				String empId = rs.getString("EMP_ID");
				String empName = rs.getString("EMP_NAME");
				String deptCode = rs.getString("DEPT_CODE");
				String jobCode = rs.getString("JOB_CODE");
				int salary = rs.getInt("SALARY");
				Date hireDate = rs.getDate("HIRE_DATE"); 
				
				
				System.out.printf(
						"사번 : %s / 이름 : %s / 부서코드 : %s / 직급코드 : %s / 급여 : %d / 입사일 : %s \n",
						empId, empName, deptCode, jobCode, salary, hireDate.toString()
				);
				
				
			}
	
			
		} catch (ClassNotFoundException e) {
			
			System.out.println("해당 Class를 찾을 수 없습니다.");
			e.printStackTrace();
			
		} catch(SQLException e) {
			// SQLException : DB 연결과 관련된 모든 예외의 최상위 부모
			e.printStackTrace();
		
			
		} finally {
			
			/* 7. 사용 완료된 JDBC 객체 자원 반환(close) */
			
			// -> 수행하지 않으면 DB와 연결된 Connection 이 그대로 남아있어서
			//    다른 클라이언트가 추가적으로 연결되지 못하는
			//    문제가 발생할 수 있다!!!
			
			try {
				
				// 만들어진 역순으로 close 수행하는 것을 권장
				if(rs != null) rs.close();
				if(stmt != null) stmt.close();
				if(conn != null) conn.close();
				
				// if문은 NullPointerException 방지용 구문
				
			} catch (Exception e) {
				
				e.printStackTrace();
			}
			
		}

	}

}


🔹 입력받은 급여보다 많은 사원 조회 예제

package edu.kh.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;

public class JDBCExample2 {

	public static void main(String[] args) {
		
		// 입력 받은 급여보다 초과해서 받는 사원의 
		// 사번, 이름, 급여를 조회
		
		
		// 1. JDBC 객체 참조용 변수 선언
		Connection con = null; // DB 연결 정보 저장 객체
		Statement stm = null;  // SQL 수행, 결과 반환용 객체
		ResultSet rs = null;   // SELECT 수행 결과 저장 객체
		
		try {
			
			// 2. DriverManager 객체를 이용해서 Connection 객체 생성
			// 2-1) Oracle JDBC Driver 객체 메모리 로드
			Class.forName("oracle.jdbc.driver.OracleDriver"); 
			
			// 2-2) DB 연결 정보 작성
			String type = "jdbc:oracle:thin:@"; // 드라이버의 종류
			
			String host = "localhost"; // DB 서버 컴픁의 IP 또는 도메인 주소
                                       // localhost == 현재 컴퓨터
			
			String port = ":1521"; // 프로그램 연결을 위한 port 번호
			
			String dbName = ":XE"; // DBMS 이름(XE = eXpress Edition) 
			
			String userName = "kh_wsm"; // 사용자 게정명
			
			String password = "kh1234"; // 계정 비밀번호
			
			// 2-3) DB 연결 정보와 DriverManager 를 이용해서 Connection 객체 생성
			con = DriverManager.getConnection(type + host + port + dbName,  
					userName,
					password); 
			
			// 3. SQL 작성
			//    입력받은 급여 - Scanner 필요
			// int input 여기에 급여 담기
			Scanner sc = new Scanner(System.in);
			System.out.println("급여 입력 : ");
			int input = sc.nextInt();
			
			String sql = "SELECT EMP_ID, EMP_NAME, SALARY FROM EMPLOYEE "
						+ "WHERE SALARY > " + input;

			// 4. Statement 객체 생성
			stm = con.createStatement();
			
			// 5. Statement 객체를 이용하여 SQL 수행 후 결과 반환 받기			
			// executeQuery() : SELECT 실행, ResultSet 반환
			// executeUpdate() : DML 실행, 결과 행의 개수 반환(int) 
			rs = stm.executeQuery(sql);
			
			
			// 6. 조회 결과가 담겨있는 ResultSet을
			//    커서 이용해 1행씩 접근해 각 행에 작성된 컬럼 값 얻어오기
			//   -> while 안에서 꺼낸 데이터 출력
			
			while(rs.next()) {
				
				String empId = rs.getString("EMP_ID");
				String empName = rs.getString("EMP_NAME");
				int salary = rs.getInt("SALARY"); 
				
				// 201 / 송종기 / 6000000원	
				// 202 / 노옹철 / 3700000원
				// 203 / 송은희 / 2800000원
				// ...
				
				
				System.out.printf("%s / %s / %d원 \n",
						empId, empName, salary);
			}
			
			
		} catch (Exception e) {
			// 최상위 예외인 Exception을 이용해서 모든 예외를 처리
			// -> 다형성 업캐스팅 적용
			e.printStackTrace();
			
		} finally {
			
			try {
				// 7.  사용 완료된 JDBC 객체 자원 반환(close)
				//   -> 생성된 역순으로 close!
				
				if(rs != null) rs.close();
				if(stm != null) stm.close();
				if(con != null) con.close();
				
			} catch (Exception e) {
				e.printStackTrace();
			}

		}
			
	}

}


🔹 입력한 급여 범위 내 사원 조회 (내림차순 정렬)

package edu.kh.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;

public class JDBCExample3 {

	public static void main(String[] args) {
		
		// 입력받은 최소 급여 이상
		// 입력받은 최대 급여 이하를 받는
		// 사원의 사번, 이름, 급여를 급여 내림차순으로 조회
		// -> 이클립스 콘솔 출력
		
		// [실행화면]
		// 최소 급여 : 1000000
		// 최대 급여 : 3000000
		
		// (사번) / (이름) / (급여)
		// (사번) / (이름) / (급여)
		// (사번) / (이름) / (급여)
		// ...
		

		// 1. JDBC 객체 참조 변수 선언
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null; // SQL(SELECT)
		
		
		try {
			
			// 2. DriverManager 객체를 이용해서 Connection 객체 생성하기
			
			Class.forName("oracle.jdbc.driver.OracleDriver"); 
			
			String type = "jdbc:oracle:thin:@"; // 드라이버의 종류			
			String host = "localhost"; // DB 서버 컴픁의 IP 또는 도메인 주소			
			String port = ":1521"; // 프로그램 연결을 위한 port 번호			
			String dbName = ":XE"; // DBMS 이름(XE = eXpress Edition) 			
			// --> jdbc:oracle:thin:@localhost:1521:XE
			
			String userName = "kh_wsm"; // 사용자 게정명			
			String password = "kh1234"; // 계정 비밀번호
			
			
			conn = DriverManager.getConnection(type + host + port + dbName,
												userName,
												password);  
			
			
			// 3. SQL 작성
			Scanner sc = new Scanner(System.in);
			System.out.print("최소 급여 : ");
			int min = sc.nextInt();
			
			System.out.print("최대 급여 : ");
			int max = sc.nextInt();
			
			
			/* String sql = "SELECT EMP_ID, EMP_NAME, SALARY "
						+ "FROM EMPLOYEE "
						+ "WHERE SALARY BETWEEN " + min + " AND" + max 
						+ " ORDER BY SALARY DESC";  // 각각 공백 잘 확인해야 함
			*/
			
			String sql = """
					SELECT EMP_ID, EMP_NAME, SALARY
					FROM EMPLOYEE
					WHERE SALARY BETWEEN
					""" + min + " AND " + max // AND 양 옆 공백 잘 확인하기
					+ "ORDER BY SALARY DESC"; // 앞 뒤에 """ 붙여주면 각각 공백, 쌍따옴표 없어도 됨 
			
			
			
			// 4. Statement 객체 생성
			stmt = conn.createStatement();
			
			
			// 5. SQL 수행 후 결과 반환 받기
			rs = stmt.executeQuery(sql);
			
			// 6. 1행씩 접근하여 컬럼 값 얻어오기
			int count = 0;
			
			while(rs.next()) {
				count++;
				
				String empId = rs.getString("EMP_ID");
				String empName = rs.getString("EMP_NAME");
				int salary = rs.getInt("SALARY");
				
				System.out.printf("%s / %s / %d \n",
									empId, empName, salary); 
				
			}
			
			System.out.println("총원 : " + count + "명");
			
			
		} catch (Exception e) {
			e.printStackTrace(); // 예외추적
			
			
		} finally {
			// 7. 사용 완료한 jdbc 객체 자원 반환 (close)
			
			try {
				if(rs != null) rs.close();
				if(stmt != null) stmt.close();
				if(conn != null) conn.close(); 
				
			} catch (Exception e) {
				e.printStackTrace();
			}
		
		}

	}
	
}


🔹 부서명 입력 받아 사원 정보 조회 (직급 오름차순)

package edu.kh.jdbc;


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;

public class JDBCExample4 {

	public static void main(String[] args) {
		
		// 부서명을 입력받아
		// 해당 부서에 근무하는 사원의
		// 사번, 이름, 부서명, 직급명을
		// 직급코드 오름차순으로 조회
		
		// 부서명 입력 : 총무부
		// 200 / 선동일 / 총무부 / 대표
		// 202 / 노옹철 / 총무부 / 부사장
		// 201 / 송종기 / 총무부 / 부사장
		
		// hint : SQL에서 문자열을 양쪽에 '' (홑따옴표) 필요
		// ex) 총무부 입력 => '총무부
		
		Connection conn = null;
		Statement stmt = null;
		ResultSet rs = null;
		
		try {
			
			Class.forName("oracle.jdbc.driver.OracleDriver"); 
			
			String url = "jdbc:oracle:thin:@localhost:1521:XE"; 		
			
			String userName = "kh_wsm"; 
			String password = "kh1234"; 
			
			
			conn = DriverManager.getConnection(url, userName, password);  
			
			
			Scanner sc = new Scanner(System.in);
			System.out.print("부서명 입력 : ");
			String dept = sc.next();
			
			String sql = """					
						SELECT EMP_ID, EMP_NAME, NVL(DEPT_TITLE, '없음') DEPT_TITLE, JOB_NAME 
						FROM EMPLOYEE LEFT JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID) 
						JOIN JOB USING(JOB_CODE)
						WHERE DEPT_TITLE = '""" + dept + "' ORDER BY JOB_CODE";
			
			stmt = conn.createStatement();
			rs = stmt.executeQuery(sql);
			
			boolean flag = true;
			// 조회 결과가 있다면 false, 없으면 true
			
			while(rs.next()) {
				flag = false;
				
				String empId = rs.getString("EMP_ID");
				String empName = rs.getString("EMP_NAME");
				String deptTitle = rs.getString("DEPT_TITLE");
				String jobName = rs.getString("JOB_NAME");
				
				System.out.printf("%s / %s / %s / %s \n",
							empId, empName, deptTitle, jobName);
				
			}
			
			if(flag) { // flag == true == while문이 수행된 적 없음
				System.out.println("일치하는 부서가 없습니다.");
			}
		
		} catch (Exception e) {
			e.printStackTrace();
			
			
		} finally {
			
			try {
				
				if(rs != null) rs.close();
				if(stmt != null) stmt.close();
				if(conn != null) conn.close();
					
				
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}

	}

}


🔹 사용자 정보 입력 받아 TB_USER 테이블에 INSERT (PreparedStatement 활용)


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.Scanner;

public class JDBCExample5 {

	public static void main(String[] args) {
		
		// 아이디, 비밀번호, 이름을 입력받아
		// TB_USER 테이블에 삽입(INSERT) 하기
		
		// 1. jdbc 객체 참조변수 선언
		Connection conn = null;
		
		/*
		 * java.sql.PreparedStatement (준비된 Statement).
		 * < * PreparedStatement는 Statement 의 자식 * >
		 * 
		 * - SQL 중간에 ? (위치홀더, placeholder)를 작성하여
		 * ? 자리에 java 값을 대입할 준비가 되어있는 Statement
		 * 
		 * 장점 1 : SQL 작성이 간단해짐
		 * 장점 2 : ?에 값 대입 시 자료형에 맞는 형태의 
		 * 		    리터럴 표기법으로 대입됨!
		 * 			ex) String 대입 -> '값' (자동으로 '' 추가)
		 * 			ex) int 대입 -> 값
		 * 
		 * 장점 3 : 성능, 속도에서 우위를 가지고 있음 
		 * 
		 * */
		PreparedStatement pstmt = null;
		
		// SELECT가 아니기 때문에 ResultSet 필요 없음!
		
		try {
			
			// 2. DriverManager 를 이용해서 Connection 객체 생성
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			String url = "jdbc:oracle:thin:@localhost:1521:XE"; 		
			String userName = "kh_wsm"; 
			String password = "kh1234"; 
			
			conn = DriverManager.getConnection(url, userName, password);
			
			// 3. SQL 작성
			Scanner sc = new Scanner(System.in);
			
			System.out.print("아이디 입력 :");
			String id = sc.nextLine();
			
			System.out.print("비밀번호 입력 :");
			String pw = sc.nextLine();
			
			System.out.print("이름 입력 :");
			String name = sc.nextLine();
			
			String sql = """
						INSERT INTO TB_USER
						VALUES(SEQ_USER_NO.NEXTVAL, ?, ?, ?, DEFAULT) 
						""";
			
			/*
			 * AutoCommit 끄기!
			 * -> 왜 끄는 건가?
			 * 	  개발자가 트랜잭션을 마음대로 제어하기 위해서
			 * 
			 * */
			conn.setAutoCommit(false);
			
			
			
			// 4. PreparedStatement 객체 생성
			// -> 객체 생성과 동시에 SQL이 담겨지게 됨
			// -> 미리 ? (placeholder)에 값을 받을 준비를 해야되기 때문에..
			pstmt = conn.prepareStatement(sql);
			
			
			// 5. ? 위치 홀더에 알맞은 값 대입
			
			// pstmt.set자료형(?순서, 대입할 값)
			pstmt.setString(1, id);
			pstmt.setString(2, pw);
			pstmt.setString(3, name);
			// -> 여기까지 실행하면 SQL 이 작성 완료된 상태!!
			
			
			// 6. SQL(INSERT) 수행 후 결과(int) 반환받기
			// executeQuery() : SELECT 수행, ResultSet 반환
			// executeUpdate() : DML 수행, 결과 행 개수(int) 반환
			// -> 보통 DML 실패 시 0, 성공 시 0 초과된 값이 반환
			
			// PreparedStatement 를 이용하여 SQL 실행 시
			// executeQuery() / executeUpdate() 매개변수 자리에 아무것도 없어야 한다!!!
			int result = pstmt.executeUpdate();	
			
			// 7. result 값에 따른 결과 처리 + 트랜잭션 제어처리
			if(result > 0) { // INSERT 성공 시
				System.out.print(name + "님이 추가되었습니다");
				conn.commit(); // COMMIT 수행 -> DB에 INSERT 영구 반영
				
			} else {
				System.out.print("추가 실패");
				conn.rollback(); // 실패 시 ROLLBACK 하기
			}	
			
			
			
		} catch (Exception e) {
			e.printStackTrace();
			
		} finally {
			
			try {
				
				// 8. 사용한 JDBC 객체 자원 반환
				if(pstmt != null) pstmt.close();
				if(conn != null) conn.close();
				
				
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}

	}	

}


🔹 TB_USER 테이블 이름 변경 (조건부 UPDATE + 트랜잭션 제어)

package edu.kh.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.util.Scanner;
import java.util.Set;

public class JDBCExample6 {
	public static void main(String[] args) {
	
		// 아이디, 비밀번호, 이름을 입력받아
		// 아이디, 비밀번호가 일치하는 사용자(TB_USER)의
		// 이름을 수정(UPDATE) 
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		
		try {
			
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			String url = "jdbc:oracle:thin:@localhost:1521:XE"; 		
			String userName = "kh_wsm"; 
			String password = "kh1234"; 
			
			conn = DriverManager.getConnection(url, userName, password);
			
			conn.setAutoCommit(false);
			
			Scanner sc = new Scanner(System.in);
			System.out.print("아이디 입력 : ");
			String id = sc.nextLine();
			
			System.out.print("비밀번호 입력 : ");
			String pw = sc.nextLine();
			
			System.out.print("수정할 이름 입력 : ");
			String name = sc.nextLine();
			
			String sql = """
						UPDATE TB_USER SET
						USER_NAME = ?
						WHERE USER_ID = ?
						AND USER_PW = ?
						""";
			
			// PreparedStatement 객체 생성
			pstmt = conn.prepareStatement(sql);
			
			// ? 에 알맞은 값 세팅
			pstmt.setString(1, name);
			pstmt.setString(2, id);
			pstmt.setString(3, pw);
			// SQL 세팅 끝! -> 실행 결과 반환 받기
			
			int result = pstmt.executeUpdate();
			
			if(result > 0) { // 성공 시
				
				System.out.print("수정 완료");
				conn.commit();
				
			} else { // 실패 시
				System.out.print("아이디 또는 비밀번호 불일치");
				conn.rollback();
			}
			
			
			
		} catch (Exception e) {
			e.printStackTrace();
			
		} finally {
			
			try {
				
				if(pstmt != null) pstmt.close();
				if(conn != null) conn.close();
				
				
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}


🔹 PreparedStatement 활용 다중 조건 조회 예제 (사원 성별/급여 필터링 및 정렬)

package edu.kh.jdbc;

import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Scanner;

public class JDBCExample7 {

	public static void main(String[] args) {

		// EMPLOYEE 테이블에서
		// 사번, 이름, 성별, 급여, 직급명, 부서명을 조회
		// 단, 입력 받은 조건에 맞는 결과만 조회하고 정렬할 것

		// - 조건 1 : 성별 (M, F)
		// - 조건 2 : 급여 범위
		// - 조건 3 : 급여 오름차순/내림차순

		// [실행화면]
		// 조회할 성별(M/F) : F
		// 급여 범위(최소, 최대 순서로 작성) : 3000000 4000000
		// 급여 정렬(1.ASC, 2.DESC) : 2

		// 사번 | 이름 | 성별 | 급여 | 직급명 | 부서명
		// --------------------------------------------------------
		// 218 | 이오리 | F | 3890000 | 사원 | 없음
		// 203 | 송은희 | F | 3800000 | 차장 | 해외영업2부
		// 212 | 장쯔위 | F | 3550000 | 대리 | 기술지원부
		// 222 | 이태림 | F | 3436240 | 대리 | 기술지원부
		// 207 | 하이유 | F | 3200000 | 과장 | 해외영업1부
		// 210 | 윤은해 | F | 3000000 | 사원 | 해외영업1부

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

		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");

			String url = "jdbc:oracle:thin:@localhost:1521:XE";
			String userName = "kh_wsm";
			String password = "kh1234";

			conn = DriverManager.getConnection(url, userName, password);

			Scanner sc = new Scanner(System.in);
			System.out.print("조회할 성별(N/F) : ");
			String gender = sc.next().toUpperCase(); // 대문자로 변경 (DCODE 1 , 'M' , 2 'F')

			System.out.print("급여 범위(최소, 최대 순서로 작성) : ");
			int min = sc.nextInt();
			int max = sc.nextInt();

			System.out.print("급여 정렬 (1.ASC, 2. DESE) : ");
			int sort = sc.nextInt();

			String sql = """
						SELECT EMP_ID, EMP_NAME, DECODE(SUBSTR(EMP_NO, 8, 1),'1', 'M', '2', 'F') GENDER,
						SALARY, JOB_NAME, NVL(DEPT_TITLE, '없음') DEPT_TITLE
					    FROM EMPLOYEE JOIN JOB USING(JOB_CODE)
					    LEFT JOIN DEPARTMENT ON(DEPT_CODE = DEPT_ID)
					    WHERE DECODE(SUBSTR(EMP_NO, 8, 1),'1', 'M', '2', 'F') = ?
					    AND SALARY BETWEEN ? AND ?
					    ORDER BY SALARY
						""";
			// placeholder -> String -> 리터럴표기법 ''
			// -> int -> 값

			// 입력받은 정렬(sort) 값에 따라서 sql에
			// 오름/내림차순 SQL 추가하기

			if (sort == 1)
				sql += "ASC";
			else
				sql += "DESC";

			// PreparedStatement 객체 생성
			pstmt = conn.prepareStatement(sql);

			// ? (위치홀더)에 알맞은 값 세팅
			pstmt.setString(1, gender);
			pstmt.setInt(2, min);
			pstmt.setInt(3, max);

			// SQL 수행 후 결과 반환받
			rs = pstmt.executeQuery();

			// 커서를 이용해서 한 행씩 접근하여 컬럼 값 얻어오기
			System.out.println("사번 | 이름   | 성별 | 급여    | 직급명 | 부서명");
			System.out.println("-----------------------------------------------");

			boolean flag = true; // true : 조회 결과가 없음, false : 조회 결과가 존재함!

			while (rs.next()) {
				flag = false; // while 1회 이상 반복함 == 조회 결과가 1행이라도 있다

				String empId = rs.getString("EMP_ID");
				String empName = rs.getString("EMP_NAME");
				String gen = rs.getString("GENDER");
				int salary = rs.getInt("SALARY");
				String jobName = rs.getString("JOB_NAME");
				String deptTitle = rs.getString("DEPT_TITLE");

				System.out.printf("%-4s | %3s | %-4s | %7d | %-3s | %s \n", empId, empName, gen, salary, jobName,
						deptTitle);
			}

			if (flag) { // flag == true 인 경우 -> while문 수행 X -> 조회결과 없음
				System.out.println("조회 결과 없음");
			}
			

		} catch (Exception e) {
			e.printStackTrace();
			
			
		} finally {

			try {

				// 8. 사용한 JDBC 객체 자원 반환
				if (rs != null) rs.close();
				if (pstmt != null) pstmt.close();
				if (conn != null) conn.close();

			} catch (Exception e) {
				e.printStackTrace();
			}

		}

	}

}

0개의 댓글