열심히 끝까지

디바이스 융합 자바(Java) day17 - 학생부 프로그램 with MVC 본문

디바이스 융합 자바(Java)기반 풀스택 개발자 양성과정(수업내용)

디바이스 융합 자바(Java) day17 - 학생부 프로그램 with MVC

노유림 2022. 6. 29. 16:37

학생부를 할 것!
[설계]
학생부 프로그램 만들 것
★실제객체는 멤버변수가 이렇게 적지 않다..

학생 VO(속성)
            학번 PK
            이름
            성적
            ★ 기본생성자를 사용(JSP, Spring 프레임워크 -> "자동매핑")

학생부 ArrayList<학생 VO> DB
// 얼마나 많이 오버로딩될 지 모르기때문에 학생 VO로 통일
★ CRUD(비즈니스 메서드 핵심로직) 메서드 인자값을 VO로 통일시켜서 작업
       -> 오버로딩↓ : VO의 멤버변수가 많을수록 오버로딩할 메서드도 기하급수적으로 많아짐
       -> 유지보수↑ : VO에 멤버변수가 추가되더라도, DAO의 메서드 시그니쳐는 변경되지 않는다.

            boolean insert(이름) // 메서드 오버로딩
            boolean Insert(이름 ,성적) // 메서드 시그니쳐 정의
            >> boolean insert(학생 VO) 로 통일

            학생 VO selectOne(학번) //학생 한 명 정보
            >> 학생 VO selectOne(학생 VO)로 학생 VO 통일

            학생부 selectAll() // 학생 전체 출력
            >> 학생부 selectAll(학생 VO)로 학생 VO 통일

            boolean update(학번)
            boolean update(학번, 성적) // 학번의 성적 입력
            >> boolean update(학생 VO)로 통일

            boolean delete(학번)
            >> boolean delete(학생 VO)로 학생 VO 통일
    >> 결국엔.. 
            >> boolean insert(학생 VO)
            >> 학생 VO selectOne(학생 VO)
            >> 학생부 selectAll(학생 VO)
            >> boolean update(학생 VO)
            >> boolean delete(학생 VO)

[V]
1) 학생추가
2) 학생목록
3) 성적변경
4) 학생삭제
5) 종료

메뉴번호 입력

String 입력 -> String func() // String 입력받을 때
int 입력 -> int func() // int 입력받을 때
ArrayList<학생 VO> 출력 -> void func(ArrayList<학생 VO> datas)
// output은 없지만 

"학생추가 메뉴입니다."
"이름 입력) "
"성적 입력)"

"학생목록 메뉴입니다."

"성적변경 메뉴입니다."
"번호 입력)"

"학생삭제 메뉴입니다."

"프로그램을 종료합니다..."
"수행성공!"
"수행실패..."

"학생 검색 메뉴입니다."



>> 이름 검색하기 기능 추가해보기
      로직이 필요한 순간
      DAO에서 제작해야함
      R : selectAll, selectOne
           >> selectAll 
                output이 두 개 이상이면 무조건 All
                output이 한 개 이거나 없을 수도 있을 때는 One
           >>>> pk로 검색하는 경우가 아니라면 모두 All()

>> 성적을 입력받지 않는 경우 추가해보기

    >> 성적을 추가입력하시겠습니까?(Y/N) 라는 view 필요
          String ans = sc.next();


-----StudentVO----

package model;
public class StudentVO {
	private int num; // PK
	private String name;
	private int score;
	private int phone;
	// 속성값이 증가해도 
	/*
	public StudentVO{
		System.out.println(" 로그 : StudentVO 호출");
	}
	*/
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getScore() {
		return score;
	}
	public void setScore(int score) {
		this.score = score;
	}
	@Override
	public String toString() {
		return "StudentVO [num : " + num + ", name : " + name + ", score : " + score + "]";
	}
}

 

 

----StudentDAO---

