JDBC (23.05.26~27)

·2023년 5월 26일
0

Java

목록 보기
32/35
post-thumbnail

📝 JDBC(Java DataBase Connectivity)

java가 DB와 연결할 수 있게 해 주는 java API

  • API(Application Programming Interface) : 프로그래밍 언어에서 사용자들이 사용할 수 있는 기술

  • Java를 이용해서 DB와 연결할 수는 있는데 어떤 DB와 어떻게 연결할지 모름
    -> 오라클 DBMS랑 연결하려면 Oracle JDBC Driver(클래스 파일)를 사용하면 됨
    - OJDBC11.jar (오라클에서 코드를 만들어서 줌 / 오라클 JDBC 드라이버 포함 라이브러리)

💡 OJDBC

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


✏️ 주요 개념

💡 Connection

DB 연결 정보를 담은 객체
-> Java와 DB 사이를 연결해 주는 일종의 통로(Stream과 비슷하게 생각)

💡 Statement

Connection 객체를 통해 Java에서 작성된 SQL을 DB로 전달하여 수행한 후 결과를 반환받아 다시 Java로 돌아오는 역할의 객체

💡 PreparedStatement

Statement의 자식으로 좀 더 향상된 기능을 제공
?(위치 홀더)를 이용하여 SQL에 작성되어지는 리터럴을 동적으로 제어함
-> 오타 위험 감소, 가독성 상승

💡 ResultSet

SELECT 질의 성공 시 반환되는 결과 행의 집합(Result Set)을 나타내는 객체


✏️ Statement와 PreparedStatement 비교

💡 SQL문 수행 순서

Statement

커넥션 생성 - SQL 작성 - Statement 객체 생성 - SQL 수행 후 결과 반환

PreparedStatement

커넥션 생성 - SQL 작성(? 사용) - PreparedStatement 객체 생성(SQL 적재) - 위치 홀더에 알맞은 값 대입 - SQL 수행 후 결과 반환

💡 SQL문 수행 후 결과 반환 받기

1. SELECT

Statement

stmt.executeQuery(sql);

PreparedStatement

pstmt.executeQuery(); <-- SQL 다시 담지 않음!!

2. DML

Statement

stmt.executeUpdate(sql);

PreparedStatement

pstmt.executeUpdate(); <-- SQL 다시 담지 않음!!


✏️ 예제 1 - Java로 SQL 조회해 보기 (1)

package edu.kh.jdbc.ex1;

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

public class JDBCExample1 {

	public static void main(String[] args) {
    
		// [1단계] : JDBC 객체 참조 변수 선언 (java.sql 패키지)
		
		Connection conn = null;
		// DB 연결 정보를 담은 객체
		// -> Java와 DB 사이를 연결해 주는 일종의 통로(Stream과 비슷하게 생각)
		
		Statement stmt = null;
		// Connection 객체를 통해
		// Java에서 작성된 SQL을 DB로 전달하여 수행한 후
		// 결과를 반환받아 다시 Java로 돌아오는 역할의 객체
		
		ResultSet rs = null;
		// SELECT 질의 성공 시 반환되는
		// 결과 행의 집합(Result Set)을 나타내는 객체
		
		try {
			
			// [2단계] 참조변수에 알맞은 객체 대입하기
			
			// 1. DB 연결에 필요한 Oracle JDBC Driver 메모리 로드하기
			// --> Oracle JDBC Driver가 어디에 있는지만 알려 주면 알아서 메모리 로드
			
			Class.forName("oracle.jdbc.driver.OracleDriver");
			// ClassNotFoundException 발생 가능성 있음
			
			// 2. 연결 정보를 담은 Connection을 생성
			// 	  (이때, DriverManager 객체가 필요함)
			// 	  DriverManager : JDBC 드라이버를 통해 Connection 객체를 만드는 역할
			
			String type = "jdbc:oracle:thin:@"; // JDBC 드라이버가 thin 타입
			
			String ip = "localhost"; // DB 서버 컴퓨터 IP
			// localhost == 127.0.0.1
			
			String port = ":1521";
			
			String sid = ":xe"; // DB 이름
			
			String user = "ash"; // 사용자명
			
			String pw = "ash1234"; // 비밀번호
	
			
			conn = DriverManager.getConnection(type + ip + port + sid, user, pw);
									// jdbc:oracle:thin:@localhost:1521:xe
			
			// 중간 확인
			System.out.println(conn); // oracle.jdbc.driver.T4CConnection@4961f6af

			
			// 3. Statement 객체에 적재할 SQL 작성하기
			// ***** java에서 작성된 SQL문은 마지막에 ;(세미콜론)을 찍지 않아야 한다.
			//	-> "유효하지 않은 문자" 오류를 발생시킴
			
			String sql = "SELECT EMP_ID, EMP_NAME, SALARY, DEPT_CODE FROM EMPLOYEE";
			
			// 4. Statement 객체 생성
			stmt = conn.createStatement();
			
			// 5. SQL을 Statement에 적재 후
			// 	  DB로 전달하여 수행한 후
			//	  결과를 반환받아 와 rs 변수에 대입
			rs = stmt.executeQuery(sql);
			
			// DB에서 SELECT 수행한 결과(ResultSet) 객체를 얻어와 rs가 참조하게 함
			
			// [3단계] SELECT 수행 결과를 한 행씩 접근하여
			//		  원하는 컬럼 값 얻어오기
			
			while(rs.next()) {
				// rs.next() : 참조하고 있는 ResultSet 객체의
				//			   첫 번째 컬럼부터 순서대로 한 행씩 이동하며
				//			   다음 행이 있을 경우 true를 반환
				
				// rs.get[Type]("컬럼명") : 현재 가리키고 있는 행의 특정 컬럼 값을 얻어옴
				// [Type]은 DB에서 얻어와서 Java에 저장할 자료형(Java 쪽 자료형)
				
				int empId = rs.getInt("EMP_ID");
				String empName = rs.getString("EMP_NAME");
				int salary = rs.getInt("SALARY");
				String deptCode = rs.getString("DEPT_CODE");
				
				// 조회 결과 출력
				System.out.printf("사번 : %d 이름 : %s 급여 : %7d 부서 코드 : %s \n",
									empId, empName, salary, deptCode);
				
			}
			
		} catch(SQLException e) {
			// SQLException : DB 연결 관련 예외의 최상위 부모
			e.printStackTrace();
			
		} catch(ClassNotFoundException e) {
			System.out.println("OJDBC 라이브러리 미등록 또는 경로 오타");
			e.printStackTrace();
			
		} finally {
			
			// [4단계] 사용한 JDBC 객체 자원 반환(close)
			// -> 자원 반환 순서는 객체 생성 순서의 "역순"으로
			// 생성 순서 : Connection, Statement, ResultSet
			// 반환 순서 : ResultSet, Statement, Connection
			
			try {
				// NullPointerException 방지를 위한 if문 추가
				if(rs != null) rs.close();
				if(stmt != null) stmt.close();
				if(conn != null) conn.close();
				
			} catch(SQLException e) {
				e.printStackTrace();
			}
			
		}
		
	}
	
}
  • 출력 화면

