Programming Language/Javascript, ...

[JDBC] MVC - Statement

Ma_Sand 2022. 4. 4. 02:35
반응형

MVC 흐름

 ① [Run 클래스] 실행하여 View 클래스 호출

 ② [View 클래스] 사용자가 전달값을 입력(Scanner)한 후 Controller 클래스 호출

 ③ [Controller 클래스] 사용자의 요청을 전달받은 후 데이터를 가공 처리하여 Dao에 전달 및 호출

 ④ [Dao 클래스]

   ⓐ Connection을 생성하여 DB에 접속

   ⓑ SQL 구문 실행

   ⓒ 해당하는 결과 받기

      - SELECT문의 경우: ResultSet으로

      - DML문의 경우: int형 타입으로

   ⓓ DML문일 경우엔 트랜잭션 처리(commit(); / rollback();)

   ⓔ 결과를 Controller 클래스로 리턴

 ⑤ [Controller 클래스] Dao 클래스로부터 반환받은 결과에 따라 View(성공 또는 실패 화면) 결정 및 호출

 ⑥ [View 클래스] 출력(print)

 

 

 

 

VO(Value Object)

   : DB 테이블의 한 행에 대한 데이터를 기록할 수 있는 저장용 객체 클래스이다.

  - 유사 용어: DTO(Data Transfer Object), DO(Domain Object), Entity, bean

  - VO의 조건

   ① 반드시 캡슐화를 적용해야 한다.

   ② 기본 생성자 및 매개변수 생성자를 작성해야 한다.

   ③ 모든 필드에 대해 getter/setter 메소드를 작성해야 한다.

package member.model.vo;

import java.sql.Date;

public class Member {
	//DB 테이블의 컬럼 정보와 유사하게 작성한다.
    private int userNo;//	USERNO NUMBER PRIMARY KEY,
    private String userId;//    USERID VARCHAR2(20) UNIQUE NOT NULL,
    private String userPw;//    USERPW VARCHAR2(20) NOT NULL,
    private String userName;//    USERNAME VARCHAR2(20) NOT NULL,
    private String gender;//    GENDER CHAR(1) CHECK (GENDER IN('M', 'F')),
    private int age;//    AGE NUMBER,
    private String email;//    EMAIL VARCHAR2(30),
    private String phone;//    PHONE CHAR(11),
    private String address;//    ADDRESS VARCHAR2(100),
    private String hobby;//    HOBBY VARCHAR2(50),
    private Date enrollDate;//    ENROLLDATE DATE DEFAULT SYSDATE NOT NULL
    
	public Member() {
		super();
	}
	
	public Member(int userNo, String userId, String userPw, String userName
                , String gender, int age, String email, String phone, String address
                , String hobby, Date enrollDate) {
		super();
		this.userNo = userNo;
		this.userId = userId;
		this.userPw = userPw;
		this.userName = userName;
		this.gender = gender;
		this.age = age;
		this.email = email;
		this.phone = phone;
		this.address = address;
		this.hobby = hobby;
		this.enrollDate = enrollDate;
	}
	
	
	// 회원 추가용 생성자(userNo와 enrollDate 제외한 매개변수 생성자)
	public Member(String userId, String userPw, String userName, String gender
                , int age, String email, String phone, String address, String hobby) {
		super();
		this.userId = userId;
		this.userPw = userPw;
		this.userName = userName;
		this.gender = gender;
		this.age = age;
		this.email = email;
		this.phone = phone;
		this.address = address;
		this.hobby = hobby;
	}

	public int getUserNo() {
		return userNo;
	}
	public void setUserNo(int userNo) {
		this.userNo = userNo;
	}
	public String getUserId() {
		return userId;
	}
	public void setUserId(String userId) {
		this.userId = userId;
	}
	public String getUserPw() {
		return userPw;
	}
	public void setUserPw(String userPw) {
		this.userPw = userPw;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getPhone() {
		return phone;
	}
	public void setPhone(String phone) {
		this.phone = phone;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public String getHobby() {
		return hobby;
	}
	public void setHobby(String hobby) {
		this.hobby = hobby;
	}
	public Date getEnrollDate() {
		return enrollDate;
	}
	public void setEnrollDate(Date enrollDate) {
		this.enrollDate = enrollDate;
	}

	@Override
	public String toString() {
		return "Member [userNo=" + userNo + ", userId=" + userId + ", userPw=" + userPw + "
                      , userName=" + userName, gender=" + gender + ", age=" + age + "
                      , email=" + email + ", phone=" + phone + ", address=" + address + "
                      , hobby=" + hobby + ", enrollDate=" + enrollDate + "]";
	}
}

 

 

 

 

Run

