JDBC 성적 처리 프로그램

17849 단어 JDBCJDBC
○ 성적 처리 → 데이터베이스 연동(데이터베이스 연결 및 액션 처리)
 				ScoreDTO 클래스 활용(속성만 존재하는 클래스, getter / setter 구성
 				ScoreDAO 클래스 활용(데이터베이스 액션 처리)
 				Process 클래스 활용 (업무 단위 기능 구성)
 				DBConn 클래스 활용 (데이터베이스 연결 전담 전용 객체 처리)

여러 명의 이름, 국어점수, 영어점수, 수학점수를 입력받아
총점, 평균, 석차 등을 계산하여 출력하는 프로그램을 구현한다.
※ 서브 메뉴 구성 → Process 클래스 활용

실행 예)

====[ 성적 처리 ]====
1. 성적 입력
2. 성적 전체 출력
3. 이름 검색 출력
4. 성적 수정
5. 성적 삭제
=====================
>> 선택(1~5, -1:종료) : 1

7번 학생 성적 입력(이름 국어 영어 수학) : 이시우 50 60 70
성적 입력이 완료되었습니다.
8번 학생 성적 입력(이름 국어 영어 수학) : 이지연 80 80 80
성적 입력이 완료되었습니다.
9번 학생 성적 입력(이름 국어 영어 수학) : .  

====[ 성적 처리 ]====
1. 성적 입력
2. 성적 전체 출력
3. 이름 검색 출력
4. 성적 수정
5. 성적 삭제
=====================
>> 선택(1~5, -1:종료) : 2

전체 인원 : 8명
번호   이름   국어   영어   수학   총점   평균   석차
 1
 2
 3
 4                         :
 5                         :
 6
 7
 8
 
====[ 성적 처리 ]====
1. 성적 입력
2. 성적 전체 출력
3. 이름 검색 출력
4. 성적 수정
5. 성적 삭제
=====================
>> 선택(1~5, -1:종료) : 
*/

DBConn.java (throws)

package com.util;

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

public class DBConn
{
	private static Connection dbConn;
	
	public static Connection getConnection() throws ClassNotFoundException, SQLException
	{
		if (dbConn == null)
		{
			String url = "jdbc:oracle:thin:@localhost:1521:xe";
			String user = "scott";
			String pwd = "tiger";
			
			Class.forName("oracle.jdbc.driver.OracleDriver");
			dbConn = DriverManager.getConnection(url, user, pwd);
		}
		
		return dbConn;
	}
	
	public static Connection getConnection(String url, String user, String pwd) throws ClassNotFoundException, SQLException
	{
		if (dbConn == null)
		{
			Class.forName("oracle.jdbc.driver.OracleDriver");
			dbConn = DriverManager.getConnection(url, user, pwd);
			
		}
		return dbConn;
	}
	
	public static void close() throws SQLException
	{
		if (dbConn != null)
		{
			if (!dbConn.isClosed())
			{
				dbConn.close();
			}
		}
		
		dbConn = null;
	}
}

ScoreDTO.java (데이터 보관 및 전송 전용 객체)

package com.test;

public class ScoreDTO
{
	// 주요 속성 구성
	private String sid, name;   // 번호, 이름 sid를 int가 아니라 string으로 한 이유는, 연산을 할 것 아니기 때문에 string으로 하는게 더 편하다.
	private int kor, eng, mat;  // 국어 영어 수학 점수
	private int tot, rank;      // 총점, 석차
	private double avg;         // 평균
	
	// getter / setter 구성 
	public String getSid()
	{
		return sid;
	}
	public void setSid(String sid)
	{
		this.sid = sid;
	}
	public String getName()
	{
		return name;
	}
	public void setName(String name)
	{
		this.name = name;
	}
	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 getRank()
	{
		return rank;
	}
	public void setRank(int rank)
	{
		this.rank = rank;
	}
	public double getAvg()
	{
		return avg;
	}
	public void setAvg(double avg)
	{
		this.avg = avg;
	}
	
	
}

ScoreDAO (데이터베이스 액션 처리 전용 클래스)

package com.test;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

import com.util.DBConn;

public class ScoreDAO
{
	// 주요 속성 구성
	private Connection conn;
	