package model;
import java.util.ArrayList;
public class StudentDAO {
	ArrayList<StudentVO> datas; // DB
	private int pk; // 시스템(프로그램)에서 부여!
	public StudentDAO() {
		datas = new ArrayList<StudentVO>();
		pk = 1001;
		// 샘플(초기) 데이터 없어도 괜찮다
		StudentVO vo = new StudentVO();
		// 지금은 자동매핑 안된다, 하지만 나중에 가능!
		vo.setName("홍길동");
		vo.setNum(pk++);
		vo.setScore(50);
		datas.add(vo);
	}
	public boolean insert(StudentVO vo) {
		// 학생객체(vo)를 학생부(AL)에 add()
		try {
		vo.setNum(pk++);
		datas.add(vo);
		return true;
		}
		catch(Exception e) {
			e.printStackTrace();
			System.out.println("    로그 : insert()에서 확인되지 않는 예외 발생!");
			return false;
		}
	}
	public boolean update(StudentVO vo) {
		// vo에 들어온 num값이 datas에 존재하는지 확인하는 작업
		// model에서도 하고 controller에서도한다!
		for(StudentVO data : datas) {
			if(data.getNum()==vo.getNum()) {
				data.setScore(vo.getScore());
				return true;
			}
		}
		return false;
	}
	public boolean delete(StudentVO vo) {
		// vo에 들어온 num값이 datas에 존재하는지 확인하는 작업
		for(int i = 0; i < datas.size(); i++) {
			if(datas.get(i).getNum()==vo.getNum()) {
				datas.remove(i);
				return true;
			}
		}
		// Controller에서 유효한 vo인지 확인하는 작업을 해준다면?
		datas.remove(pk);
		return false;
	}
	public StudentVO selectOne(StudentVO vo) {
		for(StudentVO data : datas) {
			if(data.getNum()==vo.getNum()) {
				return data;
			}
		}
		return null;
		// num을 받아서 num와 동일한 값을 가진 vo를 반환 equals 같은 개념
		/*
		for(int i = 0; i < datas.size(); i++) {
			if(datas.get(i).getNum()==vo.getNum()) {
				return datas.get(i);
			}
		}
		return null;
		*/
	}
	public ArrayList<StudentVO> selectAll(StudentVO vo) {
		if(vo.getName()!=null) {
			// 검색 [서비스] 제공
			ArrayList<StudentVO> datas = new ArrayList<StudentVO>(); // 방금 받은 인자값
			// datas와 아래 datas는 다른 값
			for(int i = 0; i < this.datas.size(); i++) {
				if(this.datas.get(i).getName().equals(vo.getName())) {
					// 존재하는 값이랑 검색한 값이랑 같으면?
					datas.add(this.datas.get(i)); // 출력
				}
			}
			return datas;
		}
		// 원래는 반환시키기 위해 배열 만들어서 datas에 데이터를 채워넣는 로직을 하고 나서
		return datas;
	}
}

 

---StudentView--------

package view;
import java.util.ArrayList;
import java.util.Scanner;
import model.StudentVO;
public class StudentView {
	public int action;
	Scanner sc = new Scanner(System.in);
	public void startview() {
		while(true) {
			System.out.println();
			System.out.println("===학생부 프로그램===");
			System.out.println("1. 학생추가");
			System.out.println("2. 학생목록");
			System.out.println("3. 성적변경");
			System.out.println("4. 학생삭제");
			System.out.println("5. 종료");
			System.out.println("6. 학생검색");
			System.out.print("메뉴입력) ");
			try {
				action  = sc.nextInt();
				if(1<=action&&action<=5) {
					break;
				}
				System.out.println("범위외 입력!");
			}
			catch(Exception e) { // 예외처리 최상위값
				sc.nextLine(); // 이상한 값 치우기
				System.out.println("정수만 입력하세요!");
				// continue; 쓰거나 if문을 try안에 넣거나
				// try안에 넣어서 사용하겠다!
			}
		}
	}
	public String inputString() { // 문자열 입력
		System.out.println("문자열 입력) ");
		String str = sc.next();
		return str;
	}
	public int inputInt() { // 정수 입력
		System.out.println("정수 입력) ");
		int i = sc.nextInt();
		return i;
	}
	public void printDatas(ArrayList<StudentVO> datas) {
		System.out.println();
		if(datas.size()==0) {
			System.out.println("저장된 정보가 없습니다!");
			return;
		}
		System.out.println("=== 학생목록 ===");
		for(StudentVO vo:datas) { // 불러올 클래스 : 쓸 배열
			System.out.println(vo.getNum() + "번 " + vo.getName() + "학생 " + vo.getScore() + "점");
		}
		System.out.println("==============");
	}
	public void funcAdd() {
		System.out.println("학생 추가 메뉴입니다.");
	}
	public void funcList() {
		System.out.println("학생 목록 메뉴입니다.");
	}
	public void funcScoreUpdate() {
		System.out.println("성적 변경 메뉴입니다.");
	}
	public void funcDelete() {
		System.out.println("학생 삭제 메뉴입니다.");
	}
	public void funcNameIn() {
		System.out.println("이름을 입력하세요.. ");
	}
	public void funcScoreIn() {
		System.out.println("성적을 입력하세요.. ");
	}
	public void funcNumIn() {
		System.out.println("번호를 입력하세요.. ");
	}
	public void funcClose() {
		System.out.println("프로그램을 종료합니다...");
	}
	public void funcSuccess() {
		System.out.println("수행 성공!");
	}
	public void funcFail() {
		System.out.println("수행 실패...");
	}	
	public String funcPlusIn() {
		String ans;
		while(true) { // yes면 1, no면 2로 해도 괜찮다
			System.out.println("성적을 추가입력하시겠습니까? (Y/N)");
			ans = sc.next();
			ans = ans.toUpperCase(); // 무조건 대문자로 만들어주는 것
			// ans.toLowerCase();는 소문자일거로 추정
			if(ans.equals("YES") || ans.equals("NO")) {
				break;
			}
			System.out.println("YES or NO 만 입력가능합니다!");
		}
		return ans;
	}
	public void FuncSearch() {
		System.out.println("학생 검색 메뉴입니다.");
	}
}

 