   : 실행하는 클래스

package member.run;

import member.view.View;

public class Run {
	public static void main(String[] args) {
		new View().mainMenu();
	}
}

 

 

 

 

View

   : 사용자가 보는 화면(시각적 요소)을 담당하는 클래스

package member.view;

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

import member.controller.Controller;
import member.model.vo.Member;

public class View {
	// 전역으로 쓸 수 있는 Scanner 객체 생성
	private Scanner sc = new Scanner(System.in);
	
	// 전역으로 MemberController에 요청할 수 있는 객체 생성
	private MemberController mc = new MemberController();

	public void mainMenu() {
		// 프로그램 종료 전까지 메뉴 선택을 반복하기 위해 while문으로 감싸기
		while(true) {
			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.println("0. 프로그램 종료");
			System.out.println("=================================");
			System.out.println("원하는 메뉴 번호를 입력하세요. ");
			int menu = sc.nextInt();
			sc.nextLine();
			
			switch(menu) {
			case 1: insertMember(); break;
			case 2: selectAll(); break;
			case 3: searchById(); break;
			case 4: searchByName(); break;
			case 5: updateMember(); break;
			case 6: deleteMember(); break;
			case 0: System.out.println("프로그램을 종료합니다."); return;  
                    // break;를 쓰면 스위치문에서만 벗어나고 다시 반복됨
			default: System.out.println("메뉴번호를 잘못 입력하였습니다.");
			}
		}
	}
 

	// 추가하고자 하는 회원의 정보를 입력받아 Controller에 추가 요청을 하는 화면

	// 1. 회원 추가 화면
	public void insertMember() {
		System.out.println("----------회원 추가----------");
		// 입력
		// 회원번호(시퀀스)와 enrollDate(default SYSDATE) 두 컬럼에 대해서는 입력받지 않는다.
		System.out.println("아이디: ");
		String userId = sc.nextLine();
        
		System.out.println("비밀번호: ");
		String userPw = sc.nextLine();
        
		System.out.println("이름: ");
		String userName = sc.nextLine();
        
		System.out.println("성별: ");
		String gender = sc.nextLine();
        
		System.out.println("나이: ");
		int age = sc.nextInt();
        
		sc.nextLine();  // 엔터 날리기
        
		System.out.println("이메일: ");
		String email = sc.nextLine();
        
		System.out.println("휴대번호: (- 없이 숫자만 입력)");
		String phone = sc.nextLine();
        
		System.out.println("주소: ");
		String address = sc.nextLine();
        
		System.out.println("취미: ");
		String hobby = sc.nextLine();
		
		// 입력받은 정보를 매개변수로 넘겨서 회원 추가 요청
        // Controller에 있는 메소드를 호출.
		mc.insertMember(userId, userPw, userName, gender, age, email, phone, address, hobby);
	}
	
	// 2. 회원 전체 조회 화면
	public void selectAll() {
		System.out.println("--------회원 전체 조회--------");
		
		// Controller에 회원 전체 조회 요청
		mc.selectAll();
	}

	// 3. 회원 아이디로 검색하는 화면
	public void searchById() {
		System.out.println("-------회원 아이디로 검색-------");
		System.out.println("검색할 회원의 아이디 입력: ");
		String userId = sc.nextLine();
		
		// 입력한 아이디로 Controller에 요청하기
		mc.searchById(userId);
	}
	
	// 4. 회원 이름으로 검색하는 화면
	public void searchByName() {
		System.out.println("--------회원 이름으로 검색--------");
		System.out.println("검색할 회원의 이름 입력: ");
		String userName = sc.nextLine();
		
		mc.searchByName(userName);
		
	}
	
	// 5. 회원 정보를 수정하는 화면
	public void updateMember() {
		System.out.println("---------회원 정보 변경---------");
		
		// 변경할 회원의 아이디
		System.out.println("변경할 회원의 아이디: ");
		String userId = sc.nextLine();
		
		// 해당 회원의 변경할 정보들
		System.out.println("변경할 비밀번호 입력: ");
		String userPw = sc.nextLine();
        
		System.out.println("변경할 이메일 입력: ");
		String email = sc.nextLine();
        
		System.out.println("변경할 휴대번호 입력: ");
		String phone = sc.nextLine();
        
		System.out.println("변경할 주소 입력: ");
		String address = sc.nextLine();
		
		// 회원 정보 수정 요청
		mc.updateMember(userId, userPw, email, phone, address);
	}
	
