JAVA개념&실습

JDBC : 03. MemberDTO/MemberDAO/Statement/회원정보 실습

u_SZero 2023. 5. 23. 23:15

! 현재 배워가고 있는 주인장이 쓴 글이니 정보의 정확성에 유의하시기바랍니다 !


 

■■■ DAO DTO VO ■■■

○ DAO(Data Access Object)
   
   데이터에 접근을 목적으로 하는 객체.
   리소스를 매우 크게 소모하는 커넥션 객체를 하나만 두고
   여러 사용자가 DAO 인터페이스를 사용하여
   필요한 데이터에 접근할 수 있도록 한다.
   즉, Database 와 연계하여 처리할 프로그램을 규정화 해 둔 클래스를 의미한다.

   - DTO 객체를 만들어 편집 및 조작을 한다.
   - DTO 를 데이터베이스 서버에 저장하기도 한다.
     데이터베이스 서버로부터 레코드를 select 해서 DTO 객체로
     변형해 가져오기도 한다.
   - insert, update, delete, select 등
     데이터 액션 처리를 주 목적으로 한다.


○ DTO(Data Transfer Object)
   
   데이터가 포함된 객체를 특정 시스템에서 다른 시스템으로
   전달하는 작업을 처리하는 객체.
   메소드 호출 횟수를 줄이기 위해 데이터를 담고 있는 객체이다.
   즉, 데이터를 하나의 객체로 관리할 목적으로 만들어 둔 클래스의 객체를 의미한다.
   setter 와 getter 메소드를 가지고 직렬화(Serializable)를 구현한다.

   - 폼에서 입력된 데이터들을 하나의 DTO 객체로 변환될 수 있다.
   - 일반적으로 하나의 데이터베이스 레코드를 저장하며
     레코드와 같은 구조를 가지고 있는 경우가 많다.
   - 하나의 레코드는 빈즈 클래스 하나로 매핑된다.
   - 데이터베이스의 컬럼은 멤버 변수로 매핑된다.


○ VO(Value Object)
   
   Value Object 는 관계형 데이터베이스의 레코드에 대응되는 자바 클래스.
   형태는 DB 레코드를 구성하는 필드들을 Values Object 의 Atrribute 로 하고
   해당 변수에 접근할 수 있는 setter / getter 메소드의 조합으로 형성된 클래스.
   특성은 대체로 불변성이고, equals() 메소드를 통해 비교할 경우
   객체를 구성하고 있는 모든 값을 비교해야 한다.
   DTO 와 유사한 개념이지만, 특정 비지니스 로직만 전달한다는 것으로
   이해하는 것이 구분에 용이하다.
   즉, 일반적으로 Value Object 는 read only 속성을 갖는다.

   - Network Traffic 을 줄여 처리 성능을 향상시킬 수 있다.
   - 장점으로는 비 서버 측에 해당하는 클라이언트도
     네트워크 오버헤드 없이 영속적 데이터베이스에 액세스 할 수 있다는 점이다.
   - 데이터 전달을 위해 가장 효율적인 방법이지만,
     클래스의 선언을 위해서는 많은 코드가 필요하다.
     즉, 파일 수가 많아지게 되고 관리도 힘들어지게 된다는 단점이 있다.

※ VO 와 DTO 비교
   
   VO 와 DTO 의 차이점은
   특정 비지니스 로직을 담는 객체를 VO 라고 하고
   레이어 간의 통신 용도로 오가는 객체를 DTO 라고 한다.
   대부분 VO 와 DTO를 같은 개념으로 다루고 있다.

 


 

 

MemberDTO.java

/*=================
   MemberDTO.java
==================*/

package com.test;

public class MemberDTO
{
	// 주요 속성 구성
	private String sid;
	private String name;
	private String tel;
	
	// getter / setter 구성 (오른쪽 마우스 -> source -> generate getters and setters)
	public String getSid()
	{
		return sid;
	}
	
	public void setSid(String sid)
	{
		this.sid = sid;
	}
	
	public String getName()
	{
		return name;
	}
	
	public void setName(String name)
	{
		this.name = name;
	}
	
	public String getTel()
	{
		return tel;
	}
	
	public void setTel(String tel)
	{
		this.tel = tel;
	}
	
}

 

MemberDAO.java

/*==========================
   MemberDAO.java
   - DB 액션 처리 전담 객체
============================*/

// 데이터베이스에 액세스 하는 기능
// → DBConn 활용(전담 계층)

// 데이터를 입력하는 기능 → insert

// 인원 수 확인하는 기능
// 즉, 대상 테이블(TBL_MEMBER)의 레코드 카운팅 기능 → select		SELECT COUNT(*) AS COUNT FROM TBL_MEMBER

// 전체 리스트 조회하는 기능
// 즉, 대상 테이블(TBL_MEMBER)의 데이터를 조회하는 기능 → select		