Oracle에 저장되어 있는 테이블의 SELECT 조회 결과 RESULT SET이 한 행씩 조회되는 모습을 볼 수 있다.

✏️ 예제 2 - Java로 SQL 조회해 보기 (2)

클래스 별 기능 설명

  • Run
    - 실행

  • View (손님)
    - 키보드 입력(Scanner)
    - 콘솔 화면 출력(Print)

  • Service (종업원)
    - 기능 제공 메소드

  • DAO (주방장)
    - DB 연결용 클래스 (SQL, JDBC)

  • VO
    - 값 저장용 객체

EmployeeRun 클래스

package edu.kh.jdbc.run;

import edu.kh.jdbc.view.EmployeeView;

public class EmployeeRun {

	public static void main(String[] args) {
		
		EmployeeView view = new EmployeeView();
		view.displayMenu();
	}

}

EmployeeView 클래스

package edu.kh.jdbc.view;

import java.util.ArrayList;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Scanner;

import edu.kh.jdbc.model.service.EmployeeService;
import edu.kh.jdbc.model.vo.Employee;

// View : 입, 출력 담당 클래스
// - 사용자 담당 인터페이스 요소로 사용자의 요청과 응답을 보여 주는 화면

public class EmployeeView {
	
	private Scanner sc = new Scanner(System.in);
	
	// 공통적으로 호출할 Service 객체를 필드에서 생성
	private EmployeeService service = new EmployeeService();
	
	/**
	 * 메인 메뉴 
	 */
	public void displayMenu() {
		
		int menuNum = -1;
		
		do {
			try {
				System.out.println();
	            System.out.println("====================================");
	            System.out.println("[사원 관리 프로그램]");
	            System.out.println("1. 전체 사원 정보 조회");
	            System.out.println("2. 사번으로 사원 정보 조회");
	            System.out.println("3. 새로운 사원 정보 추가");
	            System.out.println("4. 사번으로 사원 정보 수정");
	            System.out.println("5. 사번으로 사원 정보 삭제");
	            System.out.println("6. 입력 받은 급여 이상으로 받는 모든 직원 조회");
	            System.out.println("7. 부서 코드, 보너스율을 입력 받아 해당 부서의 보너스를 모두 수정");
	            // 메소드명 : updateBonus()
	            // [실행화면]
	            // 부서 코드를 입력하세요 : D1
	            // 보너스율을 입력하세요 : 0.3
	            
	            // (성공 시) : D1 부서의 보너스율이 0.3으로 변경되었습니다.
	            // (실패 시) : 일치하는 부서 코드가 존재하지 않습니다.
	            // 출력
	            
	            // DAO 작성 시 Statement 사용
	            
	            System.out.println("0. 프로그램 종료");
	            System.out.println("====================================");
	            
	            System.out.print("메뉴 선택 : ");
	            menuNum = sc.nextInt();
	            System.out.println();
	            
	            switch(menuNum) {
	            case 1 : selectAll(); break;
	            case 2 : selectOne(); break;
	            case 3 : insertEmployee(); break;
	            case 4 : updateEmployee(); break;
	            case 5 : deleteEmployee(); break;
	            case 6 : selectSalary(); break;
	            case 7 : updateBonus(); break;
	            case 0 :System.out.println("프로그램을 종료합니다..."); break;
	            default : System.out.println("잘못 입력하셨습니다. 다시 입력해 주세요.");
	            
	            }
	            
			} catch(InputMismatchException e) {
				System.out.println("입력 형식이 잘못되었습니다. 다시 시도해 주세요.");
				// menuNum = -1;
				sc.nextLine(); // 입력 버퍼에 남아 있는 잘못된 문자열 제거
			}
			
		} while(menuNum != 0);
		
	}
	
	/**
	 * 전체 사원 정보 조회 View
	 */
	public void selectAll() {
		System.out.println("[전체 사원 정보 조회]");
		
		// DB에서 조회해 온 사원 리스트를 출력
		
		// 1) 전체 사원 정보를 반환하는 서비스 메서드 호출
		List<Employee> empList = service.selectAll();
		
		// 2) 서비스 호출 결과를 출력용 메소드를 이용해서 출력
		printList(empList);
	}
	