	// 6. 회원 탈퇴하는 화면
	// 
	public void deleteMember() {
		System.out.println("---------회원 탈퇴---------");
		
		System.out.println("회원 탈퇴할 아이디: ");
		String userId = sc.nextLine();
		
		mc.deleteMember(userId);
	}
	
	//---------------------------------------------------
    
	// 서비스 요청 시 사용자가 보게 될 응답(성공 또는 실패) 화면
	
	// 서비스 요청 성공 시 응답 화면
	public void displaySuccess(String message) {

		System.out.println("서비스 요청 성공: " + message);
	}

	// 서비스 요청 실패시 응답 화면
	public void displayFail(String message) {
		System.out.println("서비스 요청 실패: " + message);
		
	}


	// 전체 조회 결과가 없을 때 응답 화면
	public void displayNoData(String message) {
		System.out.println(message);
	}

	// 전체 조회 결과가 있을 때 응답 화면
	public void displayList(ArrayList<Member> list) {
		System.out.println("조회된 결과는 " + list.size() + "건입니다.");
		
		// 향상된 for문: for(반환할타입 변수명 : 반복할저장소(컬렉션/배열))
		for(Member m : list) {
			System.out.println(m);
		}
	}


	// 조회결과가 하나일 때
	public void displayOne(Member m) {
		System.out.println("조회된 결과는 다음과 같습니다.");
		System.out.println(m);
	}
}

 

 

 

 

Controller

   : 사용자의 요청 처리를 담당하는 클래스

  - View에서의 요청 처리를 담당하며, 해당 메소드로 전달된 데이터들을 VO 객체에 담아 가공 처리한 후

     Dao를 호출한다.

  - Dao에서 반환받은 결과에 따라 사용자가 보게 될 화면을 지정한다.

package member.controller;

import java.util.ArrayList;

import member.model.dao.Dao;
import member.model.vo.Member;
import member.view.View;

public class Controller {

	public void insertMember(String userId, String userPw, String userName, String gender, int age, String email,
			String phone, String address, String hobby) {
		
		// 1. 전달된 데이터들을 Member 객체에 담기(가공 처리)
		Member m = new Member(userId, userPw, userName, gender, age, email, phone, address, hobby);
		
		// 2. Dao의 insertMember 메소드를 호출(가공된 멤버객체를 보낸다.)
		int result = new MemberDao().insertMember(m);
		
		// 3. Dao에서 작업한 결과값에 따라 View에 보여질 화면을 정해준다.
		if(result > 0) {
			// 성공했으니 성공 메시지를 보낸다.
			new MemberView().displaySuccess("회원 추가 성공");
		} else {
			// 실패했으니 실패 메시지를 보낸다.
			new MemberView().displayFail("회원 추가 실패");
		}
		
	}

	// 사용자의 회원 전체 조회 요청을 처리해주는 메소드
	public void selectAll() {
		// view에서 controller로 전체조회 요청 받음 -> Dao에게 DB로부터 전체조회해오라고 요청함
		// -> Dao가 Controller에게 전체조회한 결과값을 전달해줌
		
		// 결과값을 담을 변수
		// SELECT - ResultSet -> ArrayList<Member>
		ArrayList<Member> list = new MemberDao().selectAll();
		// DAO에서 작업을 끝마친 결과를 전달받아 해당 결과를 토대로 어떤 화면을 보여줄 지 정하여 view에 전달한다.
		
		// 조회결과가 있는지 없는지 판단 후 사용자가 보게될 화면을 지정한다.
		if(list.isEmpty()) { // list가 비어있어 true인 경우
			new MemberView().displayNoData("전체 조회 결과가 없습니다.");
		} else {  // list 조회된 경우 list에 Member가 담겨있음
			new MemberView().displayList(list);
		}
	}

