메타데이터 ?

- 부가적인 정보로, 컬럼명, 컬럼 타입, 컬럼폭, 등을 의미하여 ResultSet에서 얻어온다.

package metaEx;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;

import db_util.DBConn;

public class Ex001_MetaData {

	public static void main(String[] args) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		ResultSetMetaData rsmd = null;

		try {
			conn = DBConn.getConnection();

			String sql = "SELECT * FROM score";

			pstmt = conn.prepareStatement(sql);
			rs = pstmt.executeQuery();
			rsmd = rs.getMetaData();

			// 컬럼수
			int cols = rsmd.getColumnCount();
			System.out.println("전체 컬럼 수 : " + cols);

			for (int i = 1; i <= cols; i++) {
				System.out.print("컬럼명 : " + rsmd.getColumnName(i) + "\t");
				System.out.print("컬럼타입명 : " + rsmd.getColumnTypeName(i) + "\t");
				System.out.println("컬럼폭 : " + rsmd.getPrecision(i));
			}
			System.out.println();

			// 데이터
			// 테이블의 숫자, 날짜 형등은 문자열로 가져올 수 있다.
			while (rs.next()) {
				for (int i = 1; i <= cols; i++) {
					System.out.print(rs.getString(i) + "\t");
				}
				System.out.println();
			}

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

	}

}


package metaEx;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;

import db_util.DBConn;

public class Ex002_Matadata {

	public static void main(String[] args) {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		Connection conn = DBConn.getConnection();
		Statement stmt = null;
		ResultSet rs = null;
		ResultSetMetaData rsmd = null;

		String sql;

		try {
			System.out.print("쿼리 ? ");
			sql = br.readLine();
			sql = sql.trim();

			if (!sql.toUpperCase().startsWith("SELECT")) {
				System.out.println("SELECT 문만 가능합니다.");
				return;
			}

			stmt = conn.createStatement();
			rs = stmt.executeQuery(sql);
			rsmd = rs.getMetaData();

			int cols = rsmd.getColumnCount();
			for (int i = 1; i <= cols; i++) {
				System.out.print(rsmd.getColumnName(i) + "\t");
			}
			
			System.out.println();
			
			while (rs.next()) {
				for (int i = 1; i <= cols; i++) {
					System.out.print(rs.getString(i) + "\t");
				}
				System.out.println();
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (rs != null) {
				try {
					rs.close();
				} catch (Exception e2) {
				}
			}
			if (stmt != null) {
				try {
					stmt.close();
				} catch (Exception e2) {
				}
			}
		}

	}

}

 

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import db_util.DBConn;

/*
 - 결과 집합 유형
 	TYPE_FORWORD_ONLY : 기본. 순방향(next)만 가능
 	TYPE_SCROLL_SENSITIVE : 순방향, 역방향 가능, 수정 결과 바로 반영
 	TYPE_SCROLL_INSENSITIVE : 순방향, 역방향 가능, 수정 결과 바로 반영 안됨
 	
 - 동시성 유형
 	CONCUR_READ_ONLY : 기본. 읽기만 가능
 	CONCUR_UPDATABLE : 수정도 가능
 	
 */
public class Ex_Scroll {