	/**
	 * Employee List 출력용 View
	 * @param empList
	 */
	public void printList(List<Employee> empList) {
						// Employee 타입이 제한된 리스트 == Employee만 담긴 List
		
		if( empList.isEmpty() ) { // empList가 비어 있는 경우 == 조회 결과가 없을 경우
			System.out.println("조회 결과가 없습니다.");
			
		} else { // 비어 있지 않은 경우
			
			// 향상된 for문
			for(Employee emp : empList) {
				System.out.println(emp);
			}
		}
		
	}
	
	/**
	 * 사번 입력용 View (2, 4, 5번 메뉴에 필요)
	 * @return
	 */
	public int inputEmpId() {
		System.out.print("사번을 입력하세요 : ");
		int empNo = sc.nextInt();
		sc.nextLine();
		
		return empNo;
	}
	
	/**
	 * 사번으로 사원 정보 조회 View
	 */
	public void selectOne() {
		System.out.println("[사번으로 사원 정보 조회]");
	
		// 사번 입력 받기
		int input = inputEmpId();
		
		Employee emp = service.selectOne(input);
		
		List<Employee> empList = new ArrayList<Employee>();
		
		// emp가 참조하는 객체가 있는지 확인 == 조회 결과가 있는지 확인
		
		if(emp != null) {
			empList.add(emp);
		}
		
		printList(empList);
		
	}
	
	/**
	 * 입력 받은 급여 이상으로 받는 모든 직원 조회
	 */
	public void selectSalary() {
		
		System.out.println("[입력 받은 급여 이상으로 받는 모든 직원 조회]");
		
		System.out.print("급여를 입력하세요 : ");
		int input = sc.nextInt();
		sc.nextLine(); // 개행 문자 제거
		
		List<Employee> empList = service.selectSalary(input);
		
		printList(empList);
		
		System.out.println("총 인원 : " + empList.size() + "명");
	}
	
	/**
	 * 새로운 사원 정보 추가
	 */
	public void insertEmployee() {
		System.out.println("[새로운 사원 정보 추가]");
		
		System.out.print("사번 : ");
		int empId = sc.nextInt();
		
		System.out.print("이름 : ");
		String empName = sc.next();
		
		System.out.print("주민등록번호 : ");
		String empNo = sc.next();
		
		System.out.print("이메일 : ");
		String email = sc.next();
		
		System.out.print("전화번호 : ");
		String phone = sc.next();
		
		System.out.print("부서 코드(D1~ D9) : ");
		String deptCode = sc.next();
		
		System.out.print("직급 코드(J1~ J7) : ");
		String jobCode = sc.next();
		
		System.out.print("급여 : ");
		int salary = sc.nextInt();
		
		System.out.print("보너스율 : ");
		double bonus = sc.nextDouble();
		sc.nextLine();
		
		// 입력 받은 값을 Employee 객체에 저장
		Employee emp = new Employee(empId, empName, empNo, email, phone, deptCode, jobCode, salary, bonus);
		
		// 사원 정보 삽입 서비스 호출
		int result = service.insertEmployee(emp);
		
		if(result >= 0) { // 삽입 성공
			System.out.println("사원 정보가 추가되었습니다.");
		} else {
			System.out.println("사원 정보 추가 실패");
		}
	}
	
	
	/**
	 * 사번으로 사원 정보 삭제 View
	 */
	public void deleteEmployee() {
		
		// EMPLOYEE2 테이블에서
		// 사번을 입력받고 일치하는 사번을 가진 사원 정보 삭제(DELETE)
		
		// 조건 1 : PreparedStatement 사용
		// 조건 2 : 삭제 성공 시 --> "삭제되었습니다."
		//		   삭제 실패 시 --> "일치하는 사번의 사원이 없습니다." 출력
		
		System.out.println("[사번으로 사원 정보 삭제]");
		
		int input = inputEmpId();
		
		// DELETE(DML) 수행 시 결과 행의 개수가 반환됨
		int result = service.deleteEmployee(input);
		
		if(result > 0) {
			System.out.println("삭제되었습니다.");
		} else {
			System.out.println("일치하는 사번의 사원이 없습니다.");
		}
		
	}
	
	/**
	 * 사번으로 사원 정보 수정
	 */
	public void updateEmployee() {
		
		System.out.println("[사번으로 사원 정보 수정]");
		
		int empId = inputEmpId(); // 사번 입력 받는 메소드 호출 후 결과를 반환 받기
		
		// 이메일, 전화번호, 급여 입력 받기
		System.out.print("변경된 이메일 입력 : ");
		String email = sc.next();
		
		System.out.print("변경된 전화번호 입력(- 제외) : ");
		String phone = sc.next();
		
		System.out.print("변경된 급여 입력 : ");
		int salary = sc.nextInt();
		sc.nextLine(); // 입력 버퍼에 남은 개행 문자 제거
		
		// 입력된 내용을 Employee 객체를 생성해서 저장
		Employee emp = new Employee();

		// setter를 이용해서 세팅
		emp.setEmpId(empId);
		emp.setEmail(email);
		emp.setPhone(phone);
		emp.setSalary(salary);
		
		// 수정 == UPDATE == DML == 성공한 행의 개수가 반환 == int 자료형
		int result = service.updateEmployee(emp);
		
		if(result > 0) {
			System.out.println("사원 정보가 수정되었습니다.");
		}else {
			System.out.println("일치하는 사번의 사원이 없습니다.");
		}
	}
	
