테이블

더보기
DROP TABLE salary PURGE;
DROP TABLE employee PURGE;

-- 임플로이 테이블
CREATE  TABLE  employee(
    sabeon  VARCHAR2(30) PRIMARY KEY
    ,name   VARCHAR2(30) NOT NULL
    ,birth    DATE NOT NULL
    ,tel       VARCHAR2(30) 
);

-- 셀러리 테이블
CREATE  TABLE  salary(
    salaryNum        NUMBER  PRIMARY KEY
    ,sabeon            VARCHAR2(30) NOT NULL
    ,payDate           VARCHAR2(30) NOT NULL
    ,paymentDate   DATE NOT NULL
    ,pay                  NUMBER(8)
    ,sudang             NUMBER(8)
    ,tax                   NUMBER(8)
    ,memo            VARCHAR2(1000)
    ,CONSTRAINT fk_salary_sabeon FOREIGN KEY(sabeon)
                          REFERENCES  employee(sabeon)
);

SELECT * FROM tab;

-- DROP SEQUENCE salary_seq;

CREATE SEQUENCE salary_seq
    INCREMENT BY 1
    START WITH 1
    NOMAXVALUE
    NOCYCLE
    NOCACHE;

SELECT * FROM seq;

 

App

더보기
package db.employee;

import java.util.Scanner;

import db_util.DBConn;

public class App {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		
		Employee emp=new Employee();
		Salary sal=new Salary(emp);
		
		System.out.println("인사관리 프로그램");
		
		int ch;
		while(true) {
			System.out.println("\n[Main]");
			do {
				System.out.print("1.사원관리 2.급여관리 3.종료 => ");
				ch = sc.nextInt();
			}while(ch<1||ch>3);
			
			if(ch==3) break;
			
			switch(ch) {
			case 1:emp.employeeManage();break;
			case 2:sal.salaryManage();break;
			}
		}

		sc.close();
		DBConn.close(); 
	}
}

Employee

