jdbc

[jdbc] 6. 학생관리 프로그램

jeri 2024. 5. 14. 21:05
반응형

[STEP1] 프로그램기획 및 설계하기

1) 프로그램 기획하기

  • 어떤 프로그램을 만들지 생각
  • 그 프로그램에서 어떤 기능들을 구현할지 생각
  • ex) 쇼핑몰
    • 어떤 기능들 구현할 것인가?
    • 어떤 기능등을 사용자에게 제공할 것인가?

2) 기획에 맞는 설계하기 - 문서화

  • 화면 설계(화면구성)
    • 대략적으로 방향성 제시하기
    • 구체적으로는 디자이너가 해줄 것! ( 화면 디자이너)

3) 설계를 바탕으로

  1. 데이타베이스(테이블) 만들기
  2. DTO 만들기
  3. DAO 만들기 : 설계에 맞는 메소드 만들기
  4. 프로그램 만들기

 

 

[STEP2] 테이블 및 DTO클래스 만들기

1) DTO 클래스 만드는 법

  • VO클래스 > DTO클래스 ( VO클래스 내 DTO클래스의 개념이 있는 것!! )

2) VO (Value Object) 클래스

  • 값을 저장하기 위한 객체를 만들어주는 클래스
  • ( 값 저장만을 목적 )

3) DTO(Data Transfer Object)클래스

  • 데이타를 전송하는 객체를 만들어주는 클래스
  • DAO클래스의 메소드에 필요한 값들을 매개변수로 전달하거나, 메소드의 실행결과들을 저장하여 반환받기 위한 클래스
  • ( 매개변수로 전달하기 위한 값 or 저장해서 반환받기 위한 값 )

DTO 클래스의 필수요소

  1. 테이블의 컬럼과 1:1로 매칭되는 필드 선언
    • 필드명은 컬럼명과 동일하게 작성하는 것을 권장
    • 나중에 framework에서 필드명컬럼명이 같으면 검색결과 시 자동 매핑되기 때문
  2. Getter & Setter메소드

4) STUDENT테이블 만들기

STUDENT테이블
DESC STUDENT;

이름       널?       유형
-------- -------- -------------
NO       NOT NULL NUMBER(4)
NAME              VARCHAR2(50)
PHONE             VARCHAR2(20)
ADDRESS           VARCHAR2(100)
BIRTHDAY          DATE

5) StudentDTO 만들기

StudentDTO.java
package xyz.itwill.student;

//STUDENT테이블의 행정보(학생정보)를 저장하여 전달하기 위한 클래스
public class StudentDTO {
	//필드
	private int no;
	private String name;
	private String phone;
	private String address;
	private String birthday;
	//기본생성자 : [Ctrl]+[Space] >> Constructor 선택
	public StudentDTO() {	}
	//매개변수가 선언된 생성자 : [Alt]+[Shift]+[S] >> [O] >> 필드선택 >> Generate
	public StudentDTO(int no, String name, String phone, String address, String birthday) {
		super();
		this.no = no;
		this.name = name;
		this.phone = phone;
		this.address = address;
		this.birthday = birthday;
	}
	//Getter & Setter : [Alt]+[Shift]+[S] >> [R] >> 필드선택 >> Generate
	public int getNo() {return no;}
	public void setNo(int no) {this.no = no;}
	public String getName() {return name;}
	public void setName(String name) {this.name = name;}
	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 getBirthday() {return birthday;}
	public void setBirthday(String birthday) {this.birthday = birthday;}
}

[STEP3] DAO 클래스 만들기

1) DAO 클래스 만들기 (DAO 다자인패턴)

  • 프로그램1, 프로그램2, 프로그램3공통적인 데이타 처리의 기능이 있다면
    DAO 클래스 (데이타 - 저장매체)에 접근하는 객체를 만들어주는 클래스 를 만들어 사용함
  • (DAO의 부모) 인터페이스 + DAO 클래스

 

2) (부모) JdbcDAO클래스

  • (부모) DAO클래스가 상속받는 클래스
JdbcDAO.java
package xyz.itwill.student;

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

import oracle.ucp.jdbc.PoolDataSource;
import oracle.ucp.jdbc.PoolDataSourceFactory;

//모든 DAO 클래스에서 공통적으로 사용하는 JDBC 기능을 메소드로 제공하는 클래스
// => 모든 DAO 클래스가 상속받아 사용하는 부모클래스

//공통적으로 사용하는 JDBC 기능
//1. DBCP 관련 객체를 생성하여 Connection객체를 반환하는 메소드
//2. JDBC 관련 객체를 전달받아 제거하는 메소드

// => 객체 생성이 목적이 아닌 상속만을 목적으로 작성된 클래스이므로 추상클래스로 선언하는 것을 권장 
public abstract class JdbcDAO {
	//PoolDataSource 객체(DBCP)를 저장하기 위한 필드
	private static PoolDataSource pds;
	
