java가 DB와 연결할 수 있게 해 주는 java API
- API(Application Programming Interface) : 프로그래밍 언어에서 사용자들이 사용할 수 있는 기술
오라클에서 제공하는 오라클 DB와 자바가 연결하기 위한 라이브러리
-> Oracle JDBC Driver 제공
DB 연결 정보를 담은 객체
-> Java와 DB 사이를 연결해 주는 일종의 통로(Stream과 비슷하게 생각)
Connection 객체를 통해 Java에서 작성된 SQL을 DB로 전달하여 수행한 후 결과를 반환받아 다시 Java로 돌아오는 역할의 객체
Statement의 자식으로 좀 더 향상된 기능을 제공
?(위치 홀더)를 이용하여 SQL에 작성되어지는 리터럴을 동적으로 제어함
-> 오타 위험 감소, 가독성 상승
SELECT 질의 성공 시 반환되는 결과 행의 집합(Result Set)을 나타내는 객체
커넥션 생성 - SQL 작성 - Statement 객체 생성 - SQL 수행 후 결과 반환
커넥션 생성 - SQL 작성(? 사용) - PreparedStatement 객체 생성(SQL 적재) - 위치 홀더에 알맞은 값 대입 - SQL 수행 후 결과 반환
stmt.executeQuery(sql);
pstmt.executeQuery(); <-- SQL 다시 담지 않음!!
stmt.executeUpdate(sql);
pstmt.executeUpdate(); <-- SQL 다시 담지 않음!!
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이 한 행씩 조회되는 모습을 볼 수 있다.
Run
- 실행
View (손님)
- 키보드 입력(Scanner)
- 콘솔 화면 출력(Print)
Service (종업원)
- 기능 제공 메소드
DAO (주방장)
- DB 연결용 클래스 (SQL, JDBC)
VO
- 값 저장용 객체
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();
}
}
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("일치하는 부서 코드가 존재하지 않습니다.");
}
}
}
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;
}
}
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;
}
}
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() + "]";
}
}