	// 데이터베이스 연결 담당 메소드
	public Connection connection() throws ClassNotFoundException, SQLException
	{
		conn = DBConn.getConnection();
		return conn;
	}
	
	
	// 데이터 입력 담당 메소드
	public int add(ScoreDTO dto) throws SQLException
	{
		// 결과값을 반환할 변수 선언
		int result = 0;
		
		// 작업 객체
		Statement stmt = conn.createStatement();
		
		// 쿼리문 준비
		String sql = String.format("INSERT INTO TBL_SCORE(SID, NAME, KOR, ENG, MAT)"
							    + " VALUES(SCORESEQ.NEXTVAL, '%s', %d, %d, %d)"
								  , dto.getName(), dto.getKor(), dto.getEng(), dto.getMat());
		
		// 작업객체를 활용해 쿼리문을 전달(실행)
		result = stmt.executeUpdate(sql); 
		
		// 리소스 반납
		stmt.close();
		
		return result;
	}
	
	
	// 전체 리스트 출력 담당 메소드
	public ArrayList<ScoreDTO> lists() throws SQLException
	{
		// 결과값을 반환할 변수 선언
		ArrayList<ScoreDTO> result = new ArrayList<ScoreDTO>();
		
		// 작업 객체
		Statement stmt = conn.createStatement();
		
		// 쿼리문 준비
		String sql = "SELECT SID, NAME, KOR, ENG, MAT"
					+ ", (KOR + ENG + MAT) AS TOT"
					+ ", (KOR + ENG + MAT)/3 AS AVG"
					+ ", RANK() OVER(ORDER BY (KOR+ENG+MAT) DESC) AS RANK"
					+ " FROM TBL_SCORE"
					+ " ORDER BY SID ASC";
		
		// 작업객체를 통해 쿼리문 실행(전달)
		ResultSet rs = stmt.executeQuery(sql);
		
		while (rs.next())
		{
			ScoreDTO dto = new ScoreDTO();
			
			dto.setSid(rs.getString("SID"));
			dto.setName(rs.getString("NAME"));
			dto.setKor(rs.getInt("KOR"));
			dto.setEng(rs.getInt("ENG"));
			dto.setMat(rs.getInt("MAT"));
			dto.setTot(rs.getInt("TOT"));
			dto.setAvg(rs.getDouble("AVG"));
			dto.setRank(rs.getInt("RANK"));
			
			result.add(dto);
			// ArrayList의 add() 메소드는 인자로 전달된 객체를 리스트에 추가합니다.
			
		}
		
		rs.close();
		stmt.close();
		
		return result;
	}
	
	
	// 이름 검색 담당 메소드
	public ArrayList<ScoreDTO> lists(String name) throws SQLException
	{
		ArrayList<ScoreDTO> result = new ArrayList<ScoreDTO>();
		
		// 작업 객체 생성
		Statement stmt = conn.createStatement();
		
		// 쿼리문 준비
		String sql = String.format("SELECT SID, NAME, KOR, ENG, MAT, TOT, AVG, RANK"
				+ " FROM"
				+ " (SELECT SID, NAME, KOR, ENG, MAT, (KOR + ENG + MAT) AS TOT"
				+ ", (KOR + ENG + MAT)/3 AS AVG"
				+ ", RANK() OVER(ORDER BY (KOR+ENG+MAT) DESC) AS RANK"
				+ " FROM TBL_SCORE)"
				+ " WHERE NAME = '%s'", name);
		
		// 작업 객체 활용해 쿼리문 전달
		ResultSet rs = stmt.executeQuery(sql);
		
		// 반복문
		while (rs.next())
		{
			ScoreDTO dto = new ScoreDTO();
			
			dto.setSid(rs.getString("SID"));
			dto.setName(rs.getString("NAME"));
			dto.setKor(rs.getInt("KOR"));
			dto.setEng(rs.getInt("ENG"));
			dto.setMat(rs.getInt("MAT"));
			dto.setTot(rs.getInt("TOT"));
			dto.setAvg(rs.getDouble("AVG"));
			dto.setRank(rs.getInt("RANK"));
			
			result.add(dto);
			
		}
		
		rs.close();
		stmt.close();

		return result;
	}
	
	
	// 번호 검색 담당 메소드 
	// string 이 아니라 int형으로 넘겨주는 이유는 이미 오버로딩된 lists(string name)이 있기때문이다
	public ArrayList<ScoreDTO> lists(int sid) throws SQLException
	{
		ArrayList<ScoreDTO> result = new ArrayList<ScoreDTO>();
		
		// 작업 객체 생성
		Statement stmt = conn.createStatement();
		
		// 쿼리문 준비
		String sql = String.format("SELECT SID, NAME, KOR, ENG, MAT, TOT, AVG, RANK"
				+ " FROM"
				+ " (SELECT SID, NAME, KOR, ENG, MAT, (KOR + ENG + MAT) AS TOT"
				+ ", (KOR + ENG + MAT)/3 AS AVG"
				+ ", RANK() OVER(ORDER BY (KOR+ENG+MAT) DESC) AS RANK"
				+ " FROM TBL_SCORE)"
				+ " WHERE SID = %d", sid);
		
		// 작업 객체 활용해 쿼리문 전달
		ResultSet rs = stmt.executeQuery(sql);
		
		// 반복문
		while (rs.next())
		{
			ScoreDTO dto = new ScoreDTO();
			
			dto.setSid(rs.getString("SID"));
			dto.setName(rs.getString("NAME"));
			dto.setKor(rs.getInt("KOR"));
			dto.setEng(rs.getInt("ENG"));
			dto.setMat(rs.getInt("MAT"));
			dto.setTot(rs.getInt("TOT"));
			dto.setAvg(rs.getDouble("AVG"));
			dto.setRank(rs.getInt("RANK"));
			
			result.add(dto);
		}
		
		rs.close();
		stmt.close();

		return result;
	}
	
	
	