	/**
	 * 부서의 보너스를 모두 수정
	 */
	public void updateBonus() {
		
		System.out.println("[부서의 보너스를 모두 수정]");
		
		System.out.print("부서 코드를 입력하세요 : ");
		String deptCode = sc.next();
		
		System.out.print("보너스율을 입력하세요 : ");
		double bonus = sc.nextDouble();
		sc.nextLine();
		
		Employee emp = new Employee();
		emp.setDeptCode(deptCode);
		emp.setBonus(bonus);
		
		int result = service.updateBonus(emp);
		
		if(result > 0) {
			System.out.printf("%s 부서의 보너스율이 %.1f로 변경되었습니다.\n", deptCode, bonus);
		} else {
			System.out.println("일치하는 부서 코드가 존재하지 않습니다.");
		}
	}
}

EmployeeService 클래스

package edu.kh.jdbc.model.service;

import java.util.List;

import edu.kh.jdbc.model.dao.EmployeeDAO;
import edu.kh.jdbc.model.vo.Employee;


// Service : 요청에 맞는 기능을 수행하여 결과를 제공
// - 전달받은 데이터 또는 DAO 수행 결과 데이터를 필요한 형태로 가공 처리
/**
 * @author user1
 *
 */
public class EmployeeService {

	private EmployeeDAO dao = new EmployeeDAO();
	
	/**
	 * 전체 사원 정보 조회 서비스
	 * @return
	 */
	public List<Employee> selectAll() {
		
		// 별도 가공할 내용이 없으면 바로 DAO 호출
		List<Employee> empList = dao.selectAll();
		
		
		return empList;
	}

	/**
	 * 사번으로 사원 정보 조회 Service
	 * @param input
	 * @return
	 */
	public Employee selectOne(int input) {
		
		Employee emp = dao.selectOne(input);
		
		return emp; // DAO 호출 결과를 바로 View에 반환
	}

	/** 입력 받은 급여 이상으로 받는 모든 직원 조회 Service
	 * @param input
	 * @return
	 */
	public List<Employee> selectSalary(int input) {
		
		List<Employee> empList = dao.selectSalary(input);
		
		return empList;
	}

	/** 새로운 사원 정보 추가 Service
	 * @param emp
	 * @return
	 */
	public int insertEmployee(Employee emp) {
		
		int result = dao.insertEmployee(emp);
		
		return result; // INSERT 수행 결과 반환
	}

	/** 사번으로 사원 정보 삭제 Service
	 * @param input
	 * @return
	 */
	public int deleteEmployee(int input) {

		int result = dao.deleteEmployee(input);
		
		return result;
	}

	/** 사번으로 사원 정보 수정 Service
	 * @param emp
	 * @return
	 */
	public int updateEmployee(Employee emp) {
		
		// int result = dao.updateEmployee(emp);
		int result = dao.updateEmployee2(emp);
		return result;
	}

	/** 부서의 보너스를 모두 수정 Service
	 * @param emp
	 * @return
	 */
	public int updateBonus(Employee emp) {
		
		//int result = dao.updateBonus(emp);
		int result = dao.updateBonus2(emp);
		return result;
	}

}

EmployeeDAO 클래스

package edu.kh.jdbc.model.dao;

import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import edu.kh.jdbc.model.vo.Employee;

// DAO(Data Access Object) : 데이터 접근 객체
// - DB와 연결되어 SQL을 수행하고 결과를 반환받는 역할
public class EmployeeDAO {

	// JDBC 객체 저장용 참조 변수 필드 선언
	private Connection conn;
	// DB 연결 정보를 담은 객체(Java - DB 사이의 통로 역할)
	
	private Statement stmt;
	// Connection을 통해 SQL을 수행하고 결과를 반환받는 객체
	
	private PreparedStatement pstmt;
	// Statement의 자식으로 좀 더 향상된 기능을 제공
	// - ?(위치 홀더)를 이용하여 SQL에 작성되어지는 리터럴을 동적으로 제어함
	// --> 오타 위험 감소, 가독성 상승
	