package com.test;

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

import com.util.DBConn;

public class MemberDAO
{
	// 주요 속성 구성
	private static Connection conn;		//_수행을 하려면 데이터베이스에 연결해야 되니깐
	
	Scanner sc = new Scanner(System.in);
	
	// 생성자 정의(사용자 정의 생성자)
	public MemberDAO() throws ClassNotFoundException, SQLException
	{
		conn = DBConn.getConnection();
	}
	
	
	// 메소드 정의 → 데이터를 입력하는 기능 → insert
	public int add(MemberDTO dto) throws SQLException
	{
		// 반환할 결과값을 담아낼 변수(적용된 행의 갯수)
		int result = 0;
		
		// 작업 객체 생성
		Statement stmt = conn.createStatement();
		
		// 쿼리문 준비(→ insert)
		String sql = String.format("INSERT INTO TBL_MEMBER(SID, NAME, TEL)" + " VALUES(MEMBERSEQ.NEXTVAL, '%S', '%S')", dto.getName(), dto.getTel());
		
		// 작업 객체를 활용하여 쿼리문 실행(전달)
		result = stmt.executeUpdate(sql);
        
		// 사용한 리소스 반납
		stmt.close();
        
		// 최종 결과값 반환
		return result;
	}



	// 메소드 정의 → 전체 인원 수를 확인하는 기능 → select
	public int count() throws SQLException
	{
		// 결과값으로 반환하게 될 변수 선언 및 초기화
		int result = 0;
		
		// 작업 객체 생성
		Statement stmt = conn.createStatement();
		
		// 쿼리문 준비(→ select)
		String sql = String.format("SELECT COUNT(*) AS COUNT FROM TBL_MEMBER");
		
		// 생성된 작업 객체를 활용하여 쿼리문 실행 → select → executeQuery() → ResultSet 반환 → 일반적으로 반복문 구성을 통한 ResultSet 처리
		ResultSet rs = stmt.executeQuery(sql);
		
		// ResultSet 처리 → 반복문 구성 → 결과값 수신
		while (rs.next())					// if(rs.next())
		{
			result = rs.getInt("COUNT");	// rs.getInt(1);			// ※ 컬럼 인덱스는 1 부터...
		}

		// 사용한 리소스 반납
		rs.close();
		stmt.close();
        
		// 최종 결과값 반환
		return result;
        
	}// end count()
	
	
	// 메소드 정의 → 전체 리스트를 조회하는 기능 → select
	public ArrayList<MemberDTO> lists() throws SQLException 
	{
		// 결과값으로 반환할 변수 선언 및 초기화
		ArrayList<MemberDTO> result = new ArrayList<MemberDTO>();
		
		// 작업 객체 생성
		Statement stmt = conn.createStatement();
		
		// 쿼리문 준비 → select
		String sql = "SELECT SID, NAME, TEL FROM TBL_MEMBER ORDER BY 1";
		
		// 생성된 작업 객체를 활용하여 쿼리문 실행 → select → executeQuery() → ResultSet 반환
		ResultSet rs = stmt.executeQuery(sql);
		
		// ResultSet 처리 → 일반적 반복문 활용
		while (rs.next())
		{
			MemberDTO dto = new MemberDTO();
			
			dto.setSid(rs.getString("SID"));
			dto.setName(rs.getString("NAME"));
			dto.setTel(rs.getString("TEL"));
			
			result.add(dto);
		}
	
		// 사용한 리소스 반납
		rs.close();
		stmt.close();
        
		// 최종 결과값 반환
		return result;
        
	}//end Lists()
	
}//end class MemberDAO

 

MemberMain.java

/*=================
  MemberMain.java
==================*/

/*
○ TBL_MEMBER 테이블을 활용하여
   이름과 전화번호를 여러 건 입력받고, 전체 출력하는 프로그램을 구현한다.
   단, 데이터베이스 연동이 이루어져야 하고,
   MemberDAO, MemberDTO 클래스를 활용해야 한다.
   
실행 예)

이름 전화번호 입력(5) : 김철수 010-5555-5555
>> 회원 정보 입력 완료~!!!
이름 전화번호 입력(6) : 박영희 010-6666-6666
>> 회원 정보 입력 완료~!!!
이름 전화번호 입력(7) : .

------------------------------
전체 회원 수 : 6명
------------------------------
번호	이름     전화번호
1      김가나	010-1111-1111
2      박나다	010-2222-2222
3      김다라	010-3333-3333
4      이라마	010-4444-4444
5      박마바	010-5555-5555
6      김바라	010-6666-6666
------------------------------
*/

package com.test;

import java.sql.SQLException;
import java.util.Scanner;

import com.util.DBConn;

public class MemeberMain
{