	// 인원 수 확인 담당 메소드
	public int count() throws SQLException
	{
		int result = 0;
		
		Statement stmt = conn.createStatement();
		
		String sql = "SELECT COUNT(*) AS COUNT FROM TBL_SCORE";
		
		ResultSet rs = stmt.executeQuery(sql);
		
		while (rs.next()) 					// 단일 값 이므로 if (rs.next())이렇게 해도 상관없음 
			result = rs.getInt("COUNT");    // result = rs.getInt(1);
		
		rs.close();
		stmt.close();
		
		return result;
		
	}
	
	
	// 데이터 수정 담당 메소드 → 매개변수의 유형 check!!! (찾는 메소드와 수정하는 메소드는 따로따로다.. 주의해야함!!!!!)
	public int modify(ScoreDTO dto) throws SQLException
	{
		int result = 0;
		Statement stmt = conn.createStatement();
		String sql = String.format("UPDATE TBL_SCORE SET NAME='%s', KOR=%d, ENG=%d, MAT=%d WHERE SID = %s"
								, dto.getName(), dto.getKor(), dto.getEng(), dto.getMat(), dto.getSid());
		result = stmt.executeUpdate(sql);
		stmt.close();
		
		
		return result;
	}
	
	
	// 데이터 삭제 담당 메소드 
	public int remove(int sid) throws SQLException
	{
		int result = 0;
		Statement stmt = conn.createStatement();
		String sql = String.format("DELETE FROM TBL_SCORE WHERE SID=%d", sid);
		result = stmt.executeUpdate(sql);
		stmt.close();
		
		
		return result;
	}
	
	
	// 데이터베이스 연결 종료 담당 메소드
	public void close() throws SQLException
	{
		DBConn.close();
	}
	
}

Process.java

/*
1. 성적 입력
2. 성적 전체 출력
3. 이름 검색 출력
4. 성적 수정
5. 성적 삭제
*/

package com.test;

import java.util.ArrayList;
import java.util.Scanner;

public class Process
{
	// 공통적으로 필요한 주요 속성 → 데이터베이스 액션 처리 전담 객체 → ScoreDAO
	private ScoreDAO dao;
	
	// 생성자 정의(사용자 정의 생성자)
	public Process()
	{
		dao = new ScoreDAO();
	}
	
	
	// 성적 입력 기능
	public void sungjukInsert()
	{
		try
		{
			//데이터베이스 연결
			dao.connection();
			
			// 레코드 수 확인
			int count = dao.count();
			
			Scanner sc = new Scanner(System.in);
			
			do
			{
				System.out.println();
				System.out.printf("%d번 학생 성적 입력(이름 국어 영어 수학) : ", (++count));
				String name = sc.next();
				
				if (name.equals("."))
				{
					break;
				}
				
				int kor = sc.nextInt();
				int eng = sc.nextInt();
				int mat = sc.nextInt();
				
				// 입력받은 항목들 토대로 ScoreDTO 객체 구성
				ScoreDTO dto = new ScoreDTO();
				dto.setName(name);
				dto.setKor(kor);
				dto.setEng(eng);
				dto.setMat(mat);
				
				
				// dao의 add() 메소드 호출
				int result = dao.add(dto);
				
				if (result > 0)
				{
					System.out.println("성적 입력이 완료되었습니다.");
				}
				
			} while (true);
			
			// 데이터베이스 연결 종료
			dao.close();
			
		} catch (Exception e)
		{
			System.out.println(e.toString());
		}
	}
	