	private ResultSet rs;
	// SELECT 수행 후 반환되는 객체
	
	
	/**
	 * 전체 사원 정보 조회 DAO
	 * @return
	 */
	public List<Employee> selectAll() {
		
		// 결과 저장용 변수 준비
		List<Employee> empList = new ArrayList<Employee>();
		
		try {
			// 1) Oracle JDBC Driver 메모리 로드
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			// 2) DB 연결 작업(Connection 얻어오기)
			String type = "jdbc:oracle:thin:@"; // JDBC 드라이버가 thin 타입
			
			String ip = "localhost"; // DB 서버 컴퓨터 IP
			String port = ":1521";
			String sid = ":xe"; // DB 이름
			String user = "ash"; // 사용자명
			String pw = "ash1234"; // 비밀번호
			conn = DriverManager.getConnection(type + ip + port + sid, user, pw);
			// DriverManager : Connection 생성 메소드 제공
			
			// 3) 수행할 SQL 작성
			String sql = "SELECT * FROM EMPLOYEE_COPY ORDER BY EMP_ID";
						// *** SQL 작성 시 세미콜론은 없어야 된다!! ***
			
			// 4) Statement 객체 생성
			stmt = conn.createStatement(); // 커넥션을 왔다 갔다 하는 셔틀 버스 같은 역할
			
			// 5) SQL 수행 후 결과(ResultSet) 반환 받기
			rs = stmt.executeQuery(sql);
			// executeQuery() : SELECT문 수행 후 ResultSet 결과를 반환
			
			// 6) 결과를 List에 옮겨 담기
			// -> ResultSet을 한 행씩 접근하여 컬럼 값을 얻어와
			//	  한 행의 정보가 담긴 Employee 객체를 생성하고
			//	  이를 empList에 추가
			
			while(rs.next()) {
				// rs.next() : 다음 행이 있으면 true, 호출 시마다 다음 행으로 이동
				
				int empId = rs.getInt("EMP_ID"); // 현재 행의 EMP_ID 컬럼 값을 int 자료형으로 얻어옴
				String empName = rs.getString("EMP_NAME");
				String empNo = rs.getString("EMP_NO");
				String email = rs.getString("EMAIL");
				String phone = rs.getString("PHONE");
				String deptCode = rs.getString("DEPT_CODE");
				String jobCode = rs.getString("JOB_CODE");
				String salLevel = rs.getString("SAL_LEVEL");
				int salary = rs.getInt("SALARY");
				double bonus = rs.getDouble("BONUS"); // 실수형
				int managerId = rs.getInt("MANAGER_ID");
				Date hireDate = rs.getDate("HIRE_DATE");
				Date entDate = rs.getDate("ENT_DATE");
				char entYn = rs.getString("ENT_YN").charAt(0);
			
				// rs.getChar()는 존재하지 않음
				// 왜? 자바에서는 문자 하나(char) 개념이 있지만
				//	   DB에서는 오로지 문자열 개념만 존재함
				// -> String.charAt(0)을 이용함
				
				// 얻어온 컬럼 값으로 객체 생성 후 초기화
				
				Employee emp = new Employee(empId, empName, empNo, email, phone,
											deptCode, jobCode, salLevel, salary,
											bonus, managerId, hireDate, entDate, entYn);
						
				// empList에 추가
				empList.add(emp);
				
				
				
			}
			
			
		} catch(Exception e) {
			// Exception : 모든 예외의 최상위 부모
			// -> try에서 발생하는 모든 예외를 잡아서 처리
			e.printStackTrace();
			
		} finally {
			
			// 7) 사용한 JDBC 자원 반환(close)
			// -> 이때 생성 역순으로 반환하는 게 좋다!
			
				try {
					if(rs != null) rs.close();
					if(stmt != null) stmt.close();
					if(conn != null) conn.close();
					
				} catch (SQLException e) {
					e.printStackTrace();
				}
			
		}

		// 8) List 호출부로 반환
		
		return empList;
	}