	public static void main(String[] args) {
		Connection conn = DBConn.getConnection();
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		try {
			String sql = " SELECT hak, name, birth, kor, eng, mat FROM score ";
			
			// pstmt = conn.prepareStatement(sql); // 기본으로 순방향(next)만 가능
			
			// 순방향 및 역방향 가능
			pstmt = conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, 
					ResultSet.CONCUR_READ_ONLY); 
			
			rs = pstmt.executeQuery();
			
			char ch;
			while(true) {
				do {
					System.out.print("1.처음 2.이전 3.다음 4.마지막 5.종료 => ");
					ch = (char)System.in.read();
					System.in.skip(2); // 엔터 버림
				} while (ch<'1'||ch>'5');
				
				if(ch=='5') {
					break;
				}
				
				switch(ch) {
				case '1':
					if(rs.first())
						System.out.println("처음->"+rs.getString(1)+":"+rs.getString(2));
					break;
				case '2':
					if(rs.previous())
						System.out.println("이전->"+rs.getString(1)+":"+rs.getString(2));
					break;
				case '3':
					if(rs.next())
						System.out.println("다음->"+rs.getString(1)+":"+rs.getString(2));
					break;
				case '4':
					if(rs.last())
						System.out.println("마지막->"+rs.getString(1)+":"+rs.getString(2));
					break;
				}
				
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(rs != null) {
				try {
					rs.close();
				} catch (Exception e2) {
				}
			}
			
			if(pstmt != null) {
				try {
					pstmt.close();
				} catch (Exception e2) {
				}
			}
		}

	}

}

부하를 많이 준다.

 

 

트랜잭션 ? 

- 하나의 논리적인 작업 단위

- 자바에서 INSERT, UPDATE, DELETE 등의 작업을 실행하면 기본적으로 자동 COMMIT

 

실습용 테이블

더보기
CREATE TABLE test1 (
    id VARCHAR2(30) PRIMARY KEY,
    name VARCHAR2(30) NOT NULL
);

CREATE TABLE test2 (
    id VARCHAR2(30) PRIMARY KEY,
    birth VARCHAR2(30) NOT NULL,
    FOREIGN KEY(id) REFERENCES test1(id)
);

CREATE TABLE test3 (
    id VARCHAR2(30) PRIMARY KEY,
    tel VARCHAR2(30) NOT NULL,
    FOREIGN KEY(id) REFERENCES test1(id)
);

SELECT * FROM test1;
SELECT * FROM test2;
SELECT * FROM test3;
package transEx;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import db_util.DBConn;

public class Ex_Transaction {

	public static void main(String[] args) {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		
		Connection conn = DBConn.getConnection();
		PreparedStatement pstmt = null;
		
		String sql;
		String id, name, birth, tel;
		
		try {
			System.out.print("아이디 ? ");
			id = br.readLine();
			
			System.out.print("이름 ? ");
			name = br.readLine();
			
			System.out.print("생년월일 ? ");
			birth = br.readLine();
			
			// 전화번호를 입력하지 않고 그냥 엔터를 누를경우와 전화번호를 입력했을 때와 비교
			System.out.print("전화번호 ? ");
			tel = br.readLine();
			
			// 트랜잭션이 필요한 부분은 반드시 하나의 try 블록에서 모두 코드를 작성해야 한다.
			
			// 자동으로 COMMIT 되지 않도록 설정
			conn.setAutoCommit(false);
			
			sql = "INSERT INTO test1(id, name) VALUES (?, ?)";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, id);
			pstmt.setString(2, name);
			pstmt.executeUpdate();
			pstmt.close();
			
			sql = "INSERT INTO test2(id, birth) VALUES (?, ?)";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, id);
			pstmt.setString(2, birth);
			pstmt.executeUpdate();
			pstmt.close();
			
			sql = "INSERT INTO test3(id, tel) VALUES (?, ?)";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, id);
			pstmt.setString(2, tel);
			pstmt.executeUpdate();
			
			// 커밋
			conn.commit();
			
			System.out.println("데이터 추가 성공...");
		} catch (SQLException e) {
			try {
				// 세 개의 테이블 중 하나의 테이블이라도 추가하는 도중에 에러가 발생하면 모두 롤백
				conn.rollback();
			} catch (Exception e2) {
			}
			System.out.println(e.toString());
			System.out.println("데이터 추가 실패...");
		
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (pstmt != null) {
				try {
					pstmt.close();
				} catch (Exception e2) {
				}
			}
			
			try {
				conn.setAutoCommit(true);
			} catch (Exception e2) {
			}
			
			DBConn.close(); // 프로그램 종료 시
			
		}

	}

}

 

conn.setAutoCommit(false)를 통해 트랜잭션이 다 이뤄지고 나서 3개의 테이블에 모두 COMMIT되지 않는 경우에는 데이터가 들어가지 않도록 한다. 또 트랜잭션이 필요한 부분은 반드시 하나의 try 블록에서 모두 코드를 작성해야한다. 예외가 발생했을때는 ROLLBACK을 통해 데이터가 들어가지 않도록 해야한다.

쿼리 실행

- Statement

: 보안에 취약. 실무에서는 거의 사용하지 않는다.