---StudentController--------

package controller;
import java.util.ArrayList;
import model.StudentDAO;
import model.StudentVO;
import view.StudentView;
public class StudentController {
	StudentDAO model;
	StudentView view;
	public StudentController() {
		model = new StudentDAO();
		view = new StudentView();
	}
	public void startApp() {
		while(true) {
			view.startview();
			if(view.action==1) { //★★★
				view.funcAdd(); // 학생추가메뉴 출력
				view.funcNameIn(); // 이름 입력) 
				String name = view.inputString(); // 문자열입력값
				String ans = view.funcPlusIn(); // 성적 추가할 것인지 질문
				int score = 0; // 초기값
				if(ans.equals("YES")) { // 
					view.funcScoreIn(); // 성적 입력)
					score = view.inputInt(); // 정수형입력값
				}
				StudentVO vo = new StudentVO();
				vo.setName(name);
				//				vo.setName(view.inputString()); 로 써도 괜찮
				// >> String name과 vo.setName(name)을 합친 것
				vo.setScore(score);
				boolean flag = model.insert(vo);
				if(flag) { // 저장이 되면
					view.funcSuccess(); // 수행 성공
				}
				else {
					view.funcFail(); // 수행 실패
				}
			}
			else if(view.action==2) { // ★★★★★
				// 학생 목록 출력
				view.funcList(); // 학생 목록
				StudentVO vo = new StudentVO(); // 가져와 라고하니 가져온다!
				ArrayList<StudentVO> datas = model.selectAll(vo); // model에게서 받아낸다
				view.printDatas(datas); // 띄어주면 된다
			}
			else if(view.action==3) { // 성적변경
				view.funcScoreUpdate();
				view.funcNumIn();
				int num = view.inputInt();
				view.funcScoreIn();
				int score = view.inputInt();
				StudentVO vo = new StudentVO();
				vo.setNum(num);
				vo.setScore(score);
				boolean flag = model.update(vo);
				if(flag) {
					view.funcSuccess();
				}
				else {
					view.funcFail();
				}
			}
			else if(view.action==4) {
				view.funcDelete();
				view.funcNumIn();
				int num = view.inputInt();
				// selectOne을 사용하여 사용자가 입력한 num에 대한 데이터가 존재합니까?
				// selectOne()
				StudentVO vo = new StudentVO();
				vo.setNum(num);
				vo = model.selectOne(vo);
				if(vo==null) { // 둘 다 수행하는 것이 좋다!
					System.out.println("    로그 : " + num+ "번의 학생은 존재하지 않습니다.");
					view.funcFail(); // 수행실패 인지
					continue;
				}
				boolean flag = model.delete(vo);
				if(flag) {
					view.funcSuccess();
				}
				else {
					view.funcFail();
				}
			}
			else if(view.action==5) {
				view.funcClose();
				break;
			}
			else if(view.action==6) {
				view.FuncSearch();
				view.funcNameIn();
				String name = view.inputString();
				// 로직이 필요한 순간
				// DAO에서 제작해야함
				// R : selectAll, selectOne
				//  >> selectAll 
				// output이 두 개 이상이면 무조건 All
				// output이 한 개 이거나 없을 수도 있을 때는 One
				// >>>> pk로 검색하는 경우가 아니라면 모두 All()
				StudentVO vo = new StudentVO();
				vo.setName(name);
				// View에서 사용자가 입력한 이름정보를
				// Model DAO의 핵심로직(비즈니스 메서드) 인자로 전달하는 코드
				ArrayList<StudentVO> datas = model.selectAll(vo);
				view.printDatas(datas);
			}
		}
	}
}

 

---Client----------

package client;
import controller.StudentController;
public class Client {
	public static void main(String[] args) {
		StudentController app = new StudentController();
		app.startApp();
	}
}