	/** 사번으로 사원 정보 조회 DAO
	 * @param input
	 * @return
	 */
	public Employee selectOne(int input) {
		
		Employee emp = null; // 결과 저장용 변수
		
		try {
			
			Class.forName("oracle.jdbc.driver.OracleDriver"); // 드라이버 메모리 로드
			
			String type = "jdbc:oracle:thin:@"; // JDBC 드라이버가 thin 타입
			String ip = "localhost"; // 접속할 아이피
			String port = ":1521";
			String sid = ":xe"; // 접속할 DB 이름
			String user = "ash"; // 사용자 계정 명
			String pw = "ash1234"; // 사용자 계정 비밀번호
			
			// 커넥션 생성
			conn = DriverManager.getConnection(type + ip + port + sid, user, pw);
			
			// SQL 준비
			String sql = "SELECT * FROM EMPLOYEE WHERE EMP_ID = " + input;
			
			// Statement 생성
			stmt = conn.createStatement();
			
			// SQL 수행 후 결과 반환 받기
			rs= stmt.executeQuery(sql);
			
			// 조회 결과가 있다면 1행 밖에 나오지 않으므로
			// while 대신 if문을 사용한다.
			if(rs.next()) {
				// 조회 결과가 있으면 rs.next() == true --> if문 수행
				
				// 조회 결과가 없으면 rs.next() == false --> if문 수행 X --> Employee 객체 생성 X
			
				int empId = rs.getInt("EMP_ID"); // 현재 행의 EMP_ID 컬럼 값을 int 자료형으로 얻어옴
				String empName = rs.getString("EMP_NAME");
				String empNo = rs.getString("EMP_NO");
				String email = rs.getString("EMAIL");
				String phone = rs.getString("PHONE");
				String deptCode = rs.getString("DEPT_CODE");
				String jobCode = rs.getString("JOB_CODE");
				String salLevel = rs.getString("SAL_LEVEL");
				int salary = rs.getInt("SALARY");
				double bonus = rs.getDouble("BONUS"); // 실수형
				int managerId = rs.getInt("MANAGER_ID");
				Date hireDate = rs.getDate("HIRE_DATE");
				Date entDate = rs.getDate("ENT_DATE");
				char entYn = rs.getString("ENT_YN").charAt(0);
			
				// rs.getChar()는 존재하지 않음
				// 왜? 자바에서는 문자 하나(char) 개념이 있지만
				//	   DB에서는 오로지 문자열 개념만 존재함
				// -> String.charAt(0)을 이용함
				
				// 얻어온 컬럼 값으로 객체 생성 후 초기화
				
				emp = new Employee(empId, empName, empNo, email, phone,
									deptCode, jobCode, salLevel, salary,
									bonus, managerId, hireDate, entDate, entYn);
			
			}
			
			
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
	
			// 사용한 JDBC 객체 자원 반환(생성 역순)
			try {
				if(rs != null) rs.close();
				if(stmt != null) stmt.close();
				if(conn != null) conn.close();
				
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
		// 조회 결과가 있으면 Employee 객체 주소
		// 없으면 null 반환
		return emp;
	}


	/**
	 * 입력 받은 급여 이상으로 받는 모든 직원 조회 DAO
	 * @param input
	 * @return
	 */
	public List<Employee> selectSalary(int input) {
		
		List<Employee> empList = new ArrayList<Employee>();
				
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			// 2) DB 연결 작업(Connection 얻어오기)
			String type = "jdbc:oracle:thin:@"; // JDBC 드라이버가 thin 타입
			
			String ip = "localhost"; // DB 서버 컴퓨터 IP
			String port = ":1521";
			String sid = ":xe"; // DB 이름
			String user = "ash"; // 사용자명
			String pw = "ash1234"; // 비밀번호
			conn = DriverManager.getConnection(type + ip + port + sid, user, pw);

			String sql = "SELECT * FROM EMPLOYEE_COPY WHERE SALARY >= " + input;
			
			stmt = conn.createStatement();
			
			rs = stmt.executeQuery(sql);
			
			
			while(rs.next()) {
				// rs.next() : 다음 행이 있으면 true, 호출 시마다 다음 행으로 이동
				
				int empId = rs.getInt("EMP_ID"); // 현재 행의 EMP_ID 컬럼 값을 int 자료형으로 얻어옴
				String empName = rs.getString("EMP_NAME");
				String empNo = rs.getString("EMP_NO");
				String email = rs.getString("EMAIL");
				String phone = rs.getString("PHONE");
				String deptCode = rs.getString("DEPT_CODE");
				String jobCode = rs.getString("JOB_CODE");
				String salLevel = rs.getString("SAL_LEVEL");
				int salary = rs.getInt("SALARY");
				double bonus = rs.getDouble("BONUS"); // 실수형
				int managerId = rs.getInt("MANAGER_ID");
				Date hireDate = rs.getDate("HIRE_DATE");
				Date entDate = rs.getDate("ENT_DATE");
				char entYn = rs.getString("ENT_YN").charAt(0);
			
				Employee emp = new Employee(empId, empName, empNo, email, phone,
											deptCode, jobCode, salLevel, salary,
											bonus, managerId, hireDate, entDate, entYn);
						
				empList.add(emp);
				
			}
			
		} catch(Exception e){
			e.printStackTrace();
			
		} finally {
			
			try {
				if(rs != null) rs.close();
				if(stmt != null) stmt.close();
				if(conn != null) conn.close();
				
			} catch (SQLException e) {
				e.printStackTrace();
			}
			
		}
		
		return empList;
	}


	/** 새로운 사원 정보 추가 DAO
	 * @param emp
	 * @return
	 */
	public int insertEmployee(Employee emp) {
		
		int result = 0; // 결과 저장용 변수
		
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver"); // 오라클 JDBC 드라이버 메모리 로드
			
			String type = "jdbc:oracle:thin:@"; // JDBC 드라이버가 thin 타입
			String ip = "localhost"; // DB 서버 컴퓨터 IP
			String port = ":1521";
			String sid = ":xe"; // DB 이름
			String user = "ash"; // 사용자명
			String pw = "ash1234"; // 비밀번호
			
			// 커넥션 생성
			conn = DriverManager.getConnection(type + ip + port + sid, user, pw);
			// --> 생성된 커넥션을 이용해 SQL을 수행하면 자동 커밋이 된다. (기본값)
			// --> 자동 커밋 기능을 끄고 개발자가 트랜잭션을 직접 제어하는 것이 좋음
			
			conn.setAutoCommit(false); // 자동 커밋 기능 비활성화
			// --> 자동 커밋을 비활성화 시켜도
			//		conn.close()가 실행되면 남은 트랜잭션 내용이 모두 commit 된다.
			
			// SQL 작성
			String sql = "INSERT INTO EMPLOYEE2 VALUES(?, ?, ?, ?, ?, ?, ?, 'S5', ?, ?, 200, SYSDATE, NULL, 'N')";
							// ? 기호 == 위치 홀더
			
			// Statement : 커넥션 생성 - SQL 작성 - Statement 객체 생성 - SQL 수행 후 결과 반환
			
			// PreparedStatement : 커넥션 생성 - SQL 작성(? 사용) - PreparedStatement 객체 생성(SQL 적재)
			//						- 위치 홀더에 알맞은 값 대입 - SQL 수행 후 결과 반환
			
			// PreparedStatement 객체 생성(SQL 적재)
			pstmt = conn.prepareStatement(sql);
			
			// 위치 홀더에 알맞은 값 대입
			// pstmt.set[Type](위치 홀더 순서, 값)
			
			pstmt.setInt(1, emp.getEmpId()); // 입력 받은 사번을 1번 ?(위치 홀더)에 세팅
			pstmt.setString(2, emp.getEmpName());
			pstmt.setString(3, emp.getEmpNo());
			pstmt.setString(4, emp.getEmail());
			pstmt.setString(5, emp.getPhone());
			pstmt.setString(6, emp.getDeptCode());
			pstmt.setString(7, emp.getJobCode());
			pstmt.setInt(8, emp.getSalary());
			pstmt.setDouble(9, emp.getBonus());
			
			// SQL 수행 후 결과 반환 받기
			// 1) Statement - SELECT			 : stmt.executeQuery(sql);
			// 2) PreparedStatement - SELECT	 : pstmt.executeQuery(); <-- SQL 다시 담지 않음!!
			
			// **** DML 수행 시 executeUpdate 사용 ****
			// 3) Statement - DML				 : stmt.executeUpdate(sql);
			// 4) PreparedStatement - DML		 : pstmt.excuteUpdate(); <-- SQL 다시 담지 않음!!
			
			result = pstmt.executeUpdate(); // INSERT, UPDATE, DELETE가 성공한 행의 개수를 반환
												// 조건에 맞는 행이 없으면 0 반환
			
			// ********** 트랜잭션 제어 **********
			if(result > 0) conn.commit(); // DML 성공 시 commit 수행
			else		   conn.rollback(); // DML 실패 시 rollback 수행
			
		} catch(Exception e) {
			e.printStackTrace();
		} finally {
			
			try {
				if(pstmt != null) pstmt.close();
				if(conn != null) conn.close();
				
			} catch(SQLException e) {
				e.printStackTrace();
			}
		}
		
		return result;
	}