더보기
package db.employee;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class Employee {
	private BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
	private EmployeeDAO dao=new EmployeeDAO();
	
	public void employeeManage() {
		int ch = 0;
		while(true) {
			System.out.println("\n[사원관리]");
			
			do {
				System.out.print("1.사원등록 2.정보수정 3.사번검색 4.이름검색 5.리스트 6.메인 => ");
				try {
					ch = Integer.parseInt(br.readLine());
				} catch (Exception e) {
				}
			}while(ch<1||ch>6);
			
			if(ch==6) return;
			
			switch(ch) {
			case 1: insert(); break;
			case 2: update(); break;
			case 3: searchSabeon(); break;
			case 4: searchName(); break;
			case 5: list(); break;
			}
		}
	}
	
	public void insert() {
		System.out.println("\n사원 등록...");
		EmployeeDTO dto = new EmployeeDTO();
		int result = 0;
		try {
			System.out.println("사원등록을 시작합니다.");
			
			System.out.print("사번을 입력해주세요 > ");
			dto.setSabeon(br.readLine());
			System.out.print("이름을 입력해주세요 > ");
			dto.setName(br.readLine());
			System.out.print("생년월일을 입력해주세요 > ");
			dto.setBirth(br.readLine());
			System.out.print("전화번호를 입력해주세요(선택) > ");
			dto.setTel(br.readLine());
			
			result = dao.insertEmployee(dto);
			if (result > 0) {
				System.out.println("사원 등록을 완료했습니다.");
				System.out.println();				
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("사원 등록에 실패했습니다.");
		}
		
	}
	
	public void update() {
		System.out.println("\n사원 정보 수정...");
		int result = 0;
		String sabeon;
		
		try {
			System.out.print("수정할 사번을 입력해주세요 > ");
			sabeon = br.readLine();
			
			EmployeeDTO dto = dao.readEmployee(sabeon);
			if( dto == null) {
				System.out.println("등록되어있는 사번이 없습니다.");
				return;
			}
			
			System.out.print("수정할 이름을 입력하세요 > ");
			dto.setName(br.readLine());
			System.out.print("수정할 생년월일을 입력하세요 > ");
			dto.setBirth(br.readLine());
			System.out.print("수정할 전화번호를 입력하세요(선택) > ");
			dto.setTel(br.readLine());
			
			result = dao.updateEmployee(dto);
			if ( result > 0) {
				System.out.println("정보를 수정했습니다.");
			}
		} catch (Exception e) {
			System.out.println("정보 수정에 실패했습니다.");
			e.printStackTrace();
		}
		System.out.println();
	}
	
	public void searchSabeon() {
		System.out.println("\n사번 검색...");
		
		String sabeon;
		try {
			System.out.println("검색할 사번을 입력하세요 > ");
			sabeon = br.readLine();
			EmployeeDTO dto = dao.readEmployee(sabeon);
			System.out.println("사번\t이름\t생년월일\t\t전화번호");
			System.out.println("-------------------------------------------------");
			System.out.print(dto.getSabeon()+"\t");
			System.out.print(dto.getName()+"\t");
			System.out.print(dto.getBirth()+"\t");
			System.out.println(dto.getTel());
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println();
	}

	public void searchName() {
		System.out.println("\n이름 검색...");
		
		String name;
		List<EmployeeDTO> list = new ArrayList<EmployeeDTO>();
		
		
		try {
			System.out.print("검색할 이름을 입력하세요 > ");
			name = br.readLine();
			list = dao.listEmployee(name);
			
			System.out.println("사번\t이름\t생년월일\t\t전화번호");
			System.out.println("-------------------------------------------------");
			for(EmployeeDTO dto : list) {
				System.out.print(dto.getSabeon()+"\t");
				System.out.print(dto.getName()+"\t");
				System.out.print(dto.getBirth()+"\t");
				System.out.println(dto.getTel());
			}
			System.out.println();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
	public void list() {
		System.out.println("\n사원 리스트...");
		
		List<EmployeeDTO> list = new ArrayList<EmployeeDTO>();
		list = dao.listEmployee();
		System.out.println("사번\t이름\t생년월일\t\t전화번호");
		System.out.println("-------------------------------------------------");
		for(EmployeeDTO dto : list) {
			System.out.print(dto.getSabeon()+"\t");
			System.out.print(dto.getName()+"\t");
			System.out.print(dto.getBirth()+"\t");
			System.out.println(dto.getTel());
		}
		System.out.println();
	}
	
}

EmployeeDAO

더보기
package db.employee;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLDataException;
import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.ArrayList;
import java.util.List;

import db_util.DBConn;

public class EmployeeDAO {
	private Connection conn=DBConn.getConnection();
	
	public int insertEmployee(EmployeeDTO dto) throws SQLException {
		int result=0;
		PreparedStatement pstmt = null;
		String sql;
		
		try {
			sql = "INSERT INTO employee(sabeon, name, birth, tel) VALUES (?,?,?,?) ";
			pstmt = conn.prepareStatement(sql);
			
			pstmt.setString(1, dto.getSabeon());
			pstmt.setString(2, dto.getName());
			pstmt.setString(3, dto.getBirth());
			pstmt.setString(4, dto.getTel());
			
			result = pstmt.executeUpdate();
			
		} catch (SQLIntegrityConstraintViolationException e) {
			if(e.getErrorCode()==1) {
				System.out.println("사번 중복 입니다.");
			} else if(e.getErrorCode()==1400) { // NOT NULL 위반
				System.out.println("필수 사항을 입력 하지 않았습니다.");
			} else {
				System.out.println(e.toString());
			}
			throw e;
		} catch (SQLDataException e) {
			if(e.getErrorCode()==1861 || e.getErrorCode()==1840) { 
				System.out.println("날짜 형식이 잘못 되었습니다.");
			} else {
				System.out.println(e.toString());
			}
			throw e;
		} catch (SQLException e) {
			e.printStackTrace();
			throw e;
		} finally {
			if (pstmt != null) {
				try {
					pstmt.close();
				} catch (Exception e2) {
				}
			}
		}
		
		return result;
	}
	
	public int updateEmployee(EmployeeDTO dto) throws SQLException {
		int result=0;
		PreparedStatement pstmt = null;
		String sql;
		
		try {
			sql = " UPDATE employee SET name=?, birth=?, tel=? WHERE sabeon=?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, dto.getName());
			pstmt.setString(2, dto.getBirth());
			pstmt.setString(3, dto.getTel());
			pstmt.setString(4, dto.getSabeon());
			
			result = pstmt.executeUpdate();
			
		} catch (SQLIntegrityConstraintViolationException e) {
			if(e.getErrorCode()==1400) {
				System.out.println("필수 입력 사항을 입력하지 않았습니다.");
			} else {
				System.out.println(e.toString());
			}
			throw e;
		} catch (SQLDataException e) {
			if(e.getErrorCode()==1840||e.getErrorCode()==1861) {
				System.out.println("날짜 형식이 올바르지 않습니다.");
			} else {
				System.out.println(e.toString());
			}
			throw e;
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if ( pstmt != null) {
				try {
					pstmt.close();
				} catch (Exception e2) {
				}
			}
		}
		
		return result;
	}
	
	public EmployeeDTO readEmployee(String sabeon) {
		EmployeeDTO dto= new EmployeeDTO();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql;
		
		try {
			sql = " SELECT sabeon, name, birth, NVL(tel, '입력안함') 번호 "
					+" FROM employee "
					+" WHERE sabeon = ?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, sabeon);
			
			rs = pstmt.executeQuery();
			
			while(rs.next()) {
				dto.setSabeon(rs.getString("sabeon"));
				dto.setName(rs.getString("name"));
				dto.setBirth(rs.getDate("birth").toString());
				dto.setTel(rs.getString("번호"));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return dto;
	}
	
	public List<EmployeeDTO> listEmployee() {
		List<EmployeeDTO> list=new ArrayList<>();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql;
		
		try {
			sql = " SELECT sabeon, name, birth, NVL(tel, '입력안함') 번호 "
					+" FROM employee";
			
			pstmt = conn.prepareStatement(sql);
			rs = pstmt.executeQuery();
			
			while(rs.next()) {
				EmployeeDTO dto = new EmployeeDTO();
				
				dto.setSabeon(rs.getString("sabeon"));
				dto.setName(rs.getString("name"));
				dto.setBirth(rs.getDate("birth").toString());
				dto.setTel(rs.getString("번호"));
				
				list.add(dto);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (pstmt != null) {
				try {
					pstmt.close();
				} catch (Exception e2) {
				}
			}
			if (rs != null) {
				try {
					rs.close();
				} catch (Exception e2) {
				}
			}
		}
		
		return list;
	}
	
	public List<EmployeeDTO> listEmployee(String name) {
		List<EmployeeDTO> list=new ArrayList<>();
		
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql;
		
		try {
			sql = " SELECT sabeon, name, birth, NVL(tel, '입력안함') 번호 "
					+" FROM employee"
					+" WHERE INSTR(name, ?) > 0";
			
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, name);
			rs = pstmt.executeQuery();
			
			while(rs.next()) {
				EmployeeDTO dto = new EmployeeDTO();
				
				dto.setSabeon(rs.getString("sabeon"));
				dto.setName(rs.getString("name"));
				dto.setBirth(rs.getDate("birth").toString());
				dto.setTel(rs.getString("번호"));
				
				list.add(dto);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (pstmt != null) {
				try {
					pstmt.close();
				} catch (Exception e2) {
				}
			}
			if (rs != null) {
				try {
					rs.close();
				} catch (Exception e2) {
				}
			}
		}
		return list;
	}
}

EmployeeDTO

더보기
package db.employee;

public class EmployeeDTO {
	private String sabeon;
	private String name;
	private String birth;
	private String tel;
	
	public String getSabeon() {
		return sabeon;
	}
	public void setSabeon(String sabeon) {
		this.sabeon = sabeon;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getBirth() {
		return birth;
	}
	public void setBirth(String birth) {
		this.birth = birth;
	}
	public String getTel() {
		return tel;
	}
	public void setTel(String tel) {
		this.tel = tel;
	}
}

Salary

더보기

 

package db.employee;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.InputMismatchException;
import java.util.List;
import java.util.Map;

public class Salary {
	private BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
	private SalaryDAO dao=new SalaryDAO();
	private Employee emp=null;
	
	public Salary(Employee emp) {
		this.emp = emp;
	}
	
	public void salaryManage() {
		int ch = 0;
		while(true) {
			System.out.println("\n[급여관리]");
			do {
				System.out.print("1.지급 2.수정 3.삭제 4.월별리스트 5.사번검색 6.리스트 7.사원리스트 8.메인 => ");
				try {
					ch = Integer.parseInt(br.readLine());
				} catch (Exception e) {
				}
			}while(ch<1||ch>8);
			
			if(ch==8) return;
			
			switch(ch) {
			case 1:payment(); break;
			case 2:update(); break;
			case 3:delete(); break;
			case 4:monthList(); break;
			case 5:searchSabeon(); break;
			case 6:list(); break;
			case 7:emp.list(); break;
			}
		}
	}
	
	public void payment() {
		System.out.println("\n급여 지급...");
		SalaryDTO dto = new SalaryDTO();
		int result = 0;
		try {
			System.out.print("급여 지급대상의 사원번호를 입력하세요 > ");
			dto.setSabeon(br.readLine());
			System.out.print("급여년월(yyyymm)을 입력해주세요 > ");
			dto.setPayDate(br.readLine());
			System.out.print("급여지급일자(yyyymmdd)를 입력해주세요 > ");
			dto.setPaymentDate(br.readLine());
			System.out.print("기본급을 입력해주세요.(선택) > ");
			dto.setPay(Integer.parseInt(br.readLine()));
			System.out.print("수당을 입력해주세요.(선택) > ");
			dto.setSudang(Integer.parseInt(br.readLine()));
			System.out.print("기타 메모 > ");
			dto.setMemo(br.readLine());
			
			result = dao.insertSalary(dto);
			
			if ( result > 0) {
				System.out.println("급여지급을 완료했습니다.");
			}
			System.out.println();
		} catch (Exception e) {
			System.out.println("급여 지급을 실패했습니다.");
			e.printStackTrace();
			
		}
		
	}
	
	public void update() {
		System.out.println("\n급여 수정...");
		int salaryNum, result;
		
		try {
			System.out.println("수정할 급여번호를 입력해주세요 > ");
			salaryNum = Integer.parseInt(br.readLine());
			
			System.out.println("현재 해당 급여번호의 자료");
			System.out.println("------------------------------------------------------------------------------------");
			System.out.println("급여번호\t사번\t급여년월\t지급일자\t\t기본급\t수당\t총급여\t세금\t세후지급액\t메모");
			SalaryDTO dto = dao.readSalary(salaryNum);
			System.out.print(dto.getSalaryNum()+"\t");
			System.out.print(dto.getSabeon()+"\t");
			System.out.print(dto.getPayDate()+"\t");
			System.out.print(dto.getPaymentDate()+"\t");
			System.out.print(dto.getPay()+"\t");
			System.out.print(dto.getSudang()+"\t");
			System.out.print(dto.getTot()+"\t");
			System.out.print(dto.getTax()+"\t");
			System.out.print(dto.getAfterPay()+"\t");
			System.out.println(dto.getMemo());
			System.out.println();
			
			System.out.print("수정할 급여년월 > ");
			dto.setPayDate(br.readLine());
			System.out.print("수정할 지급일자 > ");
			dto.setPaymentDate(br.readLine());
			System.out.print("수정할 기본급 > ");
			dto.setPay(Integer.parseInt(br.readLine()));
			System.out.print("수정할 수당 > ");
			dto.setSudang(Integer.parseInt(br.readLine()));
			System.out.print("수정할 메모 > ");
			dto.setMemo(br.readLine());
			
			result = dao.updateSalary(dto);
			if (result > 0) {
				System.out.println("수정이 완료되었습니다.");
			}
			
		} catch (Exception e) {
			System.out.println("수정에 실패했습니다.");
			e.printStackTrace();
		}
		
	}

	public void delete() {
		System.out.println("\n급여 삭제...");
		int salaryNum, result;
		
		try {
			System.out.println("삭제할 급여번호를 입력해주세요 > ");
			salaryNum = Integer.parseInt(br.readLine());
			result = dao.deleteSalary(salaryNum);
			
			if (result > 0) {
				System.out.println("삭제되었습니다.");
			}
			
		} catch (InputMismatchException e) {
			System.out.println("급여번호는 숫자만 가능합니다.");
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void searchSabeon() {
		System.out.println("\n사번 검색...");
		String sabeon, date;
		Map<String, Object> map = new HashMap<>(); 
		int ch = 0;
		boolean b = true;
		
		try {
			while(b) {
				do {
					SalaryDTO dto = new SalaryDTO();
					System.out.print("급여년월(yyyymm)을 입력해주세요 > ");
					date = br.readLine();
					System.out.print("검색할 사번을 입력해주세요 > ");
					sabeon = br.readLine();
					dto.setSabeon(sabeon);
					
					map.put(date, dto);
					
					System.out.println("더 검색 할 자료가 없으면 1, 있으면 2를 누르세요 > ");
					ch = Integer.parseInt(br.readLine());
				} while (ch >= 2);
				if ( ch == 1) {
					b = false;					
				}
			} 
			System.out.println("검색한 사번의 급여년월 출력...");
			List<SalaryDTO> list = dao.listSalary(map);
			
			System.out.println("사번\t이름\t급여년월\t지급일자");
			System.out.println("-----------------------------------");
			for(SalaryDTO dto : list) {
				System.out.print(dto.getSabeon()+"\t");
				System.out.print(dto.getName()+"\t");
				System.out.print(dto.getPayDate()+"\t");
				System.out.println(dto.getPaymentDate());
			}
			System.out.println();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("검색에 실패했습니다.");
		}
		
	}

	public void monthList() {
		System.out.println("\n월별 리스트...");
		String paydate;
		try {
			System.out.println("검색할 급여년월(yyyymm)을 입력해주세요 > ");
			paydate = br.readLine();
			List<SalaryDTO> list = dao.listSalary(paydate);
			
			System.out.println("사번\t이름\t급여년월\t지급일자");
			System.out.println("-----------------------------------");
			for(SalaryDTO dto : list) {
				System.out.print(dto.getSabeon()+"\t");
				System.out.print(dto.getName()+"\t");
				System.out.print(dto.getPayDate()+"\t");
				System.out.println(dto.getPaymentDate());
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("검색에 실패했습니다.");
		}
		
	}
	
	public void list() {
		System.out.println("\n급여 리스트...");
		List<SalaryDTO> list = dao.listSalary();
		
		System.out.println("급여번호\t사번\t이름\t급여년월\t지급일자\t\t기본급\t\t수당\t총급여\t\t세금\t세후지급금\t\t메모");
		System.out.println("---------------------------------------------------------------------");
		for(SalaryDTO dto : list) {
			System.out.print(dto.getSalaryNum()+"\t");
			System.out.print(dto.getSabeon()+"\t");
			System.out.print(dto.getName()+"\t");
			System.out.print(dto.getPayDate()+"\t");
			System.out.print(dto.getPaymentDate()+"\t");
			System.out.printf("%,d", dto.getPay());
			System.out.print("\t");
			System.out.printf("%,d", dto.getSudang());
			System.out.print("\t");
			System.out.printf("%,d", dto.getTot());
			System.out.print("\t");
			System.out.printf("%,d", dto.getTax());
			System.out.print("\t");
			System.out.printf("%,d", dto.getAfterPay());
			System.out.print("\t");
			System.out.println(dto.getMemo());
		}
		System.out.println();
	}
}

 

 위에서 searchSabeon() 은 이렇게 짜야했다.

Map에 대한 개념을 잊어버리지 말라고 넣으신 듯.

public void searchSabeon() {
		System.out.println("\n사번 검색...");
		
		String payDate, sabeon;
		
		try {
			System.out.print("검색할 급여년월[yyyymm] ?");
			payDate=br.readLine();
			System.out.print("검색할 사번 ?");
			sabeon=br.readLine();
			Map<String, Object> map=new HashMap<>();
			map.put("payDate", payDate);
			map.put("sabeon", sabeon);
			
			List<SalaryDTO> list=dao.listSalary(map);
			
			for(SalaryDTO dto : list) {
				System.out.print(dto.getSalaryNum()+"\t");
				System.out.print(dto.getSabeon()+"\t");
				System.out.print(dto.getName()+"\t");
				System.out.print(dto.getPayDate()+"\t");
				System.out.print(dto.getPaymentDate()+"\t");
				System.out.print(dto.getPay()+"\t");
				System.out.print(dto.getSudang()+"\t");
				System.out.print(dto.getTot()+"\t");
				System.out.print(dto.getTax()+"\t");
				System.out.println(dto.getAfterPay());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println();
		
	}

SalaryDAO

더보기
package db.employee;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLDataException;
import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import db_util.DBConn;

public class SalaryDAO {
	private Connection conn=DBConn.getConnection();
	
	public int insertSalary(SalaryDTO dto) throws SQLException {
		int result=0;
		PreparedStatement pstmt = null;
		String sql;
		
		try {
			sql = "INSERT INTO salary(salaryNum, sabeon, payDate, paymentDate, pay, sudang, tax, memo)"
					+ "VALUES (salary_seq.NEXTVAL, ?, ?, ?, ?, ?, ?, ?)";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, dto.getSabeon());
			pstmt.setString(2, dto.getPayDate());
			pstmt.setString(3, dto.getPaymentDate());
			pstmt.setInt(4, dto.getPay());
			pstmt.setInt(5, dto.getSudang());
			pstmt.setInt(6, dto.getTax());
			pstmt.setString(7, dto.getMemo());
			
			result = pstmt.executeUpdate();
			
		} catch (SQLIntegrityConstraintViolationException e) {
			if(e.getErrorCode()==1) {
				System.out.println("사번 중복 입니다.");
			} else if(e.getErrorCode()==1400) { // NOT NULL 위반
				System.out.println("필수 사항을 입력 하지 않았습니다.");
			} else {
				System.out.println(e.toString());
			}
			throw e;
		} catch (SQLDataException e) {
			if(e.getErrorCode()==1861 || e.getErrorCode()==1840) { 
				System.out.println("날짜 형식이 잘못 되었습니다.");
			} else {
				System.out.println(e.toString());
			}
			throw e;
		} catch (SQLException e) {
			e.printStackTrace();
			throw e;
		} finally {
			if( pstmt != null){
				try {
					pstmt.close();
				} catch (Exception e2) {
				}
			}
		}
		
		return result;
	}
	
	public int updateSalary(SalaryDTO dto) throws SQLException {
		int result=0;
		PreparedStatement pstmt = null;
		String sql;
		
		try {
			sql = "UPDATE salary SET paydate = ?, paymentdate = ?, pay = ?, sudang = ?, memo = ?"
					+" WHERE salaryNum = ?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, dto.getPayDate());
			pstmt.setString(2, dto.getPaymentDate());
			pstmt.setInt(3, dto.getPay());
			pstmt.setInt(4, dto.getSudang());
			pstmt.setString(5, dto.getMemo());
			pstmt.setInt(6, dto.getSalaryNum());
			
			result = pstmt.executeUpdate();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return result;
	}

	public int deleteSalary(int salaryNum) throws SQLException {
		int result=0;
		PreparedStatement pstmt = null;
		String sql;
		
		try {
			sql = " DELETE FROM salary WHERE salaryNum = ?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, salaryNum);
			
			result = pstmt.executeUpdate();
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(pstmt !=null) {
				try {
					pstmt.close();
				} catch (Exception e2) {
				}
			}
		}

		return result;
	}
	
	public SalaryDTO readSalary(int salaryNum) {
		SalaryDTO dto= new SalaryDTO();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql;
		
		try {
			sql = " SELECT salaryNum, sabeon, paydate, paymentdate, pay, sudang, tax, NVL(memo, '입력안함') 메모 "
					+" FROM salary "
					+" WHERE salaryNum = ?";
			pstmt = conn.prepareStatement(sql);
			pstmt.setInt(1, salaryNum);
			
			rs = pstmt.executeQuery();
			
			while(rs.next()) {
				dto.setSalaryNum(rs.getInt("salaryNum"));
				dto.setSabeon(rs.getString("sabeon"));
				dto.setPayDate(rs.getString("paydate"));
				dto.setPaymentDate(rs.getDate("paymentdate").toString());
				dto.setPay(rs.getInt("pay"));
				dto.setSudang(rs.getInt("sudang"));
				dto.setMemo(rs.getString("메모"));
				
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (pstmt != null) {
				try {
					pstmt.close();
				} catch (Exception e2) {
				}
			}
			if (rs != null) {
				try {
					rs.close();
				} catch (Exception e2) {
				}
			}
		}
		
		return dto;
	}
	
	public List<SalaryDTO> listSalary(String payDate) {
		List<SalaryDTO> list=new ArrayList<>();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql;
		
		try {
			sql = "SELECT e.sabeon, name, paydate, paymentdate "
					+" FROM employee e "
					+" JOIN salary s ON e.sabeon = s.sabeon"
					+" WHERE paydate = ?";
			
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, payDate);
			rs = pstmt.executeQuery();
			
			while(rs.next()) {
				SalaryDTO dto = new SalaryDTO();
				dto.setSabeon(rs.getString("sabeon"));
				dto.setName(rs.getString("name"));
				dto.setPayDate(rs.getString("paydate"));
				dto.setPaymentDate(rs.getDate("paymentdate").toString());
				
				list.add(dto);
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (pstmt != null) {
				try {
					pstmt.close();
				} catch (Exception e2) {
				}
			}
			if (rs != null) {
				try {
					rs.close();
				} catch (Exception e2) {
				}
			}
		}
		return list;
	}
	
	public List<SalaryDTO> listSalary(Map<String, Object> map) {
		List<SalaryDTO> list=new ArrayList<>();
		List<SalaryDTO> list1 = listSalary(); // 전체 급여리스트
		Set<String> keySet = map.keySet(); // 검색할 사번이 있는 곳
		List<String> list2 = new ArrayList<String>(keySet); // 검색할 사번 리스트
		
		for(int i = 0; i<list2.size();i++) {
			for(int j = 0; j< list1.size(); j++) {
				if(list2.get(i) == list1.get(j).getSabeon()) {				
				SalaryDTO dto;
				dto = list1.get(j);
				list.add(dto);
				}
			}
		}
		return list;
	}

	public List<SalaryDTO> listSalary() {
		List<SalaryDTO> list=new ArrayList<>();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql;
		try {
			sql = "SELECT salarynum, e.sabeon, name, paydate, paymentdate, pay, sudang, memo "
					+" FROM employee e "
					+" JOIN salary s ON e.sabeon = s.sabeon";
			pstmt = conn.prepareStatement(sql);
			rs = pstmt.executeQuery();
			
			while(rs.next()) {
				SalaryDTO dto = new SalaryDTO();
				dto.setSalaryNum(rs.getInt("salarynum"));
				dto.setSabeon(rs.getString("sabeon"));
				dto.setName(rs.getString("name"));
				dto.setPayDate(rs.getString("paydate"));
				dto.setPaymentDate(rs.getDate("paymentdate").toString());
				dto.setPay(rs.getInt("pay"));
				dto.setSudang(rs.getInt("sudang"));
				dto.setMemo(rs.getString("memo"));
				
				list.add(dto);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (pstmt != null) {
				try {
					pstmt.close();
				} catch (Exception e2) {
				}
			}
			if (rs != null) {
				try {
					rs.close();
				} catch (Exception e2) {
				}
			}
		}
		return list;
	}

}

 

 public List<SalaryDTO> listSalary(Map<String, Object> map) 메소드의 경우 아래와 같이 짜야했다.

public List<SalaryDTO> listSalary(Map<String, Object> map) {
		List<SalaryDTO> list=new ArrayList<>();
		
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		StringBuilder sb=new StringBuilder();
		
		String sabeon=(String)map.get("sabeon");
		String payDate=(String)map.get("payDate");
		
		try {
			sb.append(" SELECT salaryNum, s.sabeon, name, payDate, ");
			sb.append("   TO_CHAR(paymentDate, 'YYYY-MM-DD') paymentDate, ");
			sb.append("   pay, sudang, pay+sudang tot, tax, (pay+sudang)-tax afterPay, memo ");
			sb.append(" FROM salary s ");
			sb.append(" JOIN employee e ON s.sabeon = e.sabeon ");
			sb.append(" WHERE s.sabeon = ? AND payDate = ?");
			
			pstmt=conn.prepareStatement(sb.toString());
			pstmt.setString(1, sabeon);
			pstmt.setString(2, payDate);
			rs=pstmt.executeQuery();
			
			while(rs.next()) {
				SalaryDTO dto = new SalaryDTO();
				dto.setSalaryNum(rs.getInt("salaryNum"));
				dto.setSabeon(rs.getString("sabeon"));
				dto.setName(rs.getString("name"));
				dto.setPayDate(rs.getString("payDate"));
				dto.setPaymentDate(rs.getString("paymentDate"));
				dto.setPay(rs.getInt("pay"));
				dto.setSudang(rs.getInt("sudang"));
				dto.setMemo(rs.getString("memo"));
				
				list.add(dto);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if(rs!=null) {
				try {
					rs.close();
				} catch (Exception e2) {
				}
			}
			if(pstmt!=null) {
				try {
					pstmt.close();
				} catch (Exception e2) {
				}
			}
		}
		
		return list;
	}

SalaryDTO

더보기
package db.employee;

public class SalaryDTO {
	private int salaryNum;
	private String sabeon;
	private String name;
	private String payDate; // 지급년월
	private String paymentDate; // 지급일자
	private int pay;
	private int sudang;
	private int tot;
	private int tax;
	private int afterPay;
	private String memo;

	public int getSalaryNum() {
		return salaryNum;
	}

	public void setSalaryNum(int salaryNum) {
		this.salaryNum = salaryNum;
	}

	public String getSabeon() {
		return sabeon;
	}

	public void setSabeon(String sabeon) {
		this.sabeon = sabeon;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPayDate() {
		return payDate;
	}

	public void setPayDate(String payDate) {
		this.payDate = payDate;
	}

	public String getPaymentDate() {
		return paymentDate;
	}

	public void setPaymentDate(String paymentDate) {
		this.paymentDate = paymentDate;
	}

	public int getPay() {
		return pay;
	}

	public void setPay(int pay) {
		this.pay = pay;
	}

	public int getSudang() {
		return sudang;
	}

	public void setSudang(int sudang) {
		this.sudang = sudang;
	}

	public int getTot() {
		tot = pay + sudang;
		return tot;
	}

	public int getTax() {
		if (sudang + pay >= 3000000) {
			tax = (int) ((sudang + pay) * 0.03);
		} else if (sudang + pay >= 2000000) {
			tax = (int) ((sudang + pay) * 0.02);
		} else {
			tax = 0;
		}
		return tax;
	}

	public int getAfterPay() {
		afterPay = tot - tax;
		return afterPay;
	}


	public String getMemo() {
		return memo;
	}

	public void setMemo(String memo) {
		this.memo = memo;
	}
}

 

SalaryDTO 클래스의 public List<SalaryDTO> listSalary(Map<String, Object> map) 메소드는 결국 못짬. 그 맵으로 받아서 뭘 하라는 건지 잘 모르겠다..ㅠㅠ

사원번호와 급여년월을 받아서 뭐 하라는건지...ㅍㅍㅠ

 

근데 나는 DTO 에서 아예 afterpay 나 tax부분은 넣을 때 알아서 계산하게끔 했는데... 쌤이 짜신 tax은 입력받은 곳에서 계산해서 DTO에 넣어준다. 

 

App

더보기
package db.member;

public class App {
	public static void main(String[] args) {
		MemberUI ui=new MemberUI();
		ui.menu();
	}

}

MemberDAO

더보기
package db.member;

import java.sql.SQLException;
import java.util.List;

public interface MemberDAO {
	public int insertMember(MemberDTO dto) throws SQLException;
	public int updateMember(MemberDTO dto) throws SQLException;
	public int deleteMember(String id) throws SQLException;
	
	public MemberDTO readMember(String id);
	public List<MemberDTO> listMember();
	public List<MemberDTO> listMember(String name);	
}

MemberDAOImpl

더보기
package db.member;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLDataException;
import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.ArrayList;
import java.util.List;

import db_util.DBConn;


public class MemberDAOImpl implements MemberDAO {
	private Connection conn = DBConn.getConnection();

	@Override
	public int insertMember(MemberDTO dto) throws SQLException {
		int result = 0;

		/*
		  - 하나의 테이블에 추가
		     INSERT INTO 테이블명(컬럼명, 컬럼명) VALUES (값, 값)
		  - 두개의 테이블에 추가
		     INSERT ALL
		       INTO 테이블명(컬럼명, 컬럼명) VALUES (값, 값)
		       INTO 테이블명(컬럼명, 컬럼명) VALUES (값, 값)
		       SELECT * FROM dual 
		*/
		
		PreparedStatement pstmt1 = null;
		PreparedStatement pstmt2 = null;
		String sql;
		try {
			sql = "INSERT INTO member1(id, pwd, name) VALUES(?, ?, ?)";
			pstmt1 = conn.prepareStatement(sql);
			
			pstmt1.setString(1, dto.getId());
			pstmt1.setString(2, dto.getPwd());
			pstmt1.setString(3, dto.getName());
			
			result = pstmt1.executeUpdate();
			
			sql = "INSERT INTO member2(id, birth, email, tel) VALUES(?,?,?,?)";
			pstmt2 = conn.prepareStatement(sql);
			
			pstmt2.setString(1, dto.getId());
			pstmt2.setString(2, dto.getBirth());
			pstmt2.setString(3, dto.getEmail());
			pstmt2.setString(4, dto.getTel());
			
			result += pstmt2.executeUpdate();
			
		} catch (SQLIntegrityConstraintViolationException e) {
			if(e.getErrorCode()==1) {
				System.out.println("아이디 중복 입니다.");
			} else if(e.getErrorCode()==1400) { // NOT NULL 위반
				System.out.println("필수 사항을 입력 하지 않았습니다.");
			} else {
				System.out.println(e.toString());
			}
			throw e;
		} catch (SQLDataException e) {
			if(e.getErrorCode()==1861 || e.getErrorCode()==1840) { 
				System.out.println("날짜 형식이 잘못 되었습니다.");
			} else {
				System.out.println(e.toString());
			}
			throw e;
		} catch (SQLException e) {
			e.printStackTrace();
			throw e;
		} finally {
			try {
				if( pstmt1 != null || pstmt2 != null) {
					pstmt1.close();
					pstmt2.close();
				}
			} catch (Exception e2) {
			}
		}
				

		// member1 테이블과 member2 테이블에 데이터 추가
		// 방법1) member1 추가 후 member2 추가
		// 방법2) member1과 member2를 한번에 추가
		
		
		return result;
	}

	@Override
	public int updateMember(MemberDTO dto) throws SQLException {
		int result = 0;
		PreparedStatement pstmt1 = null;
		PreparedStatement pstmt2 = null;
		String sql;
		
		// UPDATE 테이블명 SET 컬럼=값, 컬럼=값 WHERE 조건
		try {
			sql = " UPDATE member1 SET pwd=?, name=? WHERE id=? ";
			pstmt1 = conn.prepareStatement(sql);
			
			pstmt1.setString(1, dto.getPwd());
			pstmt1.setString(2, dto.getName());
			pstmt1.setString(3, dto.getId());
			
			result = pstmt1.executeUpdate();
			
			sql = " UPDATE member2 SET birth=?, email=?, tel=? WHERE id=? ";
			pstmt2 = conn.prepareStatement(sql);
			
			pstmt2.setString(1, dto.getBirth());
			pstmt2.setString(2, dto.getEmail());
			pstmt2.setString(3, dto.getTel());
			pstmt2.setString(4, dto.getId());
			
			result += pstmt2.executeUpdate();
			
		} catch (SQLIntegrityConstraintViolationException e) {
			if(e.getErrorCode()==1400) {
				System.out.println("필수 입력 사항을 입력하지 않았습니다.");
			} else {
				System.out.println(e.toString());
			}
			throw e;
		} catch (SQLDataException e) {
			if(e.getErrorCode()==1840||e.getErrorCode()==1861) {
				System.out.println("날짜 형식이 올바르지 않습니다.");
			} else {
				System.out.println(e.toString());
			}
			throw e;
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if( pstmt1 != null || pstmt2 != null) {
					pstmt1.close();
					pstmt2.close();
				}
			} catch (Exception e2) {
			}
		}
		// id 조건에 맞는 member1 테이블과 member2 테이블에 데이터 수정
		// member1 수정 후 member2 수정
		
		return result;
	}

	@Override
	public int deleteMember(String id) throws SQLException {
		int result = 0;
		PreparedStatement pstmt1 = null;
		PreparedStatement pstmt2 = null;
		String sql;
		// DELETE FROM 테이블명 WHERE 조건
		try {
			sql = "DELETE FROM member2 WHERE id = ?";
			pstmt1 = conn.prepareStatement(sql);
			pstmt1.setString(1, id);
			
			result = pstmt1.executeUpdate();
			
			sql = "DELETE FROM member1 WHERE id = ?";
			pstmt2 = conn.prepareStatement(sql);
			pstmt2.setString(1, id);
			
			result += pstmt2.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if( pstmt1 != null || pstmt2 != null) {
					pstmt1.close();
					pstmt2.close();
				}
			} catch (Exception e2) {
			}
		}
		// id 조건에 맞는 member1 테이블과 member2 테이블 데이터 삭제
		// member2 삭제후 member1 삭제

		return result;
	}

	@Override
	public MemberDTO readMember(String id) {
		MemberDTO dto = new MemberDTO();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql;
		/*
		  - 하나의 테이블
		    SELECT 컬럼, 컬럼 FROM 테이블 WHERE 조건
		  - EQUI 조인
		    SELECT 테이블1.컬럼, 테이블1.컬럼, 테이블2.컬럼
            FROM 테이블1
            JOIN 테이블2 ON 테이블1.컬럼 = 테이블2.컬럼
            WHERE 조건
		  - LEFT OUTER JOIN 조인
		    SELECT 테이블1.컬럼, 테이블1.컬럼, 테이블2.컬럼
            FROM 테이블1
            LEFT OUTER JOIN 테이블2 ON 테이블1.컬럼 = 테이블2.컬럼
            WHERE 조건
		 */
		
		try {
			sql = "SELECT m1.id id, pwd, name, NVL(birth, '1900-01-01') 생년월일, NVL(email, '등록안함') 이메일, NVL(tel, '등록안함') 전화번호 "
					+" FROM member1 m1 "
					+" LEFT OUTER JOIN member2 m2 ON m1.id = m2.id "
					+" WHERE m1.id LIKE ?";
			
			pstmt = conn.prepareStatement(sql);
			
			pstmt.setString(1, id);
			
			rs = pstmt.executeQuery();
			
			while(rs.next()) {
				dto.setId(rs.getString("id"));
				dto.setPwd(rs.getString("pwd"));
				dto.setName(rs.getString("name"));
				dto.setBirth(rs.getDate("생년월일").toString());
				dto.setEmail(rs.getString("이메일"));
				dto.setTel(rs.getString("전화번호"));
				
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		// id 조건에 맞는 member1 테이블과 member2 테이블 데이터를 OUTER JOIN 해서 아이디 검색

		return dto;
	}

	@Override
	public List<MemberDTO> listMember() {
		List<MemberDTO> list = new ArrayList<>();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql;
		
		// member1 테이블과 member2 테이블의 전체 데이터를 OUTER JOIN 해서 전체 리스트

		try {
			sql = "SELECT m1.id id, pwd, name, NVL(birth, '1900-01-01') 생년월일, NVL(email, '등록안함') 이메일, NVL(tel, '등록안함') 전화번호 "
					+" FROM member1 m1 "
					+" LEFT OUTER JOIN member2 m2 ON m1.id = m2.id ";
			
			pstmt = conn.prepareStatement(sql);
			
			rs = pstmt.executeQuery();
			
			while(rs.next()) {
				MemberDTO dto = new MemberDTO();
				
				dto.setId(rs.getString("id"));
				dto.setPwd(rs.getString("pwd"));
				dto.setName(rs.getString("name"));
				dto.setBirth(rs.getDate("생년월일").toString());
				dto.setEmail(rs.getString("이메일"));
				dto.setTel(rs.getString("전화번호"));
				
				list.add(dto);
			}

		} catch (NullPointerException e) {
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if( rs != null) {
					rs.close();
				}
			} catch (Exception e2) {
			}
			try {
				if ( pstmt != null ) {
					pstmt.close();
				}
			} catch (Exception e2) {
			}
		}
		
		return list;
	}

	@Override
	public List<MemberDTO> listMember(String name) {
		List<MemberDTO> list = new ArrayList<>();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		String sql;
		
		// member1 테이블과 member2 테이블의 전체 데이터를 OUTER JOIN 해서 이름 검색
		try {
			sql = "SELECT m1.id id, pwd, name, NVL(birth, '1900-01-01') 생년월일, NVL(email, '등록안함') 이메일, NVL(tel, '등록안함') 전화번호"
					+" FROM member1 m1 "
					+" LEFT OUTER JOIN member2 m2 ON m1.id = m2.id "
					+" WHERE INSTR(name, ?) > 0";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, name);
			
			rs = pstmt.executeQuery();
			
			while(rs.next()) {
				MemberDTO dto = new MemberDTO();
				
				dto.setId(rs.getString("id"));
				dto.setPwd(rs.getString("pwd"));
				dto.setName(rs.getString("name"));
				dto.setBirth(rs.getDate("생년월일").toString());
				dto.setEmail(rs.getString("이메일"));
				dto.setTel(rs.getString("전화번호"));
				
				list.add(dto);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(rs != null) {
				try {
					rs.close();
				} catch (Exception e2) {
				}
			}
			
			if (pstmt != null) {
				try {
					pstmt.close();
				} catch (Exception e2) {
				}
			}
		}
		
		
		return list;
	}
}

MemberDTO

더보기
package db.member;

public class MemberDTO {
	private String id;
	private String pwd;
	private String name;
	private String birth;
	private String email;
	private String tel;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getBirth() {
		return birth;
	}
	public void setBirth(String birth) {
		this.birth = birth;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getTel() {
		return tel;
	}
	public void setTel(String tel) {
		this.tel = tel;
	}
	
}

MemberUI

더보기
package db.member;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.List;

import db_util.DBConn;

public class MemberUI {
	private BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	private MemberDAO dao = new MemberDAOImpl();

	public void menu() {
		int ch;
		
		System.out.println("회원-예제...");
		
		while(true) {
			try {
				do {
					System.out.print("1.회원가입 2.수정 3.탈퇴 4.아이디검색 5.이름검색 6.리스트 7.종료 => ");
					ch=Integer.parseInt(br.readLine());
				} while(ch < 1 || ch > 7);
				
				if(ch == 7) {
					DBConn.close();
					return;
				}
	
				switch(ch) {
				case 1:insert(); break;
				case 2:update(); break;
				case 3:delete(); break;
				case 4:findById(); break;
				case 5:findByName(); break;
				case 6:listAll(); break;
				}
			}catch (Exception e) {
			}
		}
	}
	
	public void insert() {
		System.out.println("\n회원가입...");
		int result = 0;
		
		try {
			MemberDTO dto = new MemberDTO();
			System.out.println("회원가입을 시작합니다.");
			System.out.print("ID를 입력해주세요 > ");
			dto.setId(br.readLine());
			System.out.print("비밀번호를 입력해주세요 > ");
			dto.setPwd(br.readLine());
			System.out.print("성함을 입력해주세요 > ");
			dto.setName(br.readLine());
			
			System.out.print("생년월일을 입력해주세요(선택) > ");
			dto.setBirth(br.readLine());
			System.out.print("email을 입력해주세요(선택) > ");
			dto.setEmail(br.readLine());
			System.out.print("전화번호를 입력해주세요(선택) > ");
			dto.setTel(br.readLine());
			
			
			result = dao.insertMember(dto);
			if (result > 0) {
				System.out.println("가입이 완료되었습니다. 감사합니다.\n");				
			}
			
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("회원가입에 실패했습니다.\n");
		}

	}

	public void update() {
		System.out.println("\n회원정보수정...");
		String id;
		
		try {
			System.out.print("수정할 ID를 입력하세요.");
			id = br.readLine();
			
			MemberDTO dto = dao.readMember(id);
			if (dto == null) {
				System.out.println("가입되어있는 ID가 아닙니다.");
				return;
			}

			System.out.println("수정할 패스워드를 입력해주세요 > ");
			dto.setPwd(br.readLine());
			System.out.println("수정할 이름을 입력해주세요 > ");
			dto.setName(br.readLine());
			System.out.print("수정할 생년월일을 입력해주세요(선택) > ");
			dto.setBirth(br.readLine());
			System.out.print("수정할 email을 입력해주세요(선택) > ");
			dto.setEmail(br.readLine());
			System.out.print("수정할 전화번호를 입력해주세요(선택) > ");
			dto.setTel(br.readLine());
			
			dao.updateMember(dto);
			
			System.out.println("회원정보 수정이 완료되었습니다.");
			System.out.println();
			
		} catch (Exception e) {
			System.out.println("정보 수정에 실패했습니다.");
			e.printStackTrace();
		}
		System.out.println();
		
	}

	public void delete() {
		System.out.println("\n회원탈퇴...");
		String id;
		
		try {
			System.out.print("탈퇴할 ID를 입력하세요 > ");
			id = br.readLine();
			
			int result = dao.deleteMember(id);
			if (result > 0) {
				System.out.println("회원탈퇴가 완료되었습니다. ");
				System.out.println("그동안 이용해주셔서 감사합니다.");				
				System.out.println();
			} else {
				System.out.println("회원탈퇴가 이루어지지 않았습니다.");
				System.out.println("등록된 아이디인지 확인해주십시오.");
			}
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void findById() {
		System.out.println("\n아이디 검색...");
		String id;
		
		try {
			System.out.print("검색할 ID를 입력하세요 > ");
			id = br.readLine();
			MemberDTO dto = dao.readMember(id);
			System.out.println("id\tpwd\t이름\t생년월일\t\t이메일\t\t전화번호");
			System.out.println("-----------------------------------------------");
			System.out.print(dto.getId()+"\t");
			System.out.print(dto.getPwd()+"\t");
			System.out.print(dto.getName()+"\t");
			System.out.print(dto.getBirth()+"\t");
			System.out.print(dto.getEmail()+"\t\t");
			System.out.println(dto.getTel());
			System.out.println();
			
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public void findByName() {
		System.out.println("\n이름 검색...");
		String name;
		try {
			System.out.print("검색할 이름을 입력하세요 > ");
			name = br.readLine();
			List<MemberDTO> list = dao.listMember(name);
			
			System.out.println("id\tpwd\t이름\t생년월일\t\t이메일\t\t전화번호");
			System.out.println("-----------------------------------------------");
			for( MemberDTO dto : list) {
				System.out.print(dto.getId()+"\t");
				System.out.print(dto.getPwd()+"\t");
				System.out.print(dto.getName()+"\t");
				System.out.print(dto.getBirth()+"\t");
				System.out.print(dto.getEmail()+"\t\t");
				System.out.println(dto.getTel());
			}
			System.out.println();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void listAll() {
		System.out.println("\n전체 리스트...");
		
		List<MemberDTO> list = dao.listMember();
		System.out.println("id\tpwd\t이름\t생년월일\t\t이메일\t\t전화번호");
		System.out.println("-----------------------------------------------");
		for( MemberDTO dto : list) {
			System.out.print(dto.getId()+"\t");
			System.out.print(dto.getPwd()+"\t");
			System.out.print(dto.getName()+"\t");
			System.out.print(dto.getBirth()+"\t");
			System.out.print(dto.getEmail()+"\t\t");
			System.out.println(dto.getTel());
		}
		System.out.println();
	}
}

java.sql.Statement 인터페이스

- 정적인 SQL 문을 실행하여 작성된 결과를 돌려주는 객체

- Statement 객체는 Connection의 createStatement() 메소드를 호출하여 얻는다.

 

Statement를 이용한 JDBC프로그램 작성 순서

1) JDBC 드라이버를 로딩한다.

- ORACLE 을 사용하는 경우

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

- MySQL을 사용하는 경우

Class.forName("com.mysql.jdbc.Driver");

 

- 자바 6부터는 JDBC드라이버를 자동으로 로딩하므로 생략 가능하다.

 

2) Connection 객체를 생성한다.

- 오라클의 Connection 객체 생성

String url = "jdbc:oracle:thin:@127.0.0.1:1521:ORCL"; // 11g, ORCL : SID
// String url = "jdbc:oracle:thin:@//127.0.0.1:1521/ORCL"; // 12C 이상
String user = "계정이름";
String pwd = "비밀번호";
Connection conn=DriverManager.getConnection(url, user, pwd);

 

- MySQL의 Connection 객체 생성

String url="jdbc:mysql://127.0.0.1:3306/mydb"; // mydb : 데이터베이스명
String user="계정이름";
String pwd="비밀번호";
Connection conn=DriverManager.getConnection(url, user, pwd);

3) Connection의 createStatement() 메소드를 호출하여 쿼리를 실행할 Statement 객체를 얻는다.

Statement stmt = conn.createStatement();

 

4) 실행할 쿼리를 작성한다.

- INSERT 문의 예

String sql = "INSERT INTO 테이블명(컬럼명, 컬럼명) VALUES (값, 값)";

 

- SELECT 문의 예

String sql = "SELECT 컬럼명, 컬럼명 FROM 테이블명 WHERE 조건";

 

5) 쿼리를 실행한다.

- DML(INSERT, UPDATE, DELETE), DDL 실행

int result = stmt.executeUpdate(sql);

 

- SELECT 문 실행

ResultSet rs = stmt.executeQuery(sql);

 

6) SELECT 문의 경우 next() 메소드를 이용하여 실행된 결과를 읽어 온다.

if(rs.next()) {
	String hak = rs.getString("hak");
    // ...
}

 

7) 리소스를 close 한다.

rs.close(); // SELECT 문을 실행한 경우
stmt.close();
conn.close();

 

예 >>

더보기
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import db_util.DBConn;

public class Ex001_Statement {

	public static void main(String[] args) {
		Connection conn = DBConn.getConnection();
		
		// Statement 인터페이스 쿼리를 실행하는 인터페이스
		Statement stmt = null;
		String sql;
		
		try {
			// 쿼리를 작성할때 쿼리 마지막에 ;를 붙이지 않는다. 
			// 만약에 쿼리에 ;를 붙이면 ORA-00933 에러 발생
			sql = "INSERT INTO score(hak, name, birth, kor, eng, mat) VALUES ( " 
					+ " '1001', '김자바', '2000-10-10', 80, 90, 70) ";
			
			stmt = conn.createStatement();
			
			// executeUpdate() : DDL(CREATE, ALTER, DROP), DML(INSERT, UPDATE, DELETE) 실행
			int result = stmt.executeUpdate(sql);
				// DML을 실행한 경우 쿼리를 실행 후 변경 개수를 반환하고
			    // DDL은 실행 여부를 반환 한다.
			System.out.println(result +" 행이 추가 되었습니다.");
			
			// 이 프로그램은 한번만 실행 할 수 있다.
			// 두번 실행하면 학번이 기본키 이므로 동일한 학번을 추가 할수 없어서
			// ORA-00001(SQLIntegrityConstraintViolationException) 에러 발생
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if(stmt != null) {
				try {
					stmt.close();
				} catch (Exception e2) {
				}
			}
			DBConn.close();
		}
		

	}

}

java.sql.ResultSet 인터페이스

- 데이터베이스 결과 집합을 나타내는 데이터 테이블로, 일반적으로 데이터베이스에 조회하는 문을 실행하여 생성된다.

- ResultSet 객체는 현재 데이터 행을 가리키는 커서를 유지하며, 초기에 커서는 첫 번째 행 앞에 위치한다.

- next() 메소드는 커서를 다음 행으로 이동시키고, ResultSet 객체에 더 이상 행이 없을 때 false를 리턴하므로 while 루프에서 결과 세트를 반복할 수 있다.

- 디폴트의 ResultSet 객체는 갱신이 불가능하며, next() 메소드로 다음 행(순방향)으로만 이동 가능하다.

- 옵션을 이용해 갱신이 가능하며, 스크롤이 가능한 ResultSet객체를 생성할 수 있다.

- ResultSet 객체를 생성한 Statement 객체가 close()되거나 다시 실행되는 경우에는 ResultSet 객체는 자동으로 close() 된다.

- ResultSet 객체는 Statement의 executeQuery(String sql) 메소드, PreparedStatement의 executeQuery() 메소드 등을 이용하여 객체를 얻는다. 

 

예 >>

더보기
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import db_util.DBConn;

public class Ex002_ResultSet {
	public static void main(String[] args) {
		Connection conn = DBConn.getConnection();
		Statement stmt = null;
		ResultSet rs = null;
		String sql;
		
		try {
			stmt = conn.createStatement();
			sql = "SELECT hak hno, name, birth, kor, eng, mat, kor+eng+mat FROM score"
					+ "  WHERE hak = '1001' ";
			
			// executeQuery() : SELECT 문 실행
			// ResultSet : SELECT 문 실행 결과를 가지고 있는 객체. 전부 다 가져옴
			rs = stmt.executeQuery(sql);
			
			// 초기에 커서는 첫번재 행 앞에 위치
			// next() : 커서를 다음 행으로 이동
			if(rs.next()) {
				// String hak = rs.getString("hak"); // 에러
					// 컬럼명에 별명을 주면 반드시 별명으로 가져와야 한다.
				String hak = rs.getString("hno");
				String name = rs.getString("name");
				// String name = rs.getString(2);
				// String birth = rs.getString(3); // 컬럼의 위치로 가져오기(1부터 시작)
					// 날짜는 yyyy-mm-dd hh:mi:ss 로 출력
					// 날짜, 숫자는 String으로 가져 올수 있음
					// 날짜를 원하는 형식으로 가져오기 위해서는 쿼리에서
					// TO_CHAR(birth, 'YYYY-MM-DD') birth
					// 같이 해줘어야 함
					// 날짜는 getDate()로 가져오며, java.sql.Date 형임
				String birth = rs.getDate(3).toString(); // yyyy-mm-dd 로 반환
				int kor = rs.getInt("kor");
				int eng = rs.getInt("eng");
				int mat = rs.getInt(6);
				int tot = rs.getInt(7);
				
				System.out.print(hak + "\t" + name +"\t" + birth +"\t");
				System.out.println(kor + "\t" + eng +"\t" + mat +"\t" + tot);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(rs != null) {
				try {
					rs.close();
				} catch (Exception e2) {
				}
			}
			
			if(stmt != null) {
				try {
					stmt.close();
				} catch (Exception e2) {
				}
			}
		}
		
		
	}
}

위 Statement 예시를 실행 후 ResultSet에서 불러온 결과

java.sql.DriverManager 클래스

- DriverManager JDBC드라이버를 관리하기 위한 기본적인 클래스

- 데이터베이스 드라이버를 선택하고 새로운 데이터베이스 연결을 생성하는 기능을 한다.

- JDBC 4.0 (자바 6) 이상은 classpath 내의 JDBC드라이버가 자동으로 로드 되므로 Class.forName() 메소드를 사용하여 명시적으로 로드 하지 않아도 되지만, JDBC 4.0 미만은 수동으로 JDBC 드라이버를 로딩해야 한다.

 

java.sql.Connection 인터페이스

- 특정 데이터베이스 (DBMS) 와의 연결(session)을 나타내는 객체이다.

- Connection 객체는 쿼리를 실행하는 Statement, PreparedStatement 등의 객체를 생성하거나 COMMIT, ROLLBACK 등의 트랜잭션 처리를 위한 메소드를 제공한다.

- Connection의 객체는 DriverManager.getConnection() 메소드를 호출하여 얻는다.

import java.sql.Connection;
import java.sql.DriverManager;

// Singleton Pattern
public class DBConn {
	private static Connection conn;
	
	private DBConn() {		
	}

	public static Connection getConnection() {
		String url = "jdbc:oracle:thin:@//127.0.0.1:1521/xe"; // 12C 이상
		String user = "유저";
		String pwd = "비밀번호";
		
		if(conn == null) {
			try {
				Class.forName("oracle.jdbc.driver.OracleDriver"); // JDK 7부터 생략 가능
				conn = DriverManager.getConnection(url, user, pwd);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		return conn;
	}

	public static void close() {
		if(conn != null) {
			try {
				if(! conn.isClosed()) {
					conn.close();
				}
			} catch (Exception e) {
			}
		}
		
		conn = null;
		
	}
	
}

오라클과 연동하는 것을 클래스로 짜두면 나중에 클래스만 불러와서 하면되므로 편하다.

데이터베이스 ?

- 논리적으로 연관된 하나 이상의 자료의 모음으로 그 내용을 고도로 구조함으로써 검색과 갱신의 효율화를 꾀한 것이다. 즉, 몇 개의 자료 파일을 조직적으로 통합하여 자료 항목의 중복을 없애고 자료를 구조화하여 기억시켜 놓은 자료의 집합체라고 할 수 있다.

- 어느 한 조직의 여러 응용 시스템들이 공유(shared)할 수 있도록 통합(integrated), 저장(stored)된 운영(operational)데이터의 집합이다.

 

특징

- 실시간 접근(real-time accessibility) : 질의에 대한 실시간 처리 및 응답을 처리할 수 있도록 지원해 준다.

- 계속적인 변화(continuous evolution) : 삽입, 삭제, 갱신을 통해서 현재의 정확한 데이터를 동적으로 유지할 수 있다.

- 동시 공유(concurrent sharing)가 가능하여 여러 사용자가 동시에 공용할 수 있다.

- 내용에 의한 참조(content reference) : 위치나 주소가 아닌 데이터의 내용, 즉 값에 따라 참조할 수 있다.

 

DBMS ( Database Management System)

- DBMS란 파일 관리 시스템의 단점을 개선하여 데이터를 통합적으로 관리하는 소프트웨어로 컴퓨터에 수록한 수많은 자료들을 쉽고 빠르게 추가, 수정, 삭제, 검색 등을 할 수 있다.

- 종류 : Oracle, MS-SQL, Sybase, MySQL, MariaDB, ... emd

 

SQL (Structured Query Language)

1) SQL이란 ?

- 구조화 질의어

- 관계형 데이터베이스 관리 시스템(RDBMS)의 데이터를 관리하기 위해 설계된 특수 목적의 언어

- 관계형 데이터베이스 관리 시스템에서 자료의 검색과 관리, 데이터베이스 스키마 생성과 수정, 데이터베이스 객체 접근 조정 관리를 위해 고안

- 비 절차 언어

2) 종류

- DQL (Data Query Language) 데이터 질의 언어

  - SELECT문

- DML (Data Manipulation Language) 데이터 조작 언어

  - INSERT, UPDATE, DELETE, MARGE 문 - ROLLBACK 가능

- DDL (Data Definition Language) 데이터 정의 언어

  - 객체의 생성, 변경, 삭제 등의 명령어

  - CREATE, ALTER, DROP, RENAME, COMMENT(주석 달기), TRUNCATE 문 등

  - 자동 COMMIT, ROLLBACK불가능

- DCL (Data Control Language) 데이터 제어 언어

  - GRANT(권한부여), REVOKE(권한회수) 문

  - 자동 COMMIT, ROLLBACK불가능

 

JDBC ?

- 자바에서 데이터베이스에 일관된 방식으로 접근할 수 있도록 제공하는 API(Application Program Interface)

 - 자바를 이용한 데이터베이스 접속

 - SQL 문장 실행

 - SQL 실행 결과 얻어진 데이터 가져오기

 - 데이터베이스의 정보 및 실행 결과의 정보 가져오기

- JDBC API 클래스와 인터페이스는 자바 패키지 java.sql과 javax.sql에 포함되어 있다.

 

특징

- JDBC는 ANSI SQL-92 표준을 지원

- JDBC는 공통된 SQL인터페이스를 바탕으로 만들어짐

 

 

직렬화(Serialization)

- 직렬화란 자바 시스템 내부에서 사용되는 객체 또는 데이터를 자바 외부에서도 사용할 수 있도록 바이트(byte)단위로 변환하는 것을 말한다.

- 직렬화가 가능한 자료형 및 객체

  기본형 타입 (boolean, char, byte, short, int, long, float, double)

  Serializable 인터페이스를 구현한 클래스의 객체

  transient가 사용된 멤버변수(null 전송), static 멤버변수, 메소드는 직렬화 대상에서 제외된다.

 

역 직렬화(Deserialization)

- 직렬화된 바이트(byte)단위의 데이터를 다시 원래 데이터로 복원하는 것을 말한다.

 

java.io.Serializable 인터페이스

- 객체를 직렬화하기 위해서는 먼저, 객체를 직렬화가 가능하도록 Serializable 인터페이스를 구현해야 한다.

- 이 인터페이스는 객체 직렬화가 제공되어야 함을 자바 가상 머신에 알려주는 역할을 한다.

- Serializable 인터페이스는 다른 인터페이스와는 달리 구현해야 할 메소드가 없으므로 단지 Serializable 인터페이스만 implements 하면 된다.

- 객체의 직렬화 대상에서 제외되는 것은 멤버 변수가 static으로 선언된 경우, 멤버 변수가 transient로 선언된 경우와 메소드이다.

 

형식

public class 클래스명 implements Serializable {

 // 클래스 정의 부분

}

 

transient

- 직렬화 대상에서 제외할 멤버 변수는 transient 키워드를 사용하여 제외한다.

- transient 키워드가 붙은 멤버 변수가 복원되면, 숫자변수는 0, 객체는 null로 설정된다.

public class 클래스명 implements Serializable {

 접근제어자 자료형 변수1;

 접근제어자 transient 자료형 변수2;

 // 클래스 구현

}

 

SerialVersionUID 필드

- serialVersionUID 는 직렬화에 사용되는 고유 아이디로, 선언하지 않으면 JVM에서 디폴트로 자동생성된다.

  serialVersionUID는 역 직렬화 해서 읽어 들일 때 캐스팅한 클래스의 serialVersionUID와 역직렬화 한 serialVersionUID가 맞는지 확인하기 위해 사용된다.

- 선언하지 않아도 동작하는데 문제는 없지만, JVM에 의한 디폴트 serialVersionUID 계산은 클래스의 세부 사항을 매우 민감하게 반영하기 때문에 컴파일러 구현체에 따라서 달라질 수 있어 역 직렬화(deserialization) 과정에서 예상하지 못한 InvalidClassException을 유발할 수 있다. 

- Java에서는 명시적으로 serialVersionUID를 선언할 것을 적극 권장하고 있다.

- 선언 예

private static final long serialVersionUID = 1L;

 

예시>>

더보기

Main

import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Ex004_transient {
	public static void main(String[] args) {
		UserService ov = new UserService();
		ov.saveFile();
		ov.loadFile();
	}
}

 

Class

// Serializable : 직렬화
// 직렬화에서 제외되는 것 : 메소드, static 변수, transient 변수

class UserDTO implements Serializable { // 바이트로 고쳐서 저장해줌
	private static final long serialVersionUID = 1L; // 같은 클래스인지아닌지 확인용도
	
	private String name;
	private transient String tel; // 직렬화에서 제외됨. 네트워트로 전송이 되지 않음.
	private int age;

	public UserDTO() {
		
	}
	
	public UserDTO(String name, String tel, int age) {
		this.name = name;
		this.tel = tel;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getTel() {
		return tel;
	}

	public void setTel(String tel) {
		this.tel = tel;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
}

class UserService {
	private String pathname = "object2.txt";
	
	public void loadFile() {
		try( ObjectInputStream ois = new ObjectInputStream(new FileInputStream(pathname))) {
			
			System.out.println("파일 내용...");
			while(true) {
				UserDTO vo = (UserDTO) ois.readObject(); // 역직렬화수행
				System.out.println(vo.getName()+"\t"+vo.getTel()+"\t"+vo.getAge());
			}
			
		} catch (EOFException e) {
			// ObjectInputStream 스트림은 파일의 내용을 더 이상 읽을 수 없으면
			// EOFException 예외가 발생한다. 따라서 EOFException 예외를 catch하고
			// 아무런 코드도 작성하지 않는다. // 안잡으면 터짐
		}catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void saveFile() {
		// ObjectOutputStream : Serializable 인터페이스가 구현되어 있어야 저장가능하다.
		try ( ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(pathname))){

			oos.writeObject(new UserDTO("다자바", "010-0000-0000", 20));
			oos.writeObject(new UserDTO("너자바", "010-1111-0000", 20));
			oos.writeObject(new UserDTO("구자바", "010-2222-0000", 20));
			
			System.out.println("파일 저장 완료...");
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

클래스를 파일로 저장하고 그 파일을 읽어들이는 프로그램을 작성

 

소스 보기 >>

더보기

Main

import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class Ex003_ObjectStream {
	public static void main(String[] args) {
		User ov = new User();
		ov.saveFile();
		ov.loadFile();
	}
}

Class

// Serializable : 직렬화
// 직렬화에서 제외되는 것 : 메소드, static 변수, transient 변수

class UserVO implements Serializable { // 바이트로 고쳐서 저장해줌
	private static final long serialVersionUID = 1L; // 같은 클래스인지아닌지 확인용도
	
	private String name;
	private String tel;
	private int age;

	public UserVO() {
		
	}
	
	public UserVO(String name, String tel, int age) {
		this.name = name;
		this.tel = tel;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getTel() {
		return tel;
	}

	public void setTel(String tel) {
		this.tel = tel;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
}

class User {
	private String pathname = "object.txt";
	
	public void loadFile() {
		try( ObjectInputStream ois = new ObjectInputStream(new FileInputStream(pathname))) {
			
			System.out.println("파일 내용...");
			while(true) {
				UserVO vo = (UserVO) ois.readObject(); // 역직렬화수행
				System.out.println(vo.getName()+"\t"+vo.getTel()+"\t"+vo.getAge());
			}
			
		} catch (EOFException e) {
			// ObjectInputStream 스트림은 파일의 내용을 더 이상 읽을 수 없으면
			// EOFException 예외가 발생한다. 따라서 EOFException 예외를 catch하고
			// 아무런 코드도 작성하지 않는다. // 안잡으면 터짐
		}catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void saveFile() {
		// ObjectOutputStream : Serializable 인터페이스가 구현되어 있어야 저장가능하다.
		try ( ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(pathname))){
			UserVO vo = new UserVO("거자바", "010-1010-0000", 19);
			oos.writeObject(vo); // 주소 저장함. 직렬화해서 저장
			
			oos.writeObject(new UserVO("다자바", "010-0000-0000", 20));
			oos.writeObject(new UserVO("너자바", "010-1111-0000", 20));
			oos.writeObject(new UserVO("구자바", "010-2222-0000", 20));
			
			System.out.println("파일 저장 완료...");
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

클래스 UserVO를 Object 바이트 스트림으로 보내고 다시 Object 바이트 스트림으로 받았기 때문에. loadFile() 할때는 (UserVO)로 형변환을 해주어야 한다.  

 

 

 

 

 

 

java.io.ObjectOutputStream

- ObjectOutputStream 클래스는 객체들을 출력하는 기능을 제공하는 클래스로 출력 스트림에 출력하기 전에 직렬화를 수행한다.

- 파일이나 네트워크로 데이터를 전송하기 위해 직렬화를 수행하며, 이때 writeObject() 메소드를 사용하여 변환한다.

- 스트림에 저장할 수 있는 객체는 Serializable 인터페이스를 구현한 클래스의 객체만 가능하다.

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.util.Hashtable;

public class Ex001_ObjectOutputStream {

	public static void main(String[] args) {
		Hashtable<String, String> ht = new Hashtable<String, String>();
		
		ht.put("자바", "프로그래밍");
		ht.put("HTML", "웹 프로그래밍");
		ht.put("오라클", "데이터베이스");
		
		String pathname = "object.txt";
		ObjectOutputStream oos = null;
		
		try {
			// ObjectOutputStream : 객체를 저장 할 수 있는 스트림
			// 객체를 저장하면 파일 선두에는 객체의 클래스명이 저장된다.
			oos = new ObjectOutputStream(new FileOutputStream(pathname));
			oos.writeObject(ht);
			System.out.println("파일 저장 완료...");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(oos !=null ) {
				try {
					oos.close();
				} catch (Exception e2) {
				}
			}
		}
		
	}

}

 

위 코드를 실행하면 object.txt 파일이 저장되고 안에는 이렇게 되어있다.


java.io.ObjectInputStream

- ObjectOutputStream 클래스에 의해 파일에 저장되거나 네트워크를 통해 전달된 객체의 직렬화를 해제하는 기능을 제공한다.

- 파일이나 네트워크를 통해 받은 직렬화된 데이터를 다시 원래 데이터로 복원하는 역할을 하며, 이때 readObject() 메소드를 사용하여 복원한다.

- readObject() 메소드를 통해 읽어 들인 데이터는 원래 데이터로 캐스팅하여 사용한다.

- 스트림으로부터 읽어들일 수 있는 객체는 Serializable 인터페이스나 Externalizable 인터페이스를 구현한 클래스의 객체만 가능하다.

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.Hashtable;
import java.util.Iterator;

public class Ex002_ObjectInputStream {

	public static void main(String[] args) {
		String pathname = "object.txt";
		
		try ( ObjectInputStream ois = new ObjectInputStream(new FileInputStream(pathname))){
			// 제너릭은 다운 캐스팅하면 경고가 나옴.
			@SuppressWarnings("unchecked") // 경고없앰
			Hashtable<String, String> ht = (Hashtable<String, String>)ois.readObject();
			
			Iterator<String> it = ht.keySet().iterator();
			while(it.hasNext()) {
				String key = it.next();
				String value = ht.get(key);
				System.out.println(key+" -> "+value);
			}
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

위에서 만든 object.txt파일을 읽어들인 결과

Hashtable 은 Map의 구현 클래스로 동기화를 지원한다.

Map은 <키, 값>의 구조로 키는 중복을 허용하지 않는다. 키는 순서가 없으므로 반복자도 존재하지 않는다.

+ Recent posts