DAO클래스 작성법

yeong ·2022년 11월 4일

jdbc

목록 보기
1/1

DAO클래스란 저장매체에 행단위 정보(Record)를 삽입,변경,삭제,검색하는기능을 제공하기 위한 클래스

저장매체 : 정보를 행단위로 저장하여 관리하기 위한 하드웨어 또는 소프트웨어 - DBMS

인터페이스를 상속 받아 작성하는 것을 권장 - 메소드의 작성 규칙 제공 : 유지보수의 효율성 증가

싱글톤 디자인 패턴을 적용하여 작성하는 것을 권장 - 프로그램에 하나의 객체만 제공하는 클래스




공통적인 JDBC기능을 제공하는 프로그램: DAO클래스 작성 전에 모든 DAO클래스에서 공통적으로 사용하는 JDBC 기능을 제공하는 클래스를 만들어서 상속(Abstract)

DAO가 상속받을 클래스


DAO클래스가 반드시 상속받기 위한 인터페이스 :추상메소드를 이용하여 모든 DAO클래스가 동일한 형태로 선언되도록 오버라이드 될 메소드 작성를 작성하는 인터페이스(Interface)

DAO가 오라버이드 선언할 메소드를 가진 인터페이스



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)를 삽입,변경,삭제,검색하는
//기능을 제공하기 위한 클래스
// => 저장매체 : 정보를 행단위로 저장하여 관리하기 위한 하드웨어 또는 소프트웨어 - DBMS
// => 인터페이스를 상속 받아 작성하는 것을 권장 - 메소드의 작성 규칙 제공 : 유지보수의 효율성 증가
// => 싱글톤 디자인 패턴을 적용하여 작성하는 것을 권장 - 프로그램에 하나의 객체만 제공하는 클래스

//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;
	}
	
	//학생정보를 전달받아 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;
	}

	//학생정보를 전달받아 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;
	}

	//학번을 전달받아 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;
	}

	//학번을 전달받아 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;
	}

	//이름을 전달받아 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();
			
			String sql="select * from student where name=? 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;
	}

	//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;
	}

}

<br


최종 프로그램

package xyz.itwill.student;

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

//학생정보를 관리하는 프로그램 작성
// => 메뉴 선택에 따른 학생정보 삽입,변경,삭제,검색 기능 제공
// => 입력과 출력은 프로그램에서 구현하고 데이타는 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) {
			//메뉴 출력
			for(String item:menu) {
				System.out.println(item);
			}
			
			//메뉴 선택
			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();
			
			//[6.프로그램 종료] 메뉴를 선택한 경우 반복문 종료 - 프로그램 종료
			if(choice==6) break;
			
			//메뉴 선택에 따른 메소드 호출
			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.학생정보 삽입] 메뉴를 선택한 경우 호출되는 메소드
	// => 키보드로 학생정보를 입력받아 STUDENT 테이블에 삽입하고 처리결과를 반환받아 출력
	public void addStudent() {
		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);//문자열을 정수값으로 변환하여 저장
				
				//STUDENT 테이블에 저장된 기존 학생정보의 학번과 중복된 경우 재입력되도록 작성
				//학번을 전달받아 STUDENT 테이블에 저장된 해당 학번의 학생정보를 검색하여 처리
				// => StudentDAOImpl 클래스의 selectNoStudent(int no) 메소드 호출
				StudentDTO student=StudentDAOImpl.getDAO().selectNoStudent(no);
				if(student!=null) {//검색행이 있는 경우 - 학번이 중복된 경우
					System.out.println("[입력오류]현재 사용 중인 학번입니다. 다시 입력해 주세요.");
					continue;
				}
				
				break;//반복문 종료
			}
			
			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;
			}
			
			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}";
				if(!Pattern.matches(phoneReg, phone)) {//정규표현식과 입력값의 패턴이 다른 경우
					System.out.println("[입력오류]전화번호를 형식에 맞게 입력해 주세요.");
					continue;
				}
				
				break;
			}
			
			String address;//주소를 저장하기 위한 변수
			while(true) {//주소 입력값을 검증하기 위한 반복문
				System.out.print("주소 입력 >> ");
				address=in.readLine();
				
				if(address==null || address.equals("")) {//입력값이 존재하지 않는 경우
					System.out.println("[입력오류]주소를 반드시 입력해 주세요.");
					continue;//반복문 재실행
				}
								
				break;
			}
			
			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])";
				if(!Pattern.matches(birthdayReg, birthday)) {//정규표현식과 입력값의 패턴이 다른 경우
					System.out.println("[입력오류]생년월일을 형식에 맞게 입력해 주세요.");
					continue;
				}
				
				break;
			}
			
			//입력받은 학생정보를 이용하여 StudentDTO 객체를 생성하여 필드값 변경
			// => DAO 클래스의 메소드를 호출하기 위한 필요한 값을 객체로 변환하여 전달
			StudentDTO student=new StudentDTO();
			student.setNo(no);
			student.setName(name);
			student.setPhone(phone);
			student.setAddress(address);
			student.setBirthday(birthday);
			
			//입력받은 학생정보를 이용하여 STUDENT 테이블에 삽입 처리
			// => StudentDAOImpl 클래스의 insertStudent(StudentDTO student) 메소드 호출
			//싱글톤 클래스는 객체를 반환받아 메소드를 직접 호출하여 사용 - 참조변수 불필요
			int rows=StudentDAOImpl.getDAO().insertStudent(student);
			
			System.out.println("[처리결과]"+rows+"명의 학생정보를 삽입 하였습니다.");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	//[2.학생정보 변경] 메뉴를 선택한 경우 호출되는 메소드
	public void modifyStudent() {
		
	}

	//[3.학생정보 삭제] 메뉴를 선택한 경우 호출되는 메소드
	public void removeStudent() {
			
	}
	
	//[4.학생이름 검색] 메뉴를 선택한 경우 호출되는 메소드
	public void searchNameStudent() {
		
	}
	
	//[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("=============================================================");
	}
}

0개의 댓글