미니프로젝트

[초미니프로젝트] 3일차

Dodledd 2024. 3. 4. 17:41

저번에는 오라클 테이블과 사용자가 구매하는 것까지 구현해 보았다.

그럼 장바구니와 구매내역 삭제는 DB에 중계테이블을 이용해야하니 일단 관리자가 진행하는 CRUD를 먼저 해보겠다.

 

 

시작은 항상  mainMenu이다.

여기서 2번을 선택하면 보이는 화면을 보도록하자

	public void mainMenu() {
		while(true) {
			System.out.println("환영합니다, 컴퓨터가게 입니다.");
			System.out.println("1. 손님");
			System.out.println("2. 관리자");
			System.out.println("9. 종료");
			int menu = sc.nextInt();
			sc.nextLine();
			switch(menu) {
			case 1:
				this.customerMenu();
				break;
			case 2:
				this.masterMenu();
				break;
			case 9:
				System.out.println("시스템 종료");
				return;
			default:
				System.out.println("잘못 입력하셨습니다. 다시 입력해주세요");
				break;
			}//end switch		
		}//end while	
	}//end mainMenu

 

 

public void masterMenu() {
		while(true) {
			System.out.println("관리자 메뉴입니다.");
			System.out.println("1. 컴퓨터 부품 추가");
			System.out.println("2. 등록된 컴퓨터 부품 수정");
			System.out.println("3. 등록된 부품 삭제");
			System.out.println("4. 부품 조회");
			System.out.println("9. 종료");
			int menu = sc.nextInt();
			sc.nextLine();
			switch(menu) {
			case 1:
				this.insertParts();				
				break;
			case 2:
				this.updateParts();			
				break;
			case 3:
				this.deleteParts();				
				break;
			case 4:
				this.selectParts();
				break;
			case 9:
				System.out.println("이전 메뉴로");
				return;
			default:
				System.out.println("잘못 입력하셨습니다. 다시 입력해주세요");
				break;
			}//end switch		
		}//end while
	}

 

관리자메뉴 실행

메뉴야 뭐 그냥 넘어가겠다

 

먼저 insertParts 즉 1. 컴퓨터 부품 추가를 진행하면

이렇게 어떤 것을 추가할 것인지 분기를 만들어놓았다.

여기서 1번을 선택하면 문자열 CPU를 가지고 cpuInputData 메서드가 호출된다.

다시 공통적으로 data를 입력받는 곳으로 CPU 문자열을 들고간다.

 

밑에 코드는 CPU와 VGA가 합쳐저서 입력받게 하나의 메소드로 만들어놓았다.

//데이터 입력해주는 메소드
	public void InputData(String name) {
		System.out.println("***** " + name + "추가입니다 *****");
		
		System.out.print(name + " 이름 : ");
		String Name = sc.nextLine();
		
		System.out.print(name + " 가격 : ");
		int Price = sc.nextInt();
				sc.nextLine();
		
		System.out.print(name + " 출시일(yyyy-MM-dd) : ");
		Date Date = this.dateConversion(sc.nextLine());
		
		
		System.out.print(name + " 재고 : ");
		int Stock = sc.nextInt();
				sc.nextLine();
					   
		switch(name) {
		case "CPU":
			System.out.print(name + " 벤치점수 : ");
			int cpuCinebench = sc.nextInt();
							   sc.nextLine();
		
			System.out.print(name + " 사용 전력 : ");
			String cpuPowerusage = sc.nextLine();
			
			System.out.print(name + " 베이스 클럭 : ");
			String cpuBaseclock = sc.nextLine();
			
			System.out.print(name + " 부스트 클럭 : ");
			String cpuBoostclock = sc.nextLine();

			System.out.print(name + " 제조사(AMD/Intel) : ");
			String cpuMfrName = sc.nextLine().toUpperCase();
			
			System.out.print(name + " 소켓 : ");
			String cpuSocket = sc.nextLine();
			
			
			c.insertCPU(Name, cpuCinebench, cpuBaseclock, cpuBoostclock, 
					cpuPowerusage, Price, cpuMfrName, cpuSocket, Stock, Date);
			break;
			
		case "VGA":
			System.out.print(name + " 베이스 클럭 : ");
			String vgaBaseclock = sc.nextLine();
			
			System.out.print(name + " 부스트 클럭 : ");
			String vgaBoostclock = sc.nextLine();
			
			System.out.print(name + " 사용 전력 : ");
			String vgaPowerusage = sc.nextLine();
			
			System.out.print(name + " 제조사(NVIDIA/AMD) : ");
			String vgaMfrName = sc.nextLine().toUpperCase();
				   
			System.out.println(name + " 제로 팬 여부(TRUE/FALSE) : ");
			String vgaZerofan = sc.nextLine().toUpperCase();
			
			c.insertVGA(Name, vgaBaseclock, vgaBoostclock, vgaPowerusage, 
					 Price, vgaMfrName, Stock, vgaZerofan, Date);
			break;
		}

	}//end InputData