	public static void main(String[] args) throws ClassNotFoundException, SQLException
	{	
		Scanner sc = new Scanner(System.in);
		
		try
		{
			MemberDAO dao = new MemberDAO();
			
			int count = dao.count();
			
			// 테스트
			//System.out.println("count : " + count);
			
			do
			{
				System.out.printf("이름 전화번호 입력(%d) : ", ++count);		// 박나다 010-2222-2222
				
				String name = sc.next();										// 박나다
				
				// 반복의 조건을 무너뜨리는 코드 구성
				if (name.equals("."))
					break;
				
				String tel = sc.next();											// 010-2222-2222
				
				// 테스트
				//System.out.println("name : " + name + " & tel : " + tel);
				
				// ※ 여기까지의 과정을 통해 사용자로부터 이름과 전화번호를 입력받은 이유는
				//    입력받은 데이터를 데이터베이스의 TBL_MEMBER 테이블에 저장하기 위함
				//    데이터 입력을 위해서는 MemberDAO(dao) 의 add() 메소드 호출 필요
				//    add() 메소드 호출하기 위해서는 MemberDTO 를 넘겨주는 과정이 필요
				//    MemberDTO 를 넘겨주기 위해서는 이 객체의 속성값 구성 필요
				
				// MemberDTO 객체 생성
				MemberDTO dto = new MemberDTO();
				
				// 속성값 구성
				dto.setName(name);
				dto.setTel(tel);
				
				// 데이터베이스 TBL_MEMBER 테이블에 데이터를 입력하는 메소드 호출 → add()
				int result = dao.add(dto);
				
				if (result > 0)
					System.out.println(">> 회원 정보 입력 완료~!!!");
				
			} while (true);
		
			System.out.println();
			System.out.println("---------------------------------");
			System.out.printf("전체 회원 수 : %d명\n", dao.count());
			System.out.println("---------------------------------");
			
			System.out.println( "번호   이름    전화번호");
		
			// 리스트 가져와서 출력
			//dao.lists();
			for (MemberDTO obj : dao.lists())
			{
				System.out.printf("%3s %7s %12s\n", obj.getSid(), obj.getName(), obj.getTel());
			}
			
			System.out.println("---------------------------------");
		
			
		} catch (Exception e)
		{
			System.out.println(e.toString());
		}
		finally
		{
			try
			{
				DBConn.close();
				System.out.println("데이터베이스 연결 닫힘~!!!");
				System.out.println("프로그램 종료됨~!!!");
				
			} catch (Exception e)
			{
				System.out.println(e.toString());
			}
		}
		
		
		/* 혼자
		int num;
		
		do
		{
			num = dao.count();
			
			System.out.printf("이름 전화번호 입력(%d) : ",(num+1));
			String name = sc.next();
			String tel = sc.next();
			
			// 반복의 조건을 무너뜨리는 코드 구성
			if (name.equals("."))
			{
				break;
			}
			
			MemberDTO dto = new MemberDTO();
			dto.setName(name);
			dto.setTel(tel);
			
			dao.add(dto);
			
			System.out.println(">> 회원 정보 입력 완료~!!!");
			
		} while (true);
		
		
		System.out.println("-----------------------------");
		System.out.printf("전체 회원 수 : ", dao.count());
		System.out.println("-----------------------------");

		System.out.println("번호     이름   전화번호");
		dao.lists();
		System.out.println("-----------------------------");
		*/
	
	}
}

// 실행 결과

/*
이름 전화번호 입력(3) : 김다라 010-3333-3333
>> 회원 정보 입력 완료~!!!
이름 전화번호 입력(4) : 이라마 010-4444-4444
>> 회원 정보 입력 완료~!!!
이름 전화번호 입력(5) : .

 * ---------------------------------
전체 회원 수 : 4명
---------------------------------
번호   이름    전화번호
1	  김가나	010-1111-1111
2	  박나다	010-2222-2222
3	  김다라	010-3333-3333
4	  이라마	010-4444-4444
---------------------------------
데이터베이스 연결 닫힘~!!!
프로그램 종료됨~!!!
*/

 

 

Test005.java - 데이터베이스 연결 테스트

package com.test;

import java.sql.Connection;

import com.util.DBConn;

public class Test005
{
	public static void main(String[] args)
	{
		try
		{
			Connection conn = DBConn.getConnection();
			
			if (conn==null)
			{
				System.out.println("데이터베이스 연결 실패~!!!");
			}
			else 
			{
				System.out.println("데이터베이스 연결 성공~!!!");
			}
		} catch (Exception e)
		{
			// TODO: handle exception
			System.out.println(e.toString());
		}
		finally 
		{
			try
			{
				DBConn.close();
				
			} catch (Exception e)
			{
				// TODO: handle exception
				System.out.println(e.toString());
			}
		}
	}
}

 


! 현재 배워가고 있는 주인장이 쓴 글이니 정보의 정확성에 유의하시기바랍니다 !