	/** 사번으로 사원 정보 삭제 DAO
	 * @param input
	 * @return
	 */
	public int deleteEmployee(int input) {
		
		int result = 0;
		
		try {
			
			Class.forName("oracle.jdbc.driver.OracleDriver"); // 오라클 JDBC 드라이버 메모리 로드
			
			String type = "jdbc:oracle:thin:@"; // JDBC 드라이버가 thin 타입
			String ip = "localhost"; // DB 서버 컴퓨터 IP
			String port = ":1521";
			String sid = ":xe"; // DB 이름
			String user = "ash"; // 사용자명
			String pw = "ash1234"; // 비밀번호
			
			// 커넥션 생성
			conn = DriverManager.getConnection(type + ip + port + sid, user, pw);
			conn.setAutoCommit(false); // 자동 커밋 비활성화
			// -> 활성화 상태일 경우 SQL이 수행되자마자 commit이 되어 버림
			
			String sql = "DELETE FROM EMPLOYEE2 WHERE EMP_ID = ?";
			
			// PreparedStatement 생성(SQL 적재)
			pstmt = conn.prepareStatement(sql);
			
			// 위치 홀더에 알맞은 값 대입
			pstmt.setInt(1, input);
			
			result = pstmt.executeUpdate();
			
			if(result > 0) conn.commit();
			else		   conn.rollback();
			
		} catch(Exception e) {
			e.printStackTrace();
			
		} finally {
			
			try {
				if(pstmt != null) pstmt.close();
				if(conn != null) conn.close();
				
			} catch(SQLException e) {
				e.printStackTrace();
			}
			
		}
		
		return result;
	}


	/** 사번으로 사원 정보 수정 DAO (PreparedStatement)
	 * @param emp
	 * @return
	 */
	public int updateEmployee(Employee emp) {
		
		int result = 0; // 결과 저장용 변수
		
		try {
			
			// Oracle JDBC Driver 메모리 로드
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			// 커넥션 생성
			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "ash", "ash1234");
			
			// 자동 커밋 비활성화
			conn.setAutoCommit(false);
			
			// sql 작성 (위치 홀더 포함)
			String sql = "UPDATE EMPLOYEE2 SET EMAIL = ?, PHONE = ?, SALARY = ? WHERE EMP_ID = ?";
			
			// PreparedStatement 생성
			pstmt = conn.prepareStatement(sql);
			
			// 위치 홀더에 알맞은 값 대입
			
			// setString()을 통해 위치 홀더에 문자열 값을 대입하면
			// 문자열 양쪽에 ''(홑따옴표)가 포함된 상태로 추가된다.
			
			// ex) pstmt.setString(1, "abc");
			// 			 --> 위치 홀더 자리 'abc'
			
			pstmt.setString(1, emp.getEmail());
			pstmt.setString(2, emp.getPhone());
			
			// setInt()는 '' 붙지 않음
			pstmt.setInt(3, emp.getSalary());
			pstmt.setInt(4, emp.getEmpId());
			
			// SQL 수행
			// pstmt.executeQuery(); // SELECT 수행
			result = pstmt.executeUpdate(); // DML(INSERT, UPDATE, DELETE) 수행
			
			if(result > 0) conn.commit();
			else		   conn.rollback();

		} catch(Exception e) {
			e.printStackTrace();
			
		} finally {
			
			try {
				if(pstmt != null) pstmt.close();
				if(conn != null) conn.close();
				
			} catch(SQLException e) {
				e.printStackTrace();
			}
			
		}
		return result;
	}


	/** 사번으로 사원 정보 수정2 DAO (Statement)
	 * @param emp
	 * @return
	 */
	public int updateEmployee2(Employee emp) {
		
		int result = 0;
		
		try {
			
			Class.forName("oracle.jdbc.driver.OracleDriver"); 
			
			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "ash", "ash1234");
			
			// 자동 커밋 비활성화
			conn.setAutoCommit(false);
			
			// SQL 작성
			String sql = "UPDATE EMPLOYEE2 SET EMAIL = '" + emp.getEmail() + "', "
						+ "PHONE = " + emp.getPhone() + ", "
						+ "SALARY = " + emp.getSalary()
						+ " WHERE EMP_ID = " + emp.getEmpId();
			
			// Statement 객체 생성
			stmt = conn.createStatement();
			
			// SQL 수행
			result = stmt.executeUpdate(sql);
			
			// 트랜잭션 수행
			if(result > 0) conn.commit();
			else		   conn.rollback();
			
		} catch(Exception e) {
			e.printStackTrace();
			
		} finally {
			
			try {
				if(stmt != null) stmt.close();
				if(conn != null) conn.close();
				
			}catch(SQLException e) {
				e.printStackTrace();
			}
		}
		
		return result;
	}


	/** 부서의 보너스를 모두 수정 DAO (Statement)
	 * @param emp
	 * @return
	 */
	public int updateBonus(Employee emp) {

		int result = 0;
		
		try {
			// oracle jdbc driver 메모리 로드
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			// 커넥션 생성
			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hsn", "hsn1234");
			
			// 자동 커밋 비활성화
			conn.setAutoCommit(false);
			
			String sql = "UPDATE EMPLOYEE2 SET"
						+ " BONUS = " + emp.getBonus()
						+ " WHERE DEPT_CODE = '" + emp.getDeptCode() + "'";
			
			stmt = conn.createStatement();
			
			result = stmt.executeUpdate(sql);
			
			if(result > 0) conn.commit();
			else		   conn.rollback();
			
			
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			
			try {
				if(stmt != null) stmt.close();
				if(conn != null) conn.close();
				
			}catch(SQLException e) {
				e.printStackTrace();
			}
			
		}
		
		return result;
	}


	/** 부서의 보너스를 모두 수정 DAO (PreparedStatement)
	 * @param emp
	 * @return
	 */
	public int updateBonus2(Employee emp) {
		
		int result = 0;
		
		try {
			
			// oracle jdbc driver 메모리 로드
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			// 커넥션 생성
			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "ash", "ash1234");
			
			// 자동 커밋 비활성화
			conn.setAutoCommit(false);

			String sql = "UPDATE EMPLOYEE2 SET BONUS = ? WHERE DEPT_CODE = ?";
			
			pstmt = conn.prepareStatement(sql);
			
			pstmt.setDouble(1, emp.getBonus());
			pstmt.setString(2, emp.getDeptCode());
			
			result = pstmt.executeUpdate();
			
			if(result > 0) conn.commit();
			else		   conn.rollback();
			
		}catch(Exception e) {
			e.printStackTrace();
		}finally {
			try {
				
				if(pstmt != null) pstmt.close();
				if(conn != null) conn.close();
				
			}catch(SQLException e) {
				e.printStackTrace();
			}
		}
		
		return result;
	}

}