switch문이 실행되기 전까지는 CPU와 VGA 객체의 공통적인 부분을 같이 입력받고 그 이후로 다른 점을 입력받게 갈라놓았다. 이것도 처음에는 둘 다 전부 따로 구현했지만 리팩토링의 과정을 거쳐 줄여보게 되었다.

 

그리고 이렇게 입력받은 값을 들고 사용자의 요청을 처리하는 클래스인 Controller의 c.insertCpu 메서드로 이동한다.

	public void insertCPU(String cpuName, int cpuCinebench, String cpuBaseclock, String cpuBoostclock,
			String cpuPowerusage, int cpuPrice, String cpuMfrName, String cpuSocket, int cpuStock, Date sqlDate) {
		
		CPU myCpu = new CPU(cpuName, cpuCinebench, cpuBaseclock, cpuBoostclock,
				cpuPowerusage,cpuPrice, cpuMfrName, cpuSocket, cpuStock, sqlDate);
		
		int result = new Dao().insertCpu(myCpu);
		
		if(result > 0 ) {
			System.out.println("정상적으로 추가되었습니다.");
		}else {
			System.out.println("추가 실패하였습니다.");
		}
		
	}

insertCPU이다. 우리가 입력받은 값을 들고 매개변수에 그대로 들고와 CPU클래스의 생성자로 myCpu객체로 만들어준다.

 

그럼 우린 만들어진 객체를 들고 DB와 직접 통신하는 Dao클래스의 insertCpu(myCpu) 메소드를 호출하게 되는데 우리는 반환값을 result에 담아서 0줄보다 많다면, 즉 DB에 쿼리가 성공적으로 실행됐다면 1줄 이상의 메세지가 반환 되는 것을 이용하여 정상적으로 추가됐다는 것을 출력해준다.

 

Dao() 클래스의 생성자로 Properties를 사용해준다.

private Properties prop = new Properties();

public Dao() {
		try {
			prop.loadFromXML(new FileInputStream("resources/query.xml"));
			prop.load(new FileInputStream("resources/driver.properties"));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

저번 포스팅때 다뤘던 Properties의 응용을 하여 리팩토링을 했었다.

위처럼 Dao 어디서든 사용할 수 있게 전역변수로 생성해주고 loadFromXML과 FileInputStream을 사용하여 컴퓨터가 경로를 알게 해준다.)

 

그리고 Dao 클래스의 insertCpu메소드

public int insertCpu(CPU cpu) {
		
		int result = 0;
		Connection conn = null;
		PreparedStatement pstmt = null;
		
		String sql = prop.getProperty("insertCpu");
		
		try {
			Class.forName(prop.getProperty("driver"));
			
			conn = DriverManager.getConnection(prop.getProperty("url"), prop.getProperty("username"), prop.getProperty("password"));
			
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, cpu.getCpuName());
			pstmt.setInt(2, cpu.getCpuCinebench());
			pstmt.setString(3, cpu.getCpuBaseclock());
			pstmt.setString(4, cpu.getCpuBoostclook());
			pstmt.setString(5, cpu.getCpuPowerusage());
			pstmt.setInt(6, cpu.getCpuPrice());
			pstmt.setString(7, cpu.getCpuMfrName());
			pstmt.setString(8, cpu.getCpuSocket());
			pstmt.setInt(9, cpu.getCpuStock());
			pstmt.setDate(10, cpu.getCpuRelease());
			
			result = pstmt.executeUpdate();
			
			if (result > 0) {
				conn.commit();
			} else {
				conn.rollback();
			}

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				pstmt.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		
		return result;
	}

내가 JDBC를 공부할 때의 형식과 거의 똑같다고 보면 된다.

연결하기 위한 Connection과 쿼리를 전달하고 그 반환 값을 받기위한 PrepareStatement를 만들어주고 위에서 Properties를 통해 지정한 경로에 있는 파일에서 String 으로 저장된 key값으로 String형 value값 = 즉 DB접속정보와

쿼리의 key값 예를들면 insertCpu에 저장된 문자열을 불러들여서 보안과 코드의 효율을 높힌다.

 

말로만 하면 헷갈리니 직접 xml파일을 보면

xml 파일 중 insertCpu부분

이렇게 구현이 되어있다.

key값으로 insertCpu를 입력하면 그 밑에 있는 INSERT INTO CPUCCC ...   이 자동으로 괄호안에 들어가는 것이다.