	// 사용자가 입력한 아이디로 검색 요청을 처리해주는 메소드
	public void searchById(String userId) {
		Member m = new MemberDao().searchById(userId); // m(조회된 회원 정보)
		
		// 조회된 회원 정보가 담긴 객체 m이 null이면 조회x
		if(m == null) {
			new MemberView().displayNoData(userId+"에 해당하는 회원정보가 없습니다.");
		} else {
			new MemberView().displayOne(m);
		}
	}


	// 사용자가 입력한 이름으로 검색 요청을 처리해주는 메소드
	public void searchByName(String userName) {
		ArrayList<Member> list = new MemberDao().searchByName(userName);
		
		if(list.isEmpty()) {
			new MemberView().displayNoData("조회된 결과가 없습니다.");
		} else {
			new MemberView().displayList(list);
		}
	}

	// 사용자가 입력한 정보들을 변경 요청을 처리해주는 메소드
	public void updateMember(String userId, String userPw, String email, String phone, String address) {
		Member m = new Member();
		
		m.setUserId(userId);
		m.setUserPw(userPw);
		m.setEmail(email);
		m.setPhone(phone);
		m.setAddress(address);
		
		int result = new MemberDao().updateMember(m);
		
		// view 성공 실패 시 보여줄 화면 결정
		if(result > 0) {
			// 성공했으니 성공 메시지를 보낸다.
			new MemberView().displaySuccess("회원 정보 변경 성공");
		} else {
			// 실패했으니 실패 메시지를 보낸다.
			new MemberView().displayFail("회원 정보 변경 실패");
		}
	}

	public void deleteMember(String userId) {
		
		int result = new MemberDao().deleteMember(userId);
		
		if(result > 0) {
			// 성공했으니 성공 메시지를 보낸다.
			new MemberView().displaySuccess("회원 탈퇴 성공");
		} else {
			// 실패했으니 실패 메시지를 보낸다.
			new MemberView().displayFail("회원 탈퇴 실패");
		}
	}
}

 

 

 

 

DAO(Data Access Object)

   : DB와 직접적 접근을 담당하는 클래스

  - Controller에 의해 호출되며, Controller에서 요청받은 작업을 수행한다.

package member.model.dao;

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

import member.model.vo.Member;

public class Dao {
    // 사용자에게 회원 정보를 입력받아 회원을 추가하는 메소드
	public int insertMember(Member m) {
		int result = 0;
		Connection conn = null;
		Statement stmt = null;
		
		String sql = "INSERT INTO MEMBER VALUES (SEQ_USERNO.NEXTVAL, "
				                             +"'"+m.getUserId()+"', "
				                             +"'"+m.getUserPw()+"', "
				                             +"'"+m.getUserName()+"', "
				                             +"'"+m.getGender()+"', "
				                             +    m.getAge()+", "
				                             +"'"+m.getEmail()+"', "
				                             +"'"+m.getPhone()+"', "
				                             +"'"+m.getAddress()+"', "
				                             +"'"+m.getHobby()+"', "
				                             +"SYSDATE)";
		
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "JDBC", "JDBC");
			stmt = conn.createStatement();
			result = stmt.executeUpdate(sql);
			
			if(result > 0) { 
				conn.commit();
			} else {
				conn.rollback();
			}
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				stmt.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return result;  // DML문이 작업된 행 수
	}
	
    
	// 전체조회하는 메소드
	public ArrayList<Member> selectAll(){		
		Connection conn = null;
		Statement stmt = null;
		ResultSet rset = null;
		
		// 회원정보가 여러 개이면 여러 개의 회원정보를 담아야 하므로 ArrayList에 담는다.
		ArrayList<Member> list = new ArrayList<>();  // 빈 리스트 생성
		
		// 실행할 SQL문
		String sql = "SELECT * FROM MEMBER";
		
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "JDBC", "JDBC");
			stmt = conn.createStatement();
			rset = stmt.executeQuery(sql);
			