Employee 클래스

package edu.kh.jdbc.model.vo;

import java.sql.Date;

public class Employee {
	
	private int empId; // 사번
	private String empName; // 이름
	private String empNo; // 주민등록번호
	private String email; // 이메일
	private String phone; // 전화번호
	private String deptCode; // 부서 코드
	private String jobCode; // 직급 코드
	private String salLevel; // 급여 등급
	private int salary; // 급여
	private double bonus; // 보너스율
	private int managerId; // 관리자 사번
	private Date hireDate; // 입사일(java.sql.Date)
	private Date entDate; // 퇴사일
	private char entYn; // 퇴직 여부
	
	
	public Employee() {} // 기본 생성자

	public Employee(int empId, String empName, String empNo, String email, String phone, String deptCode,
			String jobCode, String salLevel, int salary, double bonus, int managerId, Date hireDate, Date entDate,
			char entYn) {
		super();
		this.empId = empId;
		this.empName = empName;
		this.empNo = empNo;
		this.email = email;
		this.phone = phone;
		this.deptCode = deptCode;
		this.jobCode = jobCode;
		this.salLevel = salLevel;
		this.salary = salary;
		this.bonus = bonus;
		this.managerId = managerId;
		this.hireDate = hireDate;
		this.entDate = entDate;
		this.entYn = entYn;
	}
	

	public Employee(int empId, String empName, String empNo, String email, String phone, String deptCode,
			String jobCode, int salary, double bonus) {
		super();
		this.empId = empId;
		this.empName = empName;
		this.empNo = empNo;
		this.email = email;
		this.phone = phone;
		this.deptCode = deptCode;
		this.jobCode = jobCode;
		this.salary = salary;
		this.bonus = bonus;
	}

	public int getEmpId() {
		return empId;
	}

	public void setEmpId(int empId) {
		this.empId = empId;
	}

	public String getEmpName() {
		return empName;
	}

	public void setEmpName(String empName) {
		this.empName = empName;
	}

	public String getEmpNo() {
		return empNo;
	}

	public void setEmpNo(String empNo) {
		this.empNo = empNo;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public String getDeptCode() {
		return deptCode;
	}

	public void setDeptCode(String deptCode) {
		this.deptCode = deptCode;
	}

	public String getJobCode() {
		return jobCode;
	}

	public void setJobCode(String jobCode) {
		this.jobCode = jobCode;
	}

	public String getSalLevel() {
		return salLevel;
	}

	public void setSalLevel(String salLevel) {
		this.salLevel = salLevel;
	}

	public int getSalary() {
		return salary;
	}

	public void setSalary(int salary) {
		this.salary = salary;
	}

	public double getBonus() {
		return bonus;
	}

	public void setBonus(double bonus) {
		this.bonus = bonus;
	}

	public int getManagerId() {
		return managerId;
	}

	public void setManagerId(int managerId) {
		this.managerId = managerId;
	}

	public Date getHireDate() {
		return hireDate;
	}

	public void setHireDate(Date hireDate) {
		this.hireDate = hireDate;
	}

	public Date getEntDate() {
		return entDate;
	}

	public void setEntDate(Date entDate) {
		this.entDate = entDate;
	}

	public char getEntYn() {
		return entYn;
	}

	public void setEntYn(char entYn) {
		this.entYn = entYn;
	}

	@Override
	public String toString() {
		return "Employee [empId=" + empId + ", empName=" + empName + ", empNo=" + empNo + ", email=" + email
				+ ", phone=" + phone + ", deptCode=" + deptCode + ", jobCode=" + jobCode + ", salLevel=" + salLevel
				+ ", salary=" + salary + ", bonus=" + bonus + ", managerId=" + managerId + ", hireDate=" + hireDate
				+ ", entDate=" + entDate + ", entYn=" + entYn + ", getClass()=" + getClass() + ", hashCode()="
				+ hashCode() + ", toString()=" + super.toString() + "]";
	}
	
}
profile
풀스택 개발자 기록집 📁

0개의 댓글