: 필요시 트랜잭션 처리를 자바에서 해야한다.

 

- Prepared Statement 인터페이스

: 전처리된 Statement

: 주어진 SQL문을 미리 전처리해서 저장한다.

: 보안에 유리하다.

: 필요시 트랜잭션 처리를 자바에서 해야한다.

 

- Callable Statement

: 프로시저 실행

: 프로시저에서 트랜잭션을 처리한다.

 

App

더보기
package score3;

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

 

ScoreDAO

더보기
package score3;

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

public interface ScoreDAO {
	public int insertScore(ScoreDTO dto) throws SQLException;
	public int updateScore(ScoreDTO dto) throws SQLException;
	public int deleteScore(String hak) throws SQLException;
	
	public ScoreDTO readScore(String hak);
	public List<ScoreDTO> listScore();
	public List<ScoreDTO> listScore(String name);
	
	public Map<String, Integer> averageScore();
}

 

ScoreDAOImpl

더보기
package score3;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLDataException;
import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import db_util.DBConn;
import oracle.jdbc.OracleTypes;

public class ScoreDAOImpl implements ScoreDAO {
	private Connection conn = DBConn.getConnection();
	
	@Override
	public int insertScore(ScoreDTO dto) throws SQLException {
		int result = 0;
		CallableStatement cstmt = null;
		String sql;
		
		// INSERT INTO 테이블명(컬럼, 컬럼) VALUES (값, 값)
		try {
			// 자바에서 프로시저를 호출할 때는 CALL로 실행한다.
			sql = "{ CALL insertScore(?, ?, ?, ?, ?, ?) }";
			
			cstmt = conn.prepareCall(sql);
			
			// ?에 setter를 이용하여 컬럼에 대입할 값을 할당한다.
			cstmt.setString(1, dto.getHak());
			cstmt.setString(2, dto.getName());
			cstmt.setString(3, dto.getBirth());
			cstmt.setInt(4, dto.getKor());
			cstmt.setInt(5, dto.getEng());
			cstmt.setInt(6, dto.getMat());
			
			// 쿼리를 실행한다. 반환 값은 프로시저 실행 여부이다.
			result = cstmt.executeUpdate(); // DML, DDL 실행
			
		} catch (SQLIntegrityConstraintViolationException e) {
			// 기본키 중복, NOT NULL등의 제약 조건 위반에 의한 예외 - 무결성 제약 조건 위반
			// 에러 코드는 오라클 기준이며 마리아디비등은 다를 수 있음
			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(cstmt != null) {
				try {
					cstmt.close();
				} catch (Exception e2) {
				}
			}
		}
		
		return result;
	}

	@Override
	public int updateScore(ScoreDTO dto) throws SQLException {
		int result = 0;
		CallableStatement cstmt = null;
		String sql;
		
		try {
			sql = "{ CALL updateScore(?,?,?,?,?,?) }";
			
			cstmt = conn.prepareCall(sql);
			
			cstmt.setString(1, dto.getName());
			cstmt.setString(2, dto.getBirth());
			cstmt.setInt(3, dto.getKor());
			cstmt.setInt(4, dto.getEng());
			cstmt.setInt(5, dto.getMat());
			cstmt.setString(6, dto.getHak());
			
			result =cstmt.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) {
			if(e.getErrorCode()==20100) {
				System.out.println("등록된 자료가 아닙니다.");
			} else {
				e.printStackTrace();
			}
			throw e;
		} finally {
			if ( cstmt != null) {
				try {
					cstmt.close();
				} catch (Exception e2) {
				}
			}
		}
		
		return result;
	}

	@Override
	public int deleteScore(String hak) throws SQLException {
		int result = 0;
		CallableStatement cstmt = null;
		String sql;
		
		// DELETE FROM 테이블 WHERE 조건
		try {
			sql = "{ CALL deleteScore(?) }";
			
			cstmt = conn.prepareCall(sql);
			
			cstmt.setString(1, hak);
			
			result = cstmt.executeUpdate();
			
		} catch (SQLException e) {
			if(e.getErrorCode()==20100) {
				System.out.println("등록된 자료가 아닙니다.");
			} else {
				e.printStackTrace();				
			}
			throw e;
		} finally {
			if(cstmt !=null) {
				try {
					cstmt.close();
				} catch (Exception e2) {
				}
			}	
		}
		
		return result;
	}