	// 성적 전체 출력
	public void sungjukSelectAll()
	{
		try
		{
			// dao 의 connection() 메소드 호출 → 데이터베이스 연결!
			dao.connection();
			
			// dao 의 count() 메소드 호출 → 인원수 확인
			int count = dao.count();
			
			System.out.println();
			System.out.printf("전체 인원 : %d명\n", count);
			System.out.println("번호   이름   국어   영어   수학   총점   평균   석차");
			
			// 전체 데이터 출력 담당 메소드 dao의 lists() 메소드
			for (ScoreDTO dto : dao.lists())
			{
				System.out.printf("%3s  %4s  %4d  %5d  %5d  %5d  %5.1f  %5d\n"
								, dto.getSid(), dto.getName(), dto.getKor(), dto.getEng(), dto.getMat()
								, dto.getTot(), dto.getAvg(), dto.getRank() );
			}
			
			// dao의 close() 메소드 호출 → 데이터베이스 연결 종료
			dao.close();
			
			
		} catch (Exception e)
		{
			System.out.println(e.toString());
		}
	}
	
	// 이름 검색 출력
	public void sungjukSearchName()
	{
		try
		{
			// 검색할 이름 입력받기
			Scanner sc = new Scanner(System.in);
			System.out.print("검색할 이름 입력 : ");
			String name = sc.next();
			
			//-- 필요한 경우 이 과정에서 프로그래밍적으로 검증(검사) 수행
			
			// 데이터베이스 연결
			dao.connection();
			
			// dao의 lists() 메소드 호출 → 매개변수로 검색할 이름을 문자열 형태로 lists() 에 넘겨주기
			ArrayList<ScoreDTO> arrayList = dao.lists(name);
			
			if (arrayList.size() > 0)
			{
				// 수신된 내용 출력
				System.out.println("번호   이름   국어   영어   수학   총점   평균   석차");
				
				// 전체 데이터 출력 담당 메소드 dao의 lists() 메소드
				for (ScoreDTO dto : arrayList)
				{
					System.out.printf("%3s  %4s  %4d  %5d  %5d  %5d  %5.1f  %d\n"
									, dto.getSid(), dto.getName(), dto.getKor(), dto.getEng(), dto.getMat()
									, dto.getTot(), dto.getAvg(), dto.getRank() );
				}
				
			} else
			{
				// 수신된 내용이 없다는 상황 안내
				System.out.println("검색 결과가 존재하지 않습니다.");

			}
			
			// 데이터베이스 연결 종료
			dao.close();
			
			
		} catch (Exception e)
		{
			System.out.println(e.toString());
		}
	}
	
	// 성적 수정
	public void sungjukUpdate()
	{
		try
		{
			// 수정할 대상의 번호 입력받기
			Scanner sc = new Scanner(System.in);
			System.out.print("수정할 번호를 입력하세요 : ");
			int sid = sc.nextInt();
			
			//-- 입력받은 번호로 체크해야 할 로직 적용 삽입 가능
			
			// 데이터베이스 연결
			dao.connection();
			
			// 수정할 대상 수신 → 데이터 수정을 위한 대상 검색
			ArrayList<ScoreDTO> arrayList = dao.lists(sid);
			
			if (arrayList.size() > 0)
			{
				// 수신된 내용 출력
				System.out.println("번호   이름   국어   영어   수학   총점   평균   석차");
				
				for (ScoreDTO dto : arrayList)
				{
					System.out.printf("%3s  %4s  %4d  %5d  %5d  %5d  %5.1f  %d\n"
									, dto.getSid(), dto.getName()
									, dto.getKor(), dto.getEng(), dto.getMat()
									, dto.getTot(), dto.getAvg(), dto.getRank() );
				}
				
				System.out.println();
				System.out.print("수정 데이터 입력(이름 국어 영어 수학) : ");
				String name = sc.next();
				int kor = sc.nextInt();
				int eng = sc.nextInt();
				int mat = sc.nextInt();
				
				// dao.modify로 수정된 값을 넣어줘야 하는데 dto를 넘겨줘야하는데 아직 dto가 없음
				// sid로 넘겨줘야함. 왜냐면 modify 메소드에서 sid까지 꺼내 쓰고 있기 때문에
				ScoreDTO dto = new ScoreDTO();
				dto.setName(name);
				dto.setKor(kor);
				dto.setEng(eng);
				dto.setMat(mat);
				dto.setSid(String.valueOf(sid)); // int 인수의 문자열 표현을 반환하는 String.valueOf
				
				
				
				// 구서된 dto를 넘겨주며 dao의 modify() 메소드 호출
				int result = dao.modify(dto);
				if (result > 0)
				{
					System.out.println("수정이 완료되었습니다.");
					
				}
			} else
			{
				// 수신된 내용이 존재하지 않는 상황 전달(안내)
				System.out.println("수정 대상이 존재하지 않습니다.");
			}
			
			// 데이터베이스 연결 종료
			dao.close();
			
		} catch (Exception e)
		{
			System.out.println(e.toString());
		}
	}
	