	//PoolDataSource 객체를 생성하여 필드에 저장 - 프로그램에서 한번만 실행
	// => PoolDataSource 객체에 Connection 객체를 미리 생성하여 저장
	static {
		pds=PoolDataSourceFactory.getPoolDataSource();
		try {
			pds.setConnectionFactoryClassName("oracle.jdbc.driver.OracleDriver");
			pds.setURL("jdbc:oracle:thin:@localhost:1521:xe");
			pds.setUser("scott");
			pds.setPassword("tiger");
			pds.setInitialPoolSize(10);
			pds.setMaxPoolSize(15);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	//1.
	//PoolDataSource 객체(DBCP)에 저장된 Connection 객체 중 하나를 얻어와 반환하는 메소드
	public Connection getConnection() {
		Connection con=null;
		try {
			con=pds.getConnection();	
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return con;
	}
	
	//2.
	//JDBC 관련 객체를 매개변수로 전달받아 제거하는 메소드
	public void close(Connection con) {
		try {
			//Connection 객체 제거 - PoolDataSource 객체(DBCP)에게 사용한 Connection 객체 반환
			if(con!=null) con.close();	
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public void close(Connection con, PreparedStatement pstmt) {
		try {
			if(pstmt!=null) pstmt.close();	
			if(con!=null) con.close();	
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	public void close(Connection con, PreparedStatement pstmt, ResultSet rs) {
		try {
			if(rs!=null) rs.close();	
			if(pstmt!=null) pstmt.close();	
			if(con!=null) con.close();	
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

3) (부모) StudentDAO인터페이스

  • (부모) DAO 클래스가 상속받는 인터페이스
StudentDAO.java
package xyz.itwill.student;

import java.util.List;

//DAO 클래스가 반드시 상속받기 위한 인터페이스
// => 추상메소드를 이용하여 모든 DAO 클래스가 동일한 형태로 선언되도록 작성 규칙 제공
// => 왜? 
// => 저장매체(DBMS)가 변경되어도 동일한 형태로 작성할 수 있으므로 나중에 DAO 클래스가 바뀌더라도 클래스의 영향을 최소화 할 수 있음
public interface StudentDAO { 

	/*
    조작행의 갯수를 반환해주면 됨!
    단일행,단일컬럼을 반환한다면 : int , String
    */

	//"학생정보"를 전달받아 STUDENT 테이블에 삽입하고 삽입행의 갯수를 반환하는 메소드
    //=> addStudent()메소드 호출할 때 사용할 메소드
	//int insertStudent(int no, String name, String phone, String address, String birthday);
	int insertStudnet(StudentDTO student);

	//"학생정보"를 전달받아 STUDENT 테이블에 저장된 학생정보를 변경하고 변경행의 갯수를 반환하는 메소드
    //=> modifyStudent()메소드 호출할 때 사용할 메소드
	int updateStudent(StudentDTO student);

	//"학번"을 전달받아 STUDENT 테이블에 저장된 학생정보를 삭제하고 삭제행의 갯수를 반환하는 메소드
    //=> removeStudent()메소드 호출할 때 사용할 메소드
	int deleteStudent(int no);

	/*
    단중행, 단일컬럼-다중컬럼을 반환한다면 : 무조건 List객체
    */

	//"학번"을 전달받아 STUDENT 테이블에 저장된 "해당 학번의 학생정보"를 검색하여 반환하는 메소드
    // (유일한 하나의 행만 검색해서(단일행, 다중컬럼) 반환하는 메소드)
    //=> searchNameStudent()메소드 호출할 때 사용할 메소드
	StudentDTO selectNoStudent(int no);

	//"이름"을 전달받아 STUDENT 테이블에 저장된 "해당 이름의 학생목록"를 검색하여 반환하는 메소드
    // (다중행을 검색해서(다중행) 반환하는 메소드) : 무조건 List객체로 반환
	//=> searchNameStudent()메소드 호출할 때 사용할 메소드
	List<StudentDTO> selectNameStudentList(String name);

	//STUDENT 테이블에 저장된 "모든 학생정보"를 검색하여 반환하는 메소드
    // (다중행을 검색해서(다중행) 반환하는 메소드) : 무조건 List객체로 반환
    //=> displayAllStudent()메소드 호출할 때 사용할 메소드
	List<StudentDTO> selectAllStudentList();
}

4) (자식) StudentDAOImpl클래스

StudentDAOImpl.java
package xyz.itwill.student;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

//🍎DAO(Data Access Object) 클래스
// => 저장매체에 행단위 정보(Record)를 삽입,변경,삭제,검색하는 기능을 제공하기 위한 클래스
// => 저장매체 : 정보를 행단위로 저장하여 관리하기 위한 하드웨어 또는 소프트웨어 - ex. DBMS -> 한번 저장해두면 다른 프로그램에서도 사용 가능(StudentManagerApp, StudentGUIApp)
// => 우리가 사용하는 저장매체 : 오라클 DBMS

//🍎DAO 클래스의 필수요소
//1. 인터페이스를 상속 받아 작성하는 것을 권장 
// => 메소드의 작성 규칙 제공 : 유지보수의 효율성 증가
// => 만약 저장매체가 오라클 DBMS에서 mySql DBMS로 바뀐다면?? 새롭게 작성해야함!
// => 하지만 같은 인터페이스를 상속받고 있다면?? 동일한 메소드의 작성규칙을 제공하기 때문에 유지보수의 효율성이 증가됨!!
//2. 싱글톤 디자인 패턴을 적용하여 작성하는 것을 권장 
// =>프로그램에 하나의 객체만 제공하는 클래스 - 특히 DAO 클래스는 딱 하나만 있으면 됨. 여러개 있을 필요가 없음

//🍎 DAO클래스의 메소드 만들 때 주의점
//하나의 메소드는 매개변수로 객체(값)을 제공받아 하나의 SQL 명령을 전달하여 실행하고,
//실행결과를 Java 객체(값)로 반환
// => 즉, 하나의 SQL 명령만을 전달
// => 하나의 SQL 명령을 전달하여 실행하기위해서는? : Connection객체필요 - ConnectionPool이용
// => 만약 여러개의 SQL 명령을 전달하여 실행하고 싶다면? Service 클래스 만들기
// => DAO에서는 무조건 하나의 명령만 가능!
// => 즉, DAO클래스의 메소드 내에서는 입출력하지 않고, 오로지 데이타처리하여 값(객체)만을 반환함

//STUDENT 테이블에 행(학생정보)을 삽입,변경,삭제,검색하기 위한 메소드를 제공하는 클래스
// => 하나의 메소드는 매개변수로 객체(값)을 제공받아 하나의 SQL 명령을 전달하여 실행하고 
//실행결과를 Java 객체(값) 반환
public class StudentDAOImpl extends JdbcDAO implements StudentDAO {

	//🍎 싱글톤 디자인 패턴으로 작성
	//필드선언
	private static StudentDAOImpl _dao;	
	//기본생성자선언 : 외부에서 생성자로 객체 생성을 방지하기 위해 은닉화 선언
	private StudentDAOImpl() {
		// TODO Auto-generated constructor stub
	}
	//정적영역	
	static {
		_dao=new StudentDAOImpl();
	}	
	//StudentDAOImpl 객체를 반환하는 메소드
	public static StudentDAOImpl getDAO() {
		return _dao; //이 메소드를 호출하면 정적영역에서 만들어진 똑같은 딱 하나의 객체만을 반환함
	}
	

	//🍎 insertStudent(StudentDTO student) - int 삽입행의갯수
	//학생정보를 전달받아 STUDENT 테이블에 삽입하고 삽입행의 갯수를 반환하는 메소드
	@Override
	public int insertStudent(StudentDTO student) {
		Connection con=null;
		PreparedStatement pstmt=null;
		int rows=0;//처리결과를 저장하기 위한 변수
		try {
			con=getConnection();//JdbcDAO 클래스(부모클래스)의 getConnection() 메소드 호출
			
			String sql="insert into student values(?,?,?,?,?)";
			pstmt=con.prepareStatement(sql);
			pstmt.setInt(1, student.getNo());
			pstmt.setString(2, student.getName());
			pstmt.setString(3, student.getPhone());
			pstmt.setString(4, student.getAddress());
			pstmt.setString(5, student.getBirthday());
			
			rows=pstmt.executeUpdate();
		} catch (SQLException e) {
			System.out.println("[에러]insertStudent() 메소드의 SQL 오류 = "+e.getMessage());
		} finally {
			close(con, pstmt);
		}
		return rows;
	}

	//🍎 updateStudent(StudentDTO student) - int 변경행의갯수
	//학생정보를 전달받아 STUDENT 테이블에 저장된 학생정보를 변경하고 변경행의 갯수를 반환하는 메소드
	@Override
	public int updateStudent(StudentDTO student) {
		Connection con=null;
		PreparedStatement pstmt=null;
		int rows=0;
		try {
			con=getConnection();
			
			String sql="update student set name=?,phone=?,address=?,birthday=? where no=?";
			pstmt=con.prepareStatement(sql);
			pstmt.setString(1, student.getName());
			pstmt.setString(2, student.getPhone());
			pstmt.setString(3, student.getAddress());
			pstmt.setString(4, student.getBirthday());
			pstmt.setInt(5, student.getNo());
			
			rows=pstmt.executeUpdate();
		} catch (SQLException e) {
			System.out.println("[에러]updateStudent() 메소드의 SQL 오류 = "+e.getMessage());
		} finally {
			close(con, pstmt);
		}
		return rows;
	}

	//🍎 deleteStudent(int no) - int 삭제행의갯수
	//학번을 전달받아 STUDENT 테이블에 저장된 학생정보를 삭제하고 삭제행의 갯수를 반환하는 메소드
	@Override
	public int deleteStudent(int no) {
		Connection con=null;
		PreparedStatement pstmt=null;
		int rows=0;
		try {
			con=getConnection();
			
			String sql="delete from student where no=?";
			pstmt=con.prepareStatement(sql);
			pstmt.setInt(1, no);
			
			rows=pstmt.executeUpdate();
		} catch (SQLException e) {
			System.out.println("[에러]deleteStudent() 메소드의 SQL 오류 = "+e.getMessage());
		} finally {
			close(con, pstmt);
		}
		return rows;
	}

	//🍎 selectNoStudent(int no) - StudentDTO
	//학번을 전달받아 STUDENT 테이블에 저장된 해당 학번의 학생정보를 검색하여 반환하는 메소드
	// => 단일행을 검색한 경우 검색결과를 값 또는 DTO 객체로 변환하여 반환
	@Override
	public StudentDTO selectNoStudent(int no) {
		Connection con=null;
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		StudentDTO student=null;
		try {
			con=getConnection();
			
			String sql="select * from student where no=?";
			pstmt=con.prepareStatement(sql);
			pstmt.setInt(1, no);
			
			rs=pstmt.executeQuery();
			
			if(rs.next()) {//검색행이 있는 경우
				//검색행의 컬럼값을 DTO 객체의 필드값으로 변환하여 저장 - 매핑처리
				student=new StudentDTO();//StudentDTO 객체를 생성하여 저장
				student.setNo(rs.getInt("no"));//검색행의 컬럼값을 반환받아 DTO 객체의 필드값 변경
				student.setName(rs.getString("name"));
				student.setPhone(rs.getString("phone"));
				student.setAddress(rs.getString("address"));
				student.setBirthday(rs.getString("birthday").substring(0, 10));
			}
		} catch (SQLException e) {
			System.out.println("[에러]selectNoStudent() 메소드의 SQL 오류 = "+e.getMessage());
		} finally {
			close(con, pstmt, rs);
		}
		//검색행이 없는 경우 null 반환하고 검색행이 있는 경우 StudentDTO 객체 반환
		return student;
	}

	//🍎 selectNameStudentList(String name) - List<StudentDTO>
	//이름을 전달받아 STUDENT 테이블에 저장된 해당 이름의 학생목록을 검색하여 반환하는 메소드
	@Override
	public List<StudentDTO> selectNameStudentList(String name) {
		Connection con=null;
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		List<StudentDTO> studentList=new ArrayList<StudentDTO>();
		try {
			con=getConnection();
			
			//where 조건식에서 매개변수로 전달된 값과 같은 행 검색
			//String sql="select * from student where name=? order by no";
			//where 조건식에서 매개변수로 전달된 값이 포함된 행 검색
			String sql="select * from student where name like '%'||?||'%' order by no";
			pstmt=con.prepareStatement(sql);
			pstmt.setString(1, name);
			
			rs=pstmt.executeQuery();
			
			while(rs.next()) {
				StudentDTO student=new StudentDTO();
				student.setNo(rs.getInt("no"));
				student.setName(rs.getString("name"));
				student.setPhone(rs.getString("phone"));
				student.setAddress(rs.getString("address"));
				student.setBirthday(rs.getString("birthday").substring(0, 10));
				studentList.add(student);
			}
		} catch (SQLException e) {
			System.out.println("[에러]selectNameStudentList() 메소드의 SQL 오류 = "+e.getMessage());
		} finally {
			close(con, pstmt, rs);
		}
		return studentList;
	}

	//🍎 selectAllStudentList() - List<StudentDTO>
	//STUDENT 테이블에 저장된 모든 학생정보를 검색하여 반환하는 메소드 - 다중행을 검색한 경우 검색결과를 List 객체로 변환하여 반환
	@Override
	public List<StudentDTO> selectAllStudentList() {
		Connection con=null;
		PreparedStatement pstmt=null;
		ResultSet rs=null;
		List<StudentDTO> studentList=new ArrayList<StudentDTO>();
		try {
			con=getConnection();
			
			String sql="select * from student order by no";
			pstmt=con.prepareStatement(sql);
			
			rs=pstmt.executeQuery();
			
			//ResultSet 커서를 다음행으로 이동하여 처리행의 없는 경우 반복문을 종료하고
			//처리행이 있는 경우 반복문 실행
			while(rs.next()) {
				//처리행의 컬럼값을 DTO 객체의 필드값으로 변환하여 저장 - 매핑처리
				StudentDTO student=new StudentDTO();
				student.setNo(rs.getInt("no"));
				student.setName(rs.getString("name"));
				student.setPhone(rs.getString("phone"));
				student.setAddress(rs.getString("address"));
				student.setBirthday(rs.getString("birthday").substring(0, 10));
				
				//List 객체의 요소(Element)로 StudentDTO 객체 추가
				studentList.add(student);
			}
		} catch (SQLException e) {
			System.out.println("[에러]selectAllStudentList() 메소드의 SQL 오류 = "+e.getMessage());
		} finally {
			close(con, pstmt, rs);
		}
		return studentList;
	}

}

[STEP4] 프로그램 만들기 - 학생관리CUI프로그램

StudentManagerApp.java
package xyz.itwill.student;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.List;
import java.util.regex.Pattern;

//학생정보를 관리하는 프로그램 작성
//=> 메뉴 선택에 따른 학생정보 (삽입, 삭제, 변경, 검색 기능) 제공 - DAO클래스에서 데이타 처리
//=> 입력과 출력은 프로그램에서 구현하고 데이타 처리는 DAO 클래스의 메소드를 호출하여 처리되도록 구현
//=> DAO 디자인 패턴을 이용한 프로그램

//키보드로 입력하고 모니터로 출력하는 콘솔프로그램으로 작성
public class StudentManagerApp {

 

🐹필드

//키보드 입력스트림을 저장하기 위한 필드 - 모든 메소드에서 사용하기 위해 필드로 선언
	private BufferedReader in;

 

🐹생성자

	public StudentManagerApp() {

		//키보드로 문자열을 입력받기 위한 입력스트림 생성 : 원시데이타 -> 문자데이타 -> 문자열
		in = new BufferedReader(new InputStreamReader(System.in));
		
		String[] menu = {"1.학생정보 삽입","2.학생정보 변경","3.학생정보 삭제","4.학생정보 검색","5.학생목록 출력","6.프로그램 종료"};
		System.out.println("<<학생 관리 프로그램>>");

		while(true) {
    		//1. 메뉴 출력
			for(String item:menu) {
				System.out.println(item);
			}
			//2. 메뉴 선택 - 잘못된 입력값이면 다시 선택하도록 작성
			int choice;
			try {
				System.out.print("선택[1~6]");
				choice = Integer.parseInt(in.readLine()); //NumberFormatException 발생 가능
				//비정상적 입력값인 경우
				if(choice < 1 || choice > 6) throw new Exception(); //인위적 예외 발생
			} catch (Exception e) {
				System.out.println("[에러]메뉴를 잘못 선택 하였습니다.");
				System.out.println();
				continue; //반복문 재실행
			}
			System.out.println();
			//3. [6.프로그램종료] 메뉴를 선택한 경우 반복문 종료 - 프로그램 종료
			if(choice == 6) break;
			//4. 메뉴 선택에 따른 메소드 호출
			switch (choice) {
			case 1: addStudent(); break;
			case 2: modifyStudent(); break;
			case 3: removeStudent(); break;
			case 4: searchNameStudent(); break;
			case 5: displayAllStudent(); break;
			}
			System.out.println();
		}
		System.out.println("[메세지]학생 관리 프로그램을 종료합니다.");
	}

 

🐹메인메소드

	public static void main(String[] args) {
		new StudentManagerApp();
	}

 

🐹 1. addStudent()메소드

	//[1.학생정보 삽입] 메뉴를 선택한 경우 호출되는 메소드 - 키보드로 학생정보를 입력받아 STUDENT테이블에 삽입(JDBC이용)하고 처리결과를 반환받아 출력 //STUDENT테이블에 삽입(JDBC이용) - DAO클래스가 데이타처리해줄것임
	public void addStudent() {
		System.out.println("### 학생정보 삽입 ###");

		try {
			//키보드로 학생정보를 입력받아 저장 - 입력값 검증
			// => 입력값 검증이 실패한 경우 재입력되도록 처리
	
			//1. 학번을 입력받아 저장하기 위한 변수 - 검증된 값만 정수값으로 변환하여 저장
			int no; 
			while(true) { //학번 입력값을 검증하기 위한 반복문
				System.out.print("학번 입력 >> ");
				String noTemp = in.readLine();
				if(noTemp == null || noTemp.equals("")) { //입력값이 존재하지 않는 경우
					System.out.println("[입력오류]학번을 반드시 입력해 주세요.");
					continue;//반복문 재실행
				}
				//학번에 대한 입력패턴을 저장한 정규표현식 작성
				String noReg = "^[1-9][0-9]{3}$"; //첫번째 문자는 반드시 [1-9] 중 하나로 시작 ,두번째,세번째,네번째 3자리 숫자는 [0~9]로 끝나는
				//정규표현식과 입력값의 패턴이 다른 경우
				if(!Pattern.matches(noReg, noTemp)) {
					System.out.println("[입력오류]학번을 4자리 숫자로만 입력해 주세요");
					continue;//반복문 재실행
				}
				//문자열을 정수값으로 변환하여 저장
				no = Integer.parseInt(noTemp);
				//STUDENT 테이블에 저장된 기존 학생정보의 학번과 중복된 경우 재입력되도록 작성
				//학번을 전달받아 STUDENT 테이블에 저장된 해당 학번의 학생정보를 검색하여 처리
				//=> StudentDAOImpl 클래스의 selectNoStudent(int no)메소드 호출
				StudentDTO student=  StudentDAOImpl.getDAO().selectNoStudent(no);
				if(student!=null) {//검색행이 있는 경우 - 학번이 중복된 경우
					System.out.println("[입력오류]현재 사용 중인 학번입니다. 다시 입력해 주세요.");
					continue;
				}
				break; //반복문 종료
			}

			//2. 이름을 입력받아 저장하기 위한 변수 - 검증된 값만 저장함
			String name;
			while(true) { //이름 입력값을 검증하기 위한 반복문
				System.out.print("이름 입력 >> ");
				name = in.readLine();
				if(name == null || name.equals("")) { //입력값이 존재하지 않는 경우
					System.out.println("[입력오류]이름을 반드시 입력해 주세요.");
					continue;//반복문 재실행
				}
				//이름에 대한 입력패턴을 저장한 정규표현식 작성
				String nameReg = "^[가-힣]{2,5}$"; //한글만 입력가능, 한글이 2글자~5글자까지
				//정규표현식과 입력값의 패턴이 다른 경우
				if(!Pattern.matches(nameReg, name)) {
					System.out.println("[입력오류]이름은 2~5 범위의 한글만 입력해 주세요");
					continue;//반복문 재실행
				}
				break; //반복문 종료
			}

			//3. 전화번호를 입력받아 저장하기 위한 변수 - 검증된 값만 저장함
			String phone;
			while(true) { //전화번호 입력값을 검증하기 위한 반복문
				System.out.print("전화번호 입력 >> ");
				phone = in.readLine();
				if(phone == null || phone.equals("")) { //입력값이 존재하지 않는 경우
					System.out.println("[입력오류]전화번호를 반드시 입력해 주세요.");
					continue;//반복문 재실행
				}
				//전화번호에 대한 입력패턴을 저장한 정규표현식 작성
				String phoneReg = "(01[016789])-\\\\\\\\d{3,4}-\\\\\\\\d{4}"; //앞에 자리는 01 후 [016789] 중 하나가 나와야함, - 무조건, \\\\\\\\d : 숫자값이 3번에서 4번 반복 , 숫자값이 4번 반복
				//정규표현식과 입력값의 패턴이 다른 경우
				if(!Pattern.matches(phoneReg, phone)) {
					System.out.println("[입력오류]전화번호를 형식에 맞게 입력해 주세요");
					continue;//반복문 재실행
				}
				break; //반복문 종료
			}

			//4. 주소를 입력받아 저장하기 위한 변수 - 검증된 값만 저장함
			String address;
			while(true) { //주소 입력값을 검증하기 위한 반복문
				System.out.print("주소 입력 >> ");
				address = in.readLine();
				if(address == null || address.equals("")) { //입력값이 존재하지 않는 경우
					System.out.println("[입력오류]주소를 반드시 입력해 주세요.");
					continue;//반복문 재실행
				}
				break; //반복문 종료
			}

			//5. 생년월일을 입력받아 저장하기 위한 변수 - 검증된 값만 저장함
			String birthday;
			while(true) { //생년월일 입력값을 검증하기 위한 반복문
				System.out.print("생년월일 입력 >> ");
				birthday = in.readLine();
				if(birthday == null || birthday.equals("")) { //입력값이 존재하지 않는 경우
					System.out.println("[입력오류]생년월일을 반드시 입력해 주세요.");
					continue;//반복문 재실행
				}
				//생년월일에 대한 입력패턴을 저장한 정규표현식 작성
				String birthdayReg = "(19|20)\\\\\\\\d{2}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])"; //앞이 19나 20으로 시작, 숫자 2개임 (년도4자리)  -  01~09 혹은 10~12(월2자리) - 01~09 혹은 10~29 혹은 30~31 (일2자리)
				//정규표현식과 입력값의 패턴이 다른 경우
				if(!Pattern.matches(birthdayReg, birthday)) {
					System.out.println("[입력오류]생년월일을 형식에 맞게 입력해 주세요");
					continue;//반복문 재실행
				}
				break; //반복문 종료
			}

			//6. 입력받은 학생정보를 이용하여 StudentDTO 객체를 생성하여 필드값 변경 - DTO 클래스의 메소드를 호출하기 위한 필요한 값을 객체로 변환하여 전달
			StudentDTO student = new StudentDTO();
			student.setNo(no);
			student.setName(name);
			student.setPhone(phone);
			student.setAddress(address);
			student.setBirthday(birthday);

			//7. 입력받은 학생정보를 이용하여 STUDENT테이블에 삽입 처리 - StudentDAOImpl 클래스의 insertStudnet(StudentDTO student) 메소드 호출
			//싱글톤 클래스는 객체를 반환받아 메소드를 직접 호출하여 사용 - 참조변수 불필요
			int rows = StudentDAOImpl.getDAO().insertStudent(student);
			System.out.println("[처리결과]"+rows+"명의 학생정보를 삽입 하였습니다.");
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

🐹 2. modifyStudent()메소드

	//[2.학생정보 변경] 메뉴를 선택한 경우 호출되는 메소드 - 키보드로 학번을 입력받아 STUDENT 테이블에 저장된 해당 학번의 학생정보를 검색하여 검색결과를 반환받아 출력
	// => 키보드로 변경할 학생정보를 입력받아 STUDENT 테이블에 저장된 학생정보를 변경하고 처리결과를 반환받아 출력 
	public void modifyStudent() {
		System.out.println("### 학생정보 변경 ###");
		
		try {
			//1.
			//키보드로 학번을 입력받아 저장 - 입력값 검증
			int no;
			while(true) { //학번 입력값을 검증하기 위한 반복문
				System.out.print("학번 입력 >> ");
				String noTemp = in.readLine();
				if(noTemp == null || noTemp.equals("")) { //입력값이 존재하지 않는 경우
					System.out.println("[입력오류]학번을 반드시 입력해 주세요.");
					continue;//반복문 재실행
				}
				//학번에 대한 입력패턴을 저장한 정규표현식 작성
				String noReg = "^[1-9][0-9]{3}$";
				//정규표현식과 입력값의 패턴이 다른 경우
				if(!Pattern.matches(noReg, noTemp)) {
					System.out.println("[입력오류]학번을 4자리 숫자로만 입력해 주세요");
					continue;//반복문 재실행
				}
				//문자열을 정수값으로 변환하여 저장
				no = Integer.parseInt(noTemp);
				break; //반복문 종료
			}
			
			//입력된 학번으로 STUDENT 테이블에 저장된 해당 학번의 학생정보를 검색하여 반환받아 저장
			// => StudentDAOImpl 클래스의 selectNoStudent(int no) 메소드 호출
			StudentDTO student=StudentDAOImpl.getDAO().selectNoStudent(no);
			
			if(student==null) {//검색된 학생정보가 없는 경우
				System.out.println("[처리결과]변경할 학번의 학생정보가 없습니다.");
				return;
			}
			
			//검색된 학생정보 출력
			System.out.println("=============================================================");
			System.out.println("학번\\t이름\\t전화번호\\t주소\\t\\t생년월일");
			System.out.println("=============================================================");
			System.out.println(student.getNo()+"\\t"+student.getName()
				+"\\t"+student.getPhone()+"\\t"+student.getAddress()+"\\t"+student.getBirthday());
			System.out.println("=============================================================");
			
			//2.
			//키보드로 변경값(이름, 전화번호, 주소, 생년월일)을 입력받아 저장 - 변경값 검증
			System.out.println("[메세지]변경값 입력 >> 변경하지 않을 경우 엔터만 입력해 주세요.");
			
			//2-1.			
			String name;//이름을 입력받아 저장하기 위한 변수
			while(true) {//이름 입력값을 검증하기 위한 반복문
				System.out.print("이름 입력 >> ");
				name = in.readLine();
				String nameReg="^[가-힣]{2,5}$";
				//검증에 대한 조건식이 위에와 다름 - 입력값이 있으면서 && 입력값이 패턴에 맞지 않다면
				//입력값이 있는 경우 입력값이 정규표현식의 패턴과 같지 않은 경우
				if(name != null && !name.equals("") && !Pattern.matches(nameReg, name)) {
					System.out.println("[입력오류]이름은 2~5 범위의 한글만 입력해 주세요");
					continue;//반복문 재실행
				}
				break; //반복문 종료
			}
			
			//2-2.
			String phone;//전화번호를 저장하기 위한 변수
			while(true) {//전화번호 입력값을 검증하기 위한 반복문
				System.out.print("전화번호 입력 >> ");
				phone=in.readLine();
				//전화번호에 대한 입력패턴을 저장한 정규표현식 작성
				String phoneReg="(01[016789])-\\\\d{3,4}-\\\\d{4}";
				if(phone!=null && !phone.equals("") && !Pattern.matches(phoneReg, phone)) {
					System.out.println("[입력오류]전화번호를 형식에 맞게 입력해 주세요.");
					continue;
				}			
				break;
			}
			
			//2-3.
			System.out.print("주소 입력 >> ");
			String address=in.readLine();//주소를 입력받아 저장하기 위한 변수
			
			//2-4.
			String birthday;//생년월일을 저장하기 위한 변수
			while(true) {//생년월일 입력값을 검증하기 위한 반복문
				System.out.print("생년월일 입력 >> ");
				birthday=in.readLine();				
				//생년월일에 대한 입력패턴을 저장한 정규표현식 작성
				String birthdayReg="(19|20)\\\\d{2}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])";
				if(birthday!=null && !birthday.equals("") && !Pattern.matches(birthdayReg, birthday)) {
					System.out.println("[입력오류]생년월일을 형식에 맞게 입력해 주세요.");
					continue;
				}
				break;
			}
			
			//3.
			//변경값을 이용하여 검색된 StudentDTO 객체의 필드값 변경
			// => 변경값이 있는 경우에만 StudentDTO 객체의 필드값
			if(name!=null && !name.equals("")) student.setName(name);
			if(phone!=null && !phone.equals("")) student.setPhone(phone);
			if(address!=null && !address.equals("")) student.setAddress(address);
			if(birthday!=null && !birthday.equals("")) student.setBirthday(birthday);
			
			//4.
			//입력받은 학생정보를 이용하여 STUDENT 테이블에 저장된 학생정보를 변경하고 처리결과를 반환받아 저장
			// => StudentDAOImpl 클래스의 updateStudent(StudentDTO student) 메소드 호출
			int rows=StudentDAOImpl.getDAO().updateStudent(student);
			
			//5.
			System.out.println("[처리결과]"+rows+"명의 학생정보를 변경 하였습니다.");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

🐹 3. removeStudent()메소드

	//[3.학생정보 삭제] 메뉴를 선택한 경우 호출되는 메소드
	// => 키보드로 학번을 입력받아 STUDENT 테이블에 저장된 해당 학번의 학생정보를 삭제하고
	//처리결과를 반환받아 출력
	public void removeStudent() {
		System.out.println("### 학생정보 삭제 ###");
		
		try {
			//키보드로 학번을 입력받아 저장 - 입력값 검증
			int no;
			while(true) {
				System.out.print("학번 입력 >> ");
				String noTemp=in.readLine();
				
				if(noTemp==null || noTemp.equals("")) {//입력값이 존재하지 않는 경우
					System.out.println("[입력오류]학번을 반드시 입력해 주세요.");
					continue;
				}
				
				//학번에 대한 입력패턴을 저장한 정규표현식 작성
				String noReg="^[1-9][0-9]{3}$";
				if(!Pattern.matches(noReg, noTemp)) {//정규표현식과 입력값의 패턴이 다른 경우
					System.out.println("[입력오류]학번을 4자리 숫자로만 입력해 주세요.");
					continue;
				}
				
				no=Integer.parseInt(noTemp);
				
				break;
			}
			
			//입력된 학번을 이용하여 STUDENT 테이블에 저장된 해당 학번의 학생정보를 삭제하고
			//처리결과를 반환받아 저장
			// => StudentDAOImpl 클래스의 deleteStudent(int no) 메소드 호출
			int rows=StudentDAOImpl.getDAO().deleteStudent(no);
			
			if(rows>0) {//삭제행이 있는 경우
				System.out.println("[처리결과]"+rows+"명의 학생정보를 삭제 하였습니다.");
			} else {//삭제행이 없는 경우 - 입력된 학번의 학생정보가 없는 경우
				System.out.println("[처리결과]삭제할 학번의 학생정보가 없습니다.");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

🐹 4. searchNameStudent()메소드

	//[4.학생정보 검색] 메뉴를 선택한 경우 호출되는 메소드
	// => 키보드로 이름을 입력받아 STUDENT 테이블에 저장된 해당 이름의 학생정보를 검색하고
	//결과를 반환받아 출력
	public void searchNameStudent() {
		System.out.println("### 학생정보 검색 ###");
		
		try {
			//키보드로 이름을 입력받아 저장 - 입력값 검증
			String name;
			while(true) {
				System.out.print("이름 입력 >> ");
				name=in.readLine();				
				if(name==null || name.equals("")) {//입력값이 존재하지 않는 경우
					System.out.println("[입력오류]이름을 반드시 입력해 주세요.");
					continue;//반복문 재실행
				}				
				//이름에 대한 입력패턴을 저장한 정규표현식 작성
				String nameReg="^[가-힣]{2,5}$";
				if(!Pattern.matches(nameReg, name)) {//정규표현식과 입력값의 패턴이 다른 경우
					System.out.println("[입력오류]이름은 2~5 범위의 한글만 입력해 주세요.");
					continue;
				}			
				break;
			}
			
			//입력된 이름을 이용하여 STUDENT 테이블에 저장된 해당 이름의 학생정보를 검색하고
			//검색결과를 반환받아 저장
			// => StudentDAOImpl 클래스의 selectNameStudentList(String name) 메소드 호출
			List<StudentDTO> studentList=StudentDAOImpl.getDAO().selectNameStudentList(name);
			
			//List.size() : List 객체에 저장된 요소(Element)의 갯수를 반환하는 메소드
			if(studentList.size()==0) {//List 객체에 저장된 요소가 없는 경우
				System.out.println("[처리결과]검색된 학생정보가 없습니다.");
				return;
			}
			
			System.out.println("=============================================================");
			System.out.println("학번\\t이름\\t전화번호\\t주소\\t\\t생년월일");
			System.out.println("=============================================================");
			for(StudentDTO student:studentList) {
				System.out.println(student.getNo()+"\\t"+student.getName()
					+"\\t"+student.getPhone()+"\\t"+student.getAddress()+"\\t"+student.getBirthday());
			}
			System.out.println("=============================================================");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

🐹 5. displayAllStudent()메소드

	//[5.학생목록 출력] 메뉴를 선택한 경우 호출되는 메소드
	// => STUDENT 테이블에 저장된 모든 학생정보를 검색하여 결과를 반환받아 출력
	public void displayAllStudent() {
		System.out.println("### 학생목록 출력 ###");
		
		//STUDENT 테이블에 저장된 모든 학생정보를 검색하여 저장
		// => StudentDAOImpl 클래스의 selectAllStudentList() 메소드 호출
		List<StudentDTO> studentList=StudentDAOImpl.getDAO().selectAllStudentList();
		
		//List.isEmpty() : List 객체에 요소가 있는 경우 [false]를 반환하고 요소가 없는
		//경우 [true]를 반환하는 메소드
		if(studentList.isEmpty()) {
			System.out.println("[처리결과]저장된 학생정보가 없습니다.");
			return;
		}
		
		System.out.println("=============================================================");
		System.out.println("학번\\t이름\\t전화번호\\t주소\\t\\t생년월일");
		System.out.println("=============================================================");
		//List 객체의 요소를 제공받아 처리하는 반복문
		for(StudentDTO student:studentList) {
			System.out.println(student.getNo()+"\\t"+student.getName()
				+"\\t"+student.getPhone()+"\\t"+student.getAddress()+"\\t"+student.getBirthday());
		}
		System.out.println("=============================================================");
	}

 

[STEP4] 프로그램 만들기 - 학생관리GUI프로그램

StudentGUIApp.java
package xyz.itwill.student; 

/********************************************************
파    일   명 : StudentGUIApp.java
기         능 : 학생 관리 프로그램
*********************************************************/
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import java.util.Vector;
import java.util.regex.Pattern;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;

//Java 프로그램(GUI)을 배포하는 방법 
//1.프로젝트 >> 오른쪽 버튼 클릭 >> Export >> Java 선택 >> Runnable JAR File 선택
//2.Launch configuration >> 프로그램 선택
//3.Export destination >> Jar 파일의 경로 입력
//3.Finish 클릭

public class StudentGUIApp extends JFrame implements ActionListener {
	private static final long serialVersionUID = 1L;

	public static final int NONE = 0;
	public static final int ADD = 1;
	public static final int DELETE = 2;
	public static final int UPDATE = 3;
	public static final int UPDATE_CHANGE = 4;
	public static final int SEARCH = 5;

	JTextField noTF, nameTF, phoneTF, addressTF, birthdayTF;
	JButton addB, deleteB, updateB, searchB, cancelB;

	//JTable : 테이블(표)를 제공하기 위한 컴퍼넌트
	JTable table;
	
	int cmd;
	/********************************************
	 * 생성자 정의
	 *********************************************/
	public StudentGUIApp() throws Exception {
		setTitle("◆◆◆ 학생 관리 프로그램 ◆◆◆");
		setSize(800, 400);

		//Dimension : 컴퍼넌트 크기를 저장하기 위한 객체
		Dimension dim = getToolkit().getScreenSize();
		setLocation(dim.width / 2 - getWidth() / 2, dim.height / 2
				- getHeight() / 2);

		JPanel left = new JPanel();
		left.setLayout(new GridLayout(5, 1));

		JPanel pno = new JPanel();
		pno.add(new JLabel("학  번"));
		pno.add(noTF = new JTextField(10));

		JPanel pname = new JPanel();
		pname.add(new JLabel("이  름"));
		pname.add(nameTF = new JTextField(10));
		
		JPanel pphone = new JPanel();
		pphone.add(new JLabel("전  화"));
		pphone.add(phoneTF = new JTextField(10));

		JPanel paddress = new JPanel();
		paddress.add(new JLabel("주  소"));
		paddress.add(addressTF = new JTextField(10));

		JPanel pbirthday = new JPanel();
		pbirthday.add(new JLabel("생  일"));
		pbirthday.add(birthdayTF = new JTextField(10));

		left.add(pno);
		left.add(pname);
		left.add(pphone);
		left.add(paddress);
		left.add(pbirthday);
		
		JPanel bottom = new JPanel();
		bottom.setLayout(new GridLayout(1, 5));

		bottom.add(addB = new JButton("삽  입"));
		addB.addActionListener(this);

		bottom.add(updateB = new JButton("변  경"));
		updateB.addActionListener(this);

		bottom.add(deleteB = new JButton("삭  제"));
		deleteB.addActionListener(this);

		bottom.add(searchB = new JButton("검  색"));
		searchB.addActionListener(this);
		
		bottom.add(cancelB = new JButton("초기화"));
		cancelB.addActionListener(this);

		Object[] title={"학번","이름","전화번호","주소","생년월일"};
		//DefaultTableModel : 테이블의 행과 열을 표현하기 위한 객체
		table=new JTable(new DefaultTableModel(title, 0));
		table.setEnabled(false);
		table.getTableHeader().setReorderingAllowed(false);
		table.getTableHeader().setResizingAllowed(false);

		JScrollPane sp=new JScrollPane(table);
		
		add(sp, "Center");
		add(left, "West");
		add(bottom, "South");
		cmd = NONE;
		initialize();

		//STUDENT 테이블에 저장된 모든 학생정보를 검색하여 JTable 컴퍼넌트에 출력
		displayAllStudent();
		
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setVisible(true);
	}

	//모든 텍스트 필드 컴퍼넌트를 비활성화 처리하는 메소드
	public void initialize() {
		noTF.setEditable(false);
		nameTF.setEditable(false);
		phoneTF.setEditable(false);
		addressTF.setEditable(false);
		birthdayTF.setEditable(false);
	}

	//이벤트에 따른 텍스트 필드의 활성화 상태 변경
	public void setEditable(int n) {
		switch (n) {
		case ADD:
			noTF.setEditable(true);
			nameTF.setEditable(true);
			phoneTF.setEditable(true);
			addressTF.setEditable(true);
			birthdayTF.setEditable(true);
			break;
		case DELETE:
			noTF.setEditable(true);
			break;
		case UPDATE:
			noTF.setEditable(true);
			break;
		case UPDATE_CHANGE:
			noTF.setEditable(false);
			nameTF.setEditable(true);
			phoneTF.setEditable(true);
			addressTF.setEditable(true);
			birthdayTF.setEditable(true);
			break;
		case SEARCH:
			nameTF.setEditable(true);
			break;
		case NONE:
			noTF.setEditable(false);
			nameTF.setEditable(false);
			phoneTF.setEditable(false);
			addressTF.setEditable(false);
			birthdayTF.setEditable(false);
		}
	}

	//이벤트에 따른 컴퍼넌트의 활성화 상태 변경
	public void setEnable(int n) {
		addB.setEnabled(false);
		deleteB.setEnabled(false);
		updateB.setEnabled(false);
		searchB.setEnabled(false);

		switch (n) {
		case ADD:
			addB.setEnabled(true);
			setEditable(ADD);
			cmd = ADD;
			break;
		case DELETE:
			deleteB.setEnabled(true);
			setEditable(DELETE);
			cmd = DELETE;
			break;
		case UPDATE:
			updateB.setEnabled(true);
			setEditable(UPDATE);
			cmd = UPDATE;
			break;			
		case UPDATE_CHANGE:
			updateB.setEnabled(true);
			setEditable(UPDATE_CHANGE);
			cmd = UPDATE_CHANGE;
			break;			
		case SEARCH:
			searchB.setEnabled(true);
			setEditable(SEARCH);
			cmd = SEARCH;
			break;
		case NONE:
			addB.setEnabled(true);
			deleteB.setEnabled(true);
			updateB.setEnabled(true);
			searchB.setEnabled(true);
		}
	}

	public void clear() {
		noTF.setText("");
		nameTF.setText("");
		phoneTF.setText("");
		addressTF.setText("");
		birthdayTF.setText("");
	}

	public void initDisplay() {
		setEnable(NONE);
		clear();
		cmd = NONE;
		initialize();		
	}

	public static void main(String args[]) throws Exception {
		new StudentGUIApp();
	}

	public void actionPerformed(ActionEvent ev) {
		Component c = (Component) ev.getSource();
		try {
			if (c == addB) {
				if (cmd != ADD) {//첫번째 [삽입] 버튼을 누른 경우 - NONE 상태
					setEnable(ADD);//컴퍼넌트의 활성화 상태 변경 - ADD 상태 변경					
				} else {//두번째 [삽입] 버튼을 누른 경우 - ADD 상태
					//학생정보를 입력받아 STUDENT 테이블에 삽입하여 저장하는 메소드 호출
					addStudent();
				}
			} else if (c == updateB) {
				if (cmd != UPDATE && cmd != UPDATE_CHANGE) {//첫번째 [변경] 버튼을 누른 경우 - NONE 상태
					setEnable(UPDATE);//입출력 컴퍼넌트의 활성화 상태 변경 - UPDATE 상태 변경		
				} else if (cmd != UPDATE_CHANGE) {//두번째 [변경] 버튼을 누른 경우	- UPDATE 상태
					//입력된 학번으로 STUDENT 테이블에 저장된 해당 학번의 학생정보를 검색하여 출력하는 메소드 호출		
					searchNoStudent();
				} else {//두번째 [변경] 버튼을 누른 경우 - UPDATE_CHANGE 상태		
					//학번을 제외한 학생정보의 변경값을 입력받아 STUDENT 테이블에 저장된 학생정보를 변경하는 메소드 호출
					modifyStudent();
				}
			} else if (c == deleteB) {
				if (cmd != DELETE) {//첫번째 [삭제] 버튼을 누른 경우 - NONE 상태
					setEnable(DELETE);//입출력 컴퍼넌트의 활성화 상태 변경 - DELETE 상태 변경		
				} else {//두번째 [삭제] 버튼을 누른 경우 - DELETE 상태
					//입력된 학번으로 STUDENT 테이블에 저장된 해당 학번의 학생정보를 삭제하는 메소드 호출
					removeStudent();
				}
			} else if (c == searchB) {
				if (cmd != SEARCH) {//첫번째 [검색] 버튼을 누른 경우 - NONE 상태
					setEnable(SEARCH);//입출력 컴퍼넌트의 활성화 상태 변경 - SEARCH 상태 변경		
				} else {//두번째 [검색] 버튼을 누른 경우 - SEARCH 상태
					//입력된 이름으로 STUDENT 테이블에 저장된 해당 이름이 포함된 학생정보를 
					//검색하는 출력하는 메소드 호출
					searchNameStudent();
				}
			} else if (c == cancelB) {
				displayAllStudent();
				initDisplay();
			}
		} catch (Exception e) {
			System.out.println("예외 발생 : " + e);
		}		
	}

	//STUDENT 테이블에 저장된 모든 학생정보를 검색하여 JTable 컴퍼넌트에 출력하는 메소드
	public void displayAllStudent() {
		//STUDENT 테이블에 저장된 모든 학생정보를 검색하여 저장
		// => StudentDAOImplImplImpl 클래스의 selectAllStudentList() 메소드 호출
		List<StudentDTO> studentList=StudentDAOImpl.getDAO().selectAllStudentList();
		
		if(studentList.isEmpty()) {
			//JOptionPane.showMessageDialog(Component parentComponent, String message) 
			// => 메세지 다이얼로그를 출력하는 메소드
			JOptionPane.showMessageDialog(this, "저장된 학생정보가 없습니다.");
			return;
		}
		
		//JTable.getModel() : JTable 객체의 TableModel 객체를 반환하는 메소드
		//JTable : 테이블(표) 형식으로 값을 출력하기 위한 컴퍼넌트
		//TableModel : 테이블의 행 또는 열에 대한 기능을 제공하기 위한 객체 - 인터페이스
		//DefaultTableModel : TableModel 인터페이스를 상속받아 작성된 클래스
		DefaultTableModel model=(DefaultTableModel)table.getModel();
		
		//JTable 컴퍼넌트에 출력된 기존의 모든 행을 삭제 처리 - JTable 컴퍼넌트 초기화
		//DefaultTableModel.getRowCount() : DefaultTableModel 객체에 저장된 행의 갯수를 반환하는 메소드
		for(int i=model.getRowCount();i>0;i--) {
			//DefaultTableModel.removeRow(int rowIndex) : DefaultTableModel 객체에서 원하는 위치의
			//행을 삭제하는 메소드
			model.removeRow(0);//첫번째 위치의 행 삭제
		}
		
		//List 객체에서 요소(Element - StudentDTO)를 하나씩 제공받아 반복 처리
		// => 검색된 학생정보를 DefaultTableModel 객체의 행으로 추가하여 출력 
		for(StudentDTO student:studentList) {
			//하나의 학생정보를 저장하기 위한 Vector 객체 생성
			Vector<Object> rowData=new Vector<Object>();
			rowData.add(student.getNo());
			rowData.add(student.getName());
			rowData.add(student.getPhone());
			rowData.add(student.getAddress());
			rowData.add(student.getBirthday());
			
			//DefaultTableModel.addRow(Vector rowData) : DefaultTableModel 객체에 행을 추가하는 메소드
			model.addRow(rowData);
		}
	}
	//JTextField 컴퍼넌트로 입력된 학생정보를 제공받아 STUDENT 테이블에 삽입하여 저장하고 
	//STUDENT 테이블에 저장된 모든 학생정보를 검색하여 JTable 컴퍼넌트에 출력하는 메소드
	// => 컴퍼넌트 초기화 및 NONE 상태 변경
	public void addStudent() {
		//학번 입력값을 반환받아 저장 - 입력값에 대한 검증 
		//JTextField.getText() : JTextField 컴퍼넌트의 입력값을 반환하는 메소드
		String noTemp=noTF.getText();
		
		if(noTemp.equals("")) {//입력값이 없는 경우
			JOptionPane.showMessageDialog(this, "학번을 반드시 입력해 주세요.");
			//JTextField.requestFocus() : JTextField 컴퍼넌트로 입력커서를 이동하는 메소드
			noTF.requestFocus();
			return;
		}
		
		String noReg="^[1-9][0-9]{3}$";
		if(!Pattern.matches(noReg, noTemp)) {
			JOptionPane.showMessageDialog(this, "학번은 4자리의 숫자로만 입력해 주세요.");
			noTF.requestFocus();
			return;
		}
		
		int no=Integer.parseInt(noTemp);
		
		//검색된 학생정보(STUDENT 테이블에 저장된 기존 학생정보)가 있는 경우  
		if(StudentDAOImpl.getDAO().selectNoStudent(no)!=null) {
			JOptionPane.showMessageDialog(this, "이미 사용중인 학번입니다.다시 입력해 주세요.");
			noTF.requestFocus();
			return;
		}
		
		//이름 입력값을 반환받아 저장 - 입력값에 대한 검증
		String name=nameTF.getText();
		
		if(name.equals("")) {
			JOptionPane.showMessageDialog(this, "이름을 반드시 입력해 주세요.");
			nameTF.requestFocus();
			return;
		}
		
		String nameReg="^[가-힣]{2,5}$";
		if(!Pattern.matches(nameReg, name)) {
			JOptionPane.showMessageDialog(this, "이름은 2~5 범위의 한글로만 입력해 주세요.");
			nameTF.requestFocus();
			return;
		}
		
		//전화번호 입력값을 반환받아 저장 - 입력값에 대한 검증
		String phone=phoneTF.getText();
		
		if(phone.equals("")) {
			JOptionPane.showMessageDialog(this, "전화번호를 반드시 입력해 주세요.");
			phoneTF.requestFocus();
			return;
		}
		
		String phoneReg="(01[016789])-\\\\d{3,4}-\\\\d{4}";
		if(!Pattern.matches(phoneReg, phone)) {
			JOptionPane.showMessageDialog(this, "전화번호를 형식에 맞게 입력해 주세요.");
			phoneTF.requestFocus();
			return;
		}
		
		//주소 입력값을 반환받아 저장 - 입력값에 대한 검증
		String address=addressTF.getText();
		
		if(address.equals("")) {
			JOptionPane.showMessageDialog(this, "전화번호를 반드시 입력해 주세요.");
			addressTF.requestFocus();
			return;
		}

		//생년월일 입력값을 반환받아 저장 - 입력값에 대한 검증
		String birthday=birthdayTF.getText();
		
		if(birthday.equals("")) {
			JOptionPane.showMessageDialog(this, "생년월일을 반드시 입력해 주세요.");
			birthdayTF.requestFocus();
			return;
		}
		
		String birthdayReg="(19|20)\\\\d{2}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])";
		if(!Pattern.matches(birthdayReg, birthday)) {
			JOptionPane.showMessageDialog(this, "생년월일을 형식에 맞게 입력해 주세요.");
			birthdayTF.requestFocus();
			return;
		}
		
		//StudentDTO 객체를 생성하여 입력값으로 필드값 변경
		StudentDTO student=new StudentDTO();
		student.setNo(no);
		student.setName(name);
		student.setPhone(phone);
		student.setAddress(address);
		student.setBirthday(birthday);
		
		//입력받은 학생정보를 STUDENT 테이블에 삽입하여 저장
		// => StudentDAOImplImplImpl 클래스의 insertStudent(StudentDTO student) 메소드 호출
		int rows=StudentDAOImpl.getDAO().insertStudent(student);
		
		JOptionPane.showMessageDialog(this, rows+"명의 학생정보를 삽입 하였습니다.");

		displayAllStudent();//모든 학생정보를 검색하여 출력
		initDisplay();//컴퍼넌트 초기화 및 NONE 상태 변경
	}
	//JTextField 컴퍼넌트로 입력된 학번을 제공받아 STUDENT 테이블에 저장된 해당 학번의 학생정보를 
	//검색하여 JTextField 컴퍼넌트에 출력하는 메소드 - UPDATE_CHANGE 상태 변경
	public void searchNoStudent() {
		//학번 입력값을 반환받아 저장 - 입력값에 대한 검증 
		String noTemp=noTF.getText();
		
		if(noTemp.equals("")) {
			JOptionPane.showMessageDialog(this, "학번을 반드시 입력해 주세요.");
			noTF.requestFocus();
			return;
		}
		
		String noReg="^[1-9][0-9]{3}$";
		if(!Pattern.matches(noReg, noTemp)) {
			JOptionPane.showMessageDialog(this, "학번은 4자리의 숫자로만 입력해 주세요.");
			noTF.requestFocus();
			return;
		}
		
		int no=Integer.parseInt(noTemp);
		
		//입력된 학번을 이용하여 STUDENT 테이블에 저장된 해당 학번의 학생정보를 검색하여 저장
		// => StudentDAOImplImplImpl 클래스의 selectNoStudent(int no) 메소드 호출
		StudentDTO student=StudentDAOImpl.getDAO().selectNoStudent(no);
		
		if(student==null) {//검색된 학생정보가 없는 경우
			JOptionPane.showMessageDialog(this, "변경하고자 하는 학번의 학생정보가 없습니다.");
			noTF.requestFocus();
			noTF.setText("");
			return;
		}
		
		//검색된 학생정보를 JTextField 컴퍼넌트에 출력
		noTF.setText(student.getNo()+"");
		nameTF.setText(student.getName());
		phoneTF.setText(student.getPhone());
		addressTF.setText(student.getAddress());
		birthdayTF.setText(student.getBirthday());
		
		//컴퍼넌트의 활성화 상태 변경 및 UPDATE_CHANGE 상태 변경
		setEnable(UPDATE_CHANGE);
	}
	//JTextField 컴퍼넌트로 입력된 학생정보를 제공받아 STUDENT 테이블에 저장된 학생정보를 변경하고 
	//STUDENT 테이블에 저장된 모든 학생정보를 검색하여 JTable 컴퍼넌트에 출력하는 메소드
	public void modifyStudent() {
		//학번을 반환받아 저장 
		int no=Integer.parseInt(noTF.getText());
		
		//이름 변경값을 반환받아 저장 - 변경값에 대한 검증
		String name=nameTF.getText();
		
		if(name.equals("")) {
			JOptionPane.showMessageDialog(this, "이름을 반드시 입력해 주세요.");
			nameTF.requestFocus();
			return;
		}
		
		String nameReg="^[가-힣]{2,5}$";
		if(!Pattern.matches(nameReg, name)) {
			JOptionPane.showMessageDialog(this, "이름은 2~5 범위의 한글로만 입력해 주세요.");
			nameTF.requestFocus();
			return;
		}
		
		//전화번호 변경값을 반환받아 저장 - 변경값에 대한 검증
		String phone=phoneTF.getText();
		
		if(phone.equals("")) {
			JOptionPane.showMessageDialog(this, "전화번호를 반드시 입력해 주세요.");
			phoneTF.requestFocus();
			return;
		}
		
		String phoneReg="(01[016789])-\\\\d{3,4}-\\\\d{4}";
		if(!Pattern.matches(phoneReg, phone)) {
			JOptionPane.showMessageDialog(this, "전화번호를 형식에 맞게 입력해 주세요.");
			phoneTF.requestFocus();
			return;
		}
		
		//주소 변경값을 반환받아 저장 - 변경값에 대한 검증
		String address=addressTF.getText();
		
		if(address.equals("")) {
			JOptionPane.showMessageDialog(this, "전화번호를 반드시 입력해 주세요.");
			addressTF.requestFocus();
			return;
		}

		//생년월일 변경값을 반환받아 저장 - 변경값에 대한 검증
		String birthday=birthdayTF.getText();
		
		if(birthday.equals("")) {
			JOptionPane.showMessageDialog(this, "생년월일을 반드시 입력해 주세요.");
			birthdayTF.requestFocus();
			return;
		}
		
		String birthdayReg="(19|20)\\\\d{2}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])";
		if(!Pattern.matches(birthdayReg, birthday)) {
			JOptionPane.showMessageDialog(this, "생년월일을 형식에 맞게 입력해 주세요.");
			birthdayTF.requestFocus();
			return;
		}
		
		//StudentDTO 객체를 생성하여 변경값으로 필드값 변경
		StudentDTO student=new StudentDTO();
		student.setNo(no);
		student.setName(name);
		student.setPhone(phone);
		student.setAddress(address);
		student.setBirthday(birthday);
		
		//입력된 학생정보를 이용하여 STUDENT 테이블에 저장된 학생정보 변경
		// => StudentDAOImplImplImpl 클래스의 updateStudent(StudentDTO student) 메소드 호출
		int rows=StudentDAOImpl.getDAO().updateStudent(student);
		
		JOptionPane.showMessageDialog(this, rows+"명의 학생정보를 변경 하였습니다.");

		displayAllStudent();//모든 학생정보를 검색하여 출력
		initDisplay();//컴퍼넌트 초기화	및 NONE 상태
	}
	//JTextField 컴퍼넌트로 입력된 학번을 제공받아 STUDENT 테이블에 저장된 해당 학번의 학생정보를 
	//삭제하고 STUDENT 테이블에 저장된 모든 학생정보를 검색하여 JTable 컴퍼넌트에 출력하는 메소드
	public void removeStudent() {
		//학번 입력값을 반환받아 저장 - 입력값에 대한 검증 
		String noTemp=noTF.getText();
		
		if(noTemp.equals("")) {
			JOptionPane.showMessageDialog(this, "학번을 반드시 입력해 주세요.");
			noTF.requestFocus();
			return;
		}
		
		String noReg="^[1-9][0-9]{3}$";
		if(!Pattern.matches(noReg, noTemp)) {
			JOptionPane.showMessageDialog(this, "학번은 4자리의 숫자로만 입력해 주세요.");
			noTF.requestFocus();
			return;
		}
		
		int no=Integer.parseInt(noTemp);
		
		//입력된 학번을 이용하여 STUDENT 테이블에 저장된 해당 학번의 학생정보 삭제
		// => StudentDAOImplImplImpl 클래스의 deleteStudent(int no) 메소드 호출
		int rows=StudentDAOImpl.getDAO().deleteStudent(no);
		
		if(rows>0) {
			JOptionPane.showMessageDialog(this, rows+"명의 학생정보를 삭제 하였습니다.");
			displayAllStudent();
		} else {
			JOptionPane.showMessageDialog(this, "삭제하고자 하는 학번의 학생정보가 없습니다.");
		}
		
		initDisplay();
	}
	//JTextField 컴퍼넌트로 입력된 이름을 제공받아 STUDENT 테이블에 저장된 해당 이름이 포함된  
	//학생정보를 검색하고 JTable 컴퍼넌트에 출력하는 메소드	
	public void searchNameStudent() {
		//이름 입력값을 반환받아 저장 - 입력값에 대한 검증
		String name=nameTF.getText();
		
		if(name.equals("")) {
			JOptionPane.showMessageDialog(this, "이름을 반드시 입력해 주세요.");
			nameTF.requestFocus();
			return;
		}
		
		String nameReg="^[가-힣]{2,5}$";
		if(!Pattern.matches(nameReg, name)) {
			JOptionPane.showMessageDialog(this, "이름은 2~5 범위의 한글로만 입력해 주세요.");
			nameTF.requestFocus();
			return;
		}
		
		//입력된 이름을 이용하여 STUDENT 테이블에 저장된 해당 이름이 포함된 학생정보를 검색하여 저장
		// => StudentDAOImplImplImpl 클래스의 selectNameStudentList(String name) 메소드 호출
		List<StudentDTO> studentList=StudentDAOImpl.getDAO().selectNameStudentList(name);

		if(studentList.isEmpty()) {
			JOptionPane.showMessageDialog(this, "검색된 학생정보가 없습니다.");
			initDisplay();
			return;
		}
		
		DefaultTableModel model=(DefaultTableModel)table.getModel();
		
		for(int i=model.getRowCount();i>0;i--) {
			model.removeRow(0);
		}
		
		for(StudentDTO student:studentList) {
			Vector<Object> rowData=new Vector<Object>();
			rowData.add(student.getNo());
			rowData.add(student.getName());
			rowData.add(student.getPhone());
			rowData.add(student.getAddress());
			rowData.add(student.getBirthday());
			model.addRow(rowData);
		}
		
		initDisplay();
	}
}

[STEP5] 자바프로그램 배포하기

1) 배포하기

  • .jar 파일을 만들면 배포 가능
  • 웹프로그램은 .war파일로 배포할 것임.. 나중에 배움

2) Java 프로그램(GUI)을 배포하기

  • CUI프로그램은 안되고, GUI프로그램만 가능!

3

  1. 프로젝트 >> 오른쪽 버튼 클릭 >> Export >> Java 선택 >> Runnable JAR File 선택 - 실행할 수 있는 프로그램 배포 (실행하기 위한 파일 배포) or 프로젝트 >> 오른쪽 버튼 클릭 >> Export >> Java 선택 >> JAR File 선택 - 클래스 배포 (우리가 만든 클래스 배포)
  2. Launch configuration >> 프로그램 선택
  3. Export destination : 배포하고 싶은 프로그램 이름 작성 >> Jar 파일의 경로 입력 >> Finish 클릭
반응형