	@Override
	public ScoreDTO readScore(String hak) {
		ScoreDTO dto = null;
		CallableStatement cstmt = null;
		ResultSet rs = null;
		String sql;
		
		try {
			sql = "{ CALL readScore(?, ?) }";
			cstmt = conn.prepareCall(sql);
			// OUT 파라미터는 파라미터의 타입을 설정한다.
			cstmt.registerOutParameter(1, OracleTypes.CURSOR); 
			// 오라클의 SYS_REFCURSOR
			
			// IN 파라미터 
			cstmt.setString(2, hak);
			
			// 프로시저 실행. 모든 프로시저는 executeUpdate()로 실행
			cstmt.executeUpdate();
			
			// OUT 파라미터 값 넘겨 받기
			rs = (ResultSet) cstmt.getObject(1); 
			// SYS_REFCURSOR는 ResultSet로 반환 받는다.
			
			// 기본키 조건에 만족하는 레코드는 1개 또는 0개
			if(rs.next()) {
				dto = new ScoreDTO();
				
				dto.setHak(rs.getString("hak"));
				dto.setName(rs.getString("name"));
				dto.setBirth(rs.getString("birth"));
				dto.setKor(rs.getInt("kor"));
				dto.setEng(rs.getInt("eng"));
				dto.setMat(rs.getInt("mat"));
				dto.setTot(rs.getInt("tot"));
				dto.setAve(rs.getInt("ave"));
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(rs != null) {
				try {
					rs.close();
				} catch (Exception e2) {
				}
			}
			if(cstmt != null) {
				try {
					cstmt.close();
				} catch (Exception e2) {
				}
			}
		}
		
		return dto;
	}

	@Override
	public List<ScoreDTO> listScore() {
		List<ScoreDTO> list = new ArrayList<ScoreDTO>();
		CallableStatement cstmt = null;
		ResultSet rs = null;
		String sql;
		
		try {
			sql = "{ CALL listScore(?) }";
			cstmt = conn.prepareCall(sql);
			
			cstmt.registerOutParameter(1, OracleTypes.CURSOR);
			
			cstmt.executeUpdate();
			
			rs = (ResultSet) cstmt.getObject(1);
			
			// 테이블의 모든 레코드를 읽어 List에 저장
			while(rs.next()) {
				ScoreDTO dto = new ScoreDTO();
				
				dto.setHak(rs.getString("hak")); // dto.setHak(rs.getString(1));
				dto.setName(rs.getString("name")); // dto.setName(rs.getString(2));
				dto.setBirth(rs.getDate("birth").toString());
				// dto.setBirth(rs.getDate("birth")); // yyyy-mm-dd hh:mi:ss
				dto.setKor(rs.getInt("kor"));
				dto.setEng(rs.getInt("eng"));
				dto.setMat(rs.getInt("mat"));
				dto.setTot(rs.getInt("tot"));
				dto.setAve(rs.getInt("ave"));
				dto.setRank(rs.getInt("rank"));
				
				list.add(dto); // List에 저장
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if(rs != null) {
				try {
					rs.close();
				} catch (Exception e2) {
				}
			}
			
			if (cstmt != null) {
				try {
					cstmt.close();
				} catch (Exception e2) {
				}
			}
		}
		
		return list;
	}

	@Override
	public List<ScoreDTO> listScore(String name) {
		List<ScoreDTO> list = new ArrayList<ScoreDTO>();
		CallableStatement cstmt = null;
		ResultSet rs = null;
		String sql;
		
		try {
			sql = " { CALL searchNameScore(?, ?) } ";
			cstmt = conn.prepareCall(sql);
			
			cstmt.registerOutParameter(1, OracleTypes.CURSOR);
			cstmt.setString(2, name);
			
			cstmt.executeUpdate();
			
			rs = (ResultSet) cstmt.getObject(1);
			
			while(rs.next()) {
				ScoreDTO dto = new ScoreDTO();
				dto.setHak(rs.getString("hak"));
				dto.setName(rs.getString("name"));
				dto.setBirth(rs.getDate("birth").toString());
				dto.setKor(rs.getInt("kor"));
				dto.setEng(rs.getInt("eng"));
				dto.setMat(rs.getInt("mat"));
				
				list.add(dto);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(rs != null) {
				try {
					rs.close();
				} catch (Exception e2) {
				}
			}
			
			if (cstmt != null) {
				try {
					cstmt.close();
				} catch (Exception e2) {
				}
			}
		}
		
		return list;
	}

	@Override
	public Map<String, Integer> averageScore() {
		Map<String, Integer> map = new HashMap<String, Integer>();
		CallableStatement cstmt = null;
		String sql;
		
		try {
			sql = " { CALL averageScore(?, ?, ?) } ";
			cstmt = conn.prepareCall(sql);
			
			cstmt.registerOutParameter(1, OracleTypes.INTEGER);
			cstmt.registerOutParameter(2, OracleTypes.INTEGER);
			cstmt.registerOutParameter(3, OracleTypes.INTEGER);
			
			cstmt.executeUpdate();
			
			int kor = cstmt.getInt(1);
			int eng = cstmt.getInt(2);
			int mat = cstmt.getInt(3);
			
			map.put("kor", kor);
			map.put("eng", eng);
			map.put("mat", mat);
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(cstmt != null) {
				try {
					cstmt.close();
				} catch (Exception e2) {
				}
			}
		}
		
		return map;
	}

}

 

ScoreDTO

더보기
package score3;

public class ScoreDTO {
	private String hak;
	private String name;
	private String birth;
	private int kor;
	private int eng;
	private int mat;
	
	private int tot;
	private int ave;
	private int rank;
	
	public String getHak() {
		return hak;
	}
	public void setHak(String hak) {
		this.hak = hak;
	}
	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 int getKor() {
		return kor;
	}
	public void setKor(int kor) {
		this.kor = kor;
	}
	public int getEng() {
		return eng;
	}
	public void setEng(int eng) {
		this.eng = eng;
	}
	public int getMat() {
		return mat;
	}
	public void setMat(int mat) {
		this.mat = mat;
	}
	public int getTot() {
		return tot;
	}
	public void setTot(int tot) {
		this.tot = tot;
	}
	public int getAve() {
		return ave;
	}
	public void setAve(int ave) {
		this.ave = ave;
	}
	public int getRank() {
		return rank;
	}
	public void setRank(int rank) {
		this.rank = rank;
	}
}

 

ScoreUI

더보기
package score3;

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

import db_util.DBConn;

public class ScoreUI {
	private BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	private ScoreDAO dao = new ScoreDAOImpl();
	
	public void menu() {
		int ch;
		
		System.out.println("Callable Statement 예제...");
		
		while(true) {
			try {
				do {
					System.out.print("1.등록 2.수정 3.삭제 4.학번검색 5.이름검색 6.리스트 7.과목별평균 8.종료 => ");
					ch = Integer.parseInt(br.readLine());
				} while(ch < 1 || ch > 8);
				
				if(ch == 8) {
					DBConn.close();
					return;
				}
				
				switch(ch) {
				case 1: insert(); break;
				case 2: update(); break;
				case 3: delete(); break;
				case 4: findByHak(); break;
				case 5: findByName(); break;
				case 6: listAll(); break;
				case 7: average(); break;
				}
				
			} catch (Exception e) {
			}
		}
		
	}
	
	public void insert() {
		System.out.println("\n데이터 등록...");
		
		ScoreDTO dto = new ScoreDTO();
		try {
			System.out.print("학번 ? ");
			dto.setHak(br.readLine());
			
			System.out.print("이름 ? ");
			dto.setName(br.readLine());
			
			System.out.print("생년월일 ? ");
			dto.setBirth(br.readLine());
			
			System.out.print("국어 ? ");
			dto.setKor(Integer.parseInt(br.readLine()));
			
			System.out.print("영어 ? ");
			dto.setEng(Integer.parseInt(br.readLine()));
			
			System.out.print("수학 ? ");
			dto.setMat(Integer.parseInt(br.readLine()));
			
			dao.insertScore(dto);
			System.out.println("데이터 추가 완료...");
		} catch (NumberFormatException e) {
			System.out.println("점수는 숫자만 가능합니다.");
		} catch (Exception e) {
			System.out.println("데이터 등록에 실패 했습니다.");
			// e.printStackTrace();
		}
		System.out.println();
	}
	
	public void update() {
		System.out.println("\n데이터 수정...");
		
		String hak;
		try {
			System.out.print("수정할 학번 ? ");
			hak = br.readLine();
			
			ScoreDTO dto = dao.readScore(hak);
			if(dto == null) {
				System.out.println("등록된 자료가 없습니다.\n");
				return;
			}
			
			System.out.print("수정할 이름 ? ");
			dto.setName(br.readLine());
			
			System.out.print("생년월일 ? ");
			dto.setBirth(br.readLine());
			
			System.out.print("국어 ? ");
			dto.setKor(Integer.parseInt(br.readLine()));
			
			System.out.print("영어 ? ");
			dto.setEng(Integer.parseInt(br.readLine()));
			
			System.out.print("수학 ? ");
			dto.setMat(Integer.parseInt(br.readLine()));
			
			dao.updateScore(dto);
			
			System.out.println("데이터 수정이 완료 되었습니다.");
			
		} catch (NumberFormatException e) {
			System.out.println("점수는 숫자만 가능합니다.");
		} catch (Exception e) {
			System.out.println("데이터 수정에 실패 했습니다.");
			// e.printStackTrace();
		}
		System.out.println();
		
	}
	
	public void delete() {
		System.out.println("\n데이터 삭제...");
		
		String hak;
		try {
			System.out.print("삭제할 학번 ? ");
			hak = br.readLine();
			
			dao.deleteScore(hak);
			
			System.out.println("삭제 완료...\n");
			
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("삭제 실패...\n");
		}
	}
	
	public void findByHak() {
		System.out.println("\n학번 검색...");
		String hak;
		
		try {
			System.out.print("검색할 학번 ? ");
			hak = br.readLine();
			
			ScoreDTO dto = dao.readScore(hak);
			if ( dto == null) {
				System.out.println("등록된 자료가 없습니다.\n");
				return;
			}
			
			System.out.print(dto.getHak()+"\t");
			System.out.print(dto.getName()+"\t");
			System.out.print(dto.getBirth()+"\t");
			System.out.print(dto.getKor()+"\t");
			System.out.print(dto.getEng()+"\t");
			System.out.print(dto.getMat()+"\t");
			System.out.print(dto.getTot()+"\t");
			System.out.println(dto.getAve());
			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<ScoreDTO> list = dao.listScore(name);
			if(list.size() == 0) {
				System.out.println("등록된 자료가 없습니다.\n");
				return;
			}
			
			for(ScoreDTO dto : list) {
				System.out.print(dto.getHak()+"\t");
				System.out.print(dto.getName()+"\t");
				System.out.print(dto.getBirth()+"\t");
				System.out.print(dto.getKor()+"\t");
				System.out.print(dto.getEng()+"\t");
				System.out.println(dto.getMat());
			}
			System.out.println();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public void listAll() {
		System.out.println("\n전체 리스트...");
		
		List<ScoreDTO> list = dao.listScore();
		System.out.println("학번\t이름\t생년월일\t\t국어\t영어\t수학\t총점\t평균\t석차");
		System.out.println("----------------------------------------------------------------------------");
		for(ScoreDTO dto : list) {
			System.out.print(dto.getHak()+"\t");
			System.out.print(dto.getName()+"\t");
			System.out.print(dto.getBirth()+"\t");
			System.out.print(dto.getKor()+"\t");
			System.out.print(dto.getEng()+"\t");
			System.out.print(dto.getMat()+"\t");
			System.out.print(dto.getTot()+"\t");
			System.out.print(dto.getAve()+"\t");
			System.out.println(dto.getRank());
		}
		System.out.println();
	}
	
	public void average() {
		System.out.println("\n과목별 평균 점수");
		
		Map<String, Integer> map = dao.averageScore();
		
		try {
			int kor = map.get("kor");
			int eng = map.get("eng");
			int mat = map.get("mat");
			
			System.out.println("국어:"+kor);
			System.out.println("영어:"+eng);
			System.out.println("수학:"+mat);
			
		} catch (Exception e) {
			
		}
		System.out.println();
		
	}
}

 

프로시저

더보기
-- 프로시저에서 DML(INSERT, UPDATE, DELETE)작업 후 반드시 COMMIT
CREATE OR REPLACE PROCEDURE insertScore
(
    pHak IN score.hak%TYPE,
    pName IN score.name%TYPE,
    pBirth IN score.birth%TYPE,
    pKor IN score.kor%TYPE,
    pEng IN score.eng%TYPE,
    pMat IN score.mat%TYPE
)
IS
BEGIN
    INSERT INTO score(hak,name,birth,kor,eng,mat) VALUES
    (pHak, pName, pBirth, pKor, pEng, pMat);
    COMMIT;
END;
/

SELECT * FROM user_procedures;

EXEC insertScore('5555', '마마마', '2003-03-03', 80, 90, 70);

SELECT * FROM score;

-- 수정 프로시저
CREATE OR REPLACE PROCEDURE updateScore
(
    pName IN score.name%TYPE,
    pBirth IN score.birth%TYPE,
    pKor IN score.kor%TYPE,
    pEng IN score.eng%TYPE,
    pMat IN score.mat%TYPE,
    pHak IN score.hak%TYPE
)
IS
BEGIN
    UPDATE score SET name=pName, birth=pBirth, kor=pKor, eng=pEng,
        mat=pMat WHERE hak=pHak;
        IF SQL%NOTFOUND THEN
            RAISE_APPLICATION_ERROR(-20100, '존재하지 않는 자료입니다.');
        END IF;
        COMMIT;
END;
/

EXEC updateScore('마마마', '2000-10-10', 100, 100, 100, '5555');

SELECT * FROM score;

-- 삭제 프로시저
CREATE OR REPLACE PROCEDURE deleteScore
(
    pHak IN score.hak%TYPE
)
IS
BEGIN
    DELETE FROM score WHERE hak = pHak;
    IF SQL%NOTFOUND THEN
        RAISE_APPLICATION_ERROR(-20100, '존재하지 않는 자료 입니다.');
    END IF;
    COMMIT;
END;
/

EXEC deleteScore('5555');
SELECT * FROM score;

-- 학번 검색 프로시저
CREATE OR REPLACE PROCEDURE readScore
(
    pResult OUT SYS_REFCURSOR,
    pHak IN VARCHAR2
)
IS
BEGIN
    OPEN pResult  FOR
        SELECT hak, name, TO_CHAR(birth, 'YYYY-MM-DD') birth, kor, eng, mat,
            (kor+eng+mat) tot, (kor+eng+mat)/3 ave
        FROM score where hak = pHak;
END;
/

-- 전체 리스트 프로시저
CREATE OR REPLACE PROCEDURE listScore
(
    pResult OUT SYS_REFCURSOR
)
IS
BEGIN
    OPEN pResult FOR
        SELECT hak, name, birth, kor, eng, mat, 
            (kor+eng+mat) tot, (kor+eng+mat)/3 ave,
            RANK() OVER( ORDER BY (kor+eng+mat) DESC ) rank
        FROM score;

END;
/

-- 이름 검색 프로시저
CREATE OR REPLACE PROCEDURE searchNameScore
(
    pResult OUT SYS_REFCURSOR,
    pName IN VARCHAR2
)
IS
BEGIN
    OPEN pResult  FOR
        SELECT hak, name, birth, kor, eng, mat,
            (kor+eng+mat) tot, (kor+eng+mat)/3 ave
        FROM score where INSTR(name, pName) >= 1;
END;
/

-- 각 과목 평균프로시저
CREATE OR REPLACE PROCEDURE averageScore
(
    pKor OUT NUMBER,
    pEng OUT NUMBER,
    pMat OUT NUMBER
)
IS
BEGIN
    SELECT NVL(AVG(kor), 0), NVL(AVG(eng), 0), NVL(AVG(mat), 0)
        INTO pKor, pEng, pMat 
    FROM score;
END;
/

테이블

더보기
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;
		
	}
	
}

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

+ Recent posts