	// 성적 삭제 기능
	public void sungjukDelete()
	{
		try
		{
			Scanner sc = new Scanner(System.in);
			System.out.print("삭제할 번호를 입력하세요 : ");
			int sid = sc.nextInt();
			
			// 데이터베이스 연결
			dao.connection();
			
			// dao의 lists() 메소드 호출 → 삭제할 대상 검색
			ArrayList<ScoreDTO> arrayList = dao.lists(sid);
			
			if (arrayList.size() > 0)
			{
				// 수신된 내용 출력 
				System.out.println("번호   이름   국어   영어   수학   총점   평균   석차");
				
				for (ScoreDTO dto : arrayList)
				{
					System.out.printf("%3s  %4s  %4d  %5d  %5d  %5d  %5.1f  %d\n"
									, dto.getSid(), dto.getName()
									, dto.getKor(), dto.getEng(), dto.getMat()
									, dto.getTot(), dto.getAvg(), dto.getRank() );
				}
				
				System.out.print(">> 정말 삭제하시겠습니까?(Y/N) : ");
				String response = sc.next();
				
				if (response.equals("Y") || response.equals("y"))
				{
					int result = dao.remove(sid);
					if (result > 0)
					{
						System.out.println("삭제가 완료되었습니다.");
					}
				}
				else
				{
					System.out.println("취소되었습니다.");
				}
				
			} else
			{
				// 수신된 내용이 존재하지 않는 상황 전달(안내)
				System.out.println("삭제할 대상이 존재하지 않습니다.");
			}
			
			// 데이터베이스 연결 종료
			dao.close();
			
		} catch (Exception e)
		{
			System.out.println(e.toString());
		}
	}
}

ScoreMain.java

package com.test;

import java.util.Scanner;

public class ScoreMain
{
	public static void main(String[] args)
	{
		Process prc = new Process();
		
		Scanner sc = new Scanner(System.in);
		
		do
		{
			
			
			// 알트 + 쉬프트 + A 누르면 토클모드 진입
			// 마우스로 드래그해서 영역을 잡고 복사한다음 
			// " " 사이를 ㅣ 자로 드래그한다음 붙여넣기하면 그대로 들어간다
			System.out.println();
			System.out.println("====[ 성적 처리 ]====");
			System.out.println("1. 성적 입력");
			System.out.println("2. 성적 전체 출력");
			System.out.println("3. 이름 검색 출력");
			System.out.println("4. 성적 수정");
			System.out.println("5. 성적 삭제");
			System.out.println("=====================");
			System.out.print(">> 선택(1~5, -1:종료) : ");
			String menus = sc.next();
			
			try
			{
				int menu = Integer.parseInt(menus);
						
				if (menu == -1)
				{
					System.out.println();
					System.out.println("프로그램이 종료되었습니다.");
					return;
				}
				
				switch (menu)
				{
					case 1:
						// 성적 입력 기능 수행
						prc.sungjukInsert();
						break;
					case 2:
						// 성적 전체 출력 기능 수행
						prc.sungjukSelectAll();
						break;
					case 3:
						// 이름 검색 출력 기능 수행
						prc.sungjukSearchName();
						break;
					case 4:
						// 성적 수정 기능 수행
						prc.sungjukUpdate();
						break;
					case 5:
						// 성적 삭제 기능 수행
						prc.sungjukDelete();
						break;
				}
				
				
			} catch (Exception e)
			{
				System.out.println(e.toString());
			}
			
		} while (true);
	}
}

좋은 웹페이지 즐겨찾기