			while(rset.next()) {
				Member m = new Member();
                
				m.setUserNo(rset.getInt("USERNO"));
				m.setUserId(rset.getString("USERID"));
				m.setUserPw(rset.getString("USERPW"));
				m.setUserName(rset.getString("USERNAME"));
				m.setGender(rset.getString("GENDER"));
				m.setAge(rset.getInt("AGE"));
				m.setEmail(rset.getString("EMAIL"));
				m.setPhone(rset.getString("PHONE"));
				m.setAddress(rset.getString("ADDRESS"));
				m.setHobby(rset.getString("HOBBY"));
				m.setEnrollDate(rset.getDate("ENROLLDATE"));
				// 한 행에 대한 모든 컬럼의 데이터값을 Member 객체 필드에 각각 담았다.
				
				list.add(m);
			}
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				rset.close();
				stmt.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return list;
        // 행의 데이터를 갖고 있는 Member 객체들이 인덱스에 담겨있는 리스트를 반환한다.
	}
	
    
	// 사용자에게 입력받은 아이디로 해당 회원이 있는지 정보 검색 처리하는 메소드
	public Member searchById(String userId) {
		// 필요 도구 생성하기
		Connection conn = null;
		Statement stmt = null;
		ResultSet rset = null;
		Member m = null;  // 조회된 회원의 정보를 담을 Member 객체
		
		String sql = "SELECT * FROM MEMBER WHERE USERID = '" + userId + "'";
		
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "JDBC", "JDBC");
			stmt = conn.createStatement();
			rset = stmt.executeQuery(sql);
			
			// 조회 결과가 담긴 rset을 옮긴다.
			if(rset.next()) {  // 커서가 가르킬 곳에 조회될 결과가 있는 경우
				// 조회된 행에 있는 컬럼들의 데이터를 Member 객체에 한번에 모아 보낸다.
				// 매개변수 생성자로 값 넣기
				m = new Member(rset.getInt("USERNO")
						     , rset.getString("USERID")
						     , rset.getString("USERPW")
						     , rset.getString("USERNAME")
						     , rset.getString("GENDER")
						     , rset.getInt("AGE")
						     , rset.getString("EMAIL")
						     , rset.getString("PHONE")
						     , rset.getString("ADDRESS")
						     , rset.getString("HOBBY")
						     , rset.getDate("ENROLLDATE"));
			}
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				rset.close();
				stmt.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return m;
	}
    
    // 사용자에게 입력 받은 이름으로 회원 조회하는 메소드
	public ArrayList<Member> searchByName(String userName) {
		Connection conn = null;
		Statement stmt = null;
		ResultSet rset = null;
				
		String sql = "SELECT * FROM MEMBER WHERE USERNAME LIKE '%"+ userName + "%'";
		
		ArrayList<Member> list = new ArrayList<>();
		
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "JDBC", "JDBC");
			stmt = conn.createStatement();
			rset = stmt.executeQuery(sql);
			
			while(rset.next()) {
				list.add(new Member(rset.getInt("USERNO")
					              , rset.getString("USERID")
					              , rset.getString("USERPW")
					              , rset.getString("USERNAME")
					              , rset.getString("GENDER")
					              , rset.getInt("AGE")
					              , rset.getString("EMAIL")
					              , rset.getString("PHONE")
					              , rset.getString("ADDRESS")
				          	      , rset.getString("HOBBY")
					              , rset.getDate("ENROLLDATE")));
			}
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				rset.close();
				stmt.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return list;
	}

    // 사용자에게 변경 정보를 입력받아 해당 회원의 정보를 변경하는 메소드
	public int updateMember(Member m) {
		Connection conn = null;
		Statement stmt = null;
		int result = 0;
		
		String sql = "UPDATE MEMBER "
			       + "SET USERPW = '"+m.getUserPw()+"'"
			       + "  , EMAIL = '"+m.getEmail()+"'"
			       + "  , PHONE = '"+m.getPhone()+"'"
			       + "  , ADDRESS = '"+m.getAddress()+"'"
			       + "WHERE USERID = '"+m.getUserId()+"'";
		
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "JDBC", "JDBC");
			stmt = conn.createStatement();
			result = stmt.executeUpdate(sql);
			
			if(result > 0) {
				conn.commit();
			} else {
				conn.rollback();
			}
		} catch (ClassNotFoundException | SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				stmt.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return result;
	}

    // 사용자에게 입력을 받아 회원을 탈퇴시키는 메소드
    public int deleteMember(String userId) {
		Connection conn = null;
		Statement stmt = null;
		int result = 0;
		
		// DELETE FROM MEMBER WHERE USERID='admin';
		String sql ="DELETE FROM MEMBER WHERE USERID='"+userId+"'";
		
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
			conn=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","JDBC","JDBC");
			stmt=conn.createStatement();
			result=stmt.executeUpdate(sql);
			
			if(result>0) {
				conn.commit();
			}else {
				conn.rollback();
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				stmt.close();
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return result;
	}
}
반응형