티스토리 뷰

반응형

강사 : 김호진 강사님



 DAO / DTO / VO

○ DAO (Data Access Object)

데이터에 접근을 목적으로 하는 객체.

리소스를 매우 크게 소모하는 커넥션 객체를 하나만 두고 여러 사용자가 DAO 인터페이스를 사용하여 필요한 데이터에 접근할 수 있도록 한다.

즉, Database 와 연계하여 처리 할 프로그램을 규정화 해 둔 클래스를 말한다.

  • DTO 객체를 만들어 편집 및 조작을 한다.
  • DTO 를 데이터베이스 서버에 저장하기도 하고 DB 서버로부터 레코드를 select 해서 DTO 객체로 변경해 가져오기도 한다.
  • insert, update, delete, select 등 데이터 처리를 주 목적으로 한다.
  • 필요성
    • 모든 데이터베이스에 공통적으로 접속할 수 있는 ODBC가 나왔지만 완벽하진 못했다.
    • 여전히 로우 레벨의 API 를 포함하고 있었기 때문에 개발 장벽이 여전히 높았다.
    • 이런 이유 때문에 개발자들은 정작 데이터베이스에 들어있는 데이터를 어떻게 이용할지에 초점을 맞추기 보다 어떻게 데이터베이스에 접속해서 데이터베이스와 교류하는지에 더 고민하고 집중할 수 밖에 없었다.
    • 즉, 데이터를 활용하는 논리적인 고민보다 기술적 고민에 더 많은 신경을 쏟았던 것이다.
    • 이러한 이유로 DAO 라는 대안이 나왔다.
    • 사용자는 자신이 필요한 Interface 를 DAO 에 던지고,
    • DAO 는 이 인터페이스를 구현한 객체를 사용자에게 편리하게 사용할 수 있도록 반환해준다.
    • DB 에 대한 접근을 DAO 가 담당하도록 하여 데이터베이스 액세스를 DAO 에서만 하게 되면 다수의 원격 호출을 통한 오버헤드를 VO 나 DTO 를 통해 줄일 수 있고 다수의 DB 호출문제를 해결할 수 있다.
    • 또한 단순히 읽기만 하는 연산이기 때문에 트랜잭션 간의 오버헤드를 감소할 수 있다.
    • 그러나 Persistent Storage 를 너무 밀접하게 결합해서 작성하게 되면 Persistent Storage 를 다시 작성해야 할 경우가 생기는데 이 경우 유지보수의 문제가 발생할 수 있다.

○ DTO (Data Transfer Object)

데이터가 포함된 객체를 특정 시스템에서 다른 시스템으로 전달해야 하는 작업을 처리하는 객체.

메소드 호출 횟수를 줄이기 위해 데이터를 담고 있는 객체이다.

즉, 데이터를 하나의 객체로 관리할 목적으로 만들어 둔 클래스의 객체를 말한다.

setter 와 getter 메소드를 가지고 직렬화(Serializable)를 구현한다.

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

※ beans(빈즈) → 개별학습을 통한 정리 필요~!!!


○ VO (Value Object)

Value Object 는 관계형 데이터베이스의 레코드에 대응되는 자바 클래스로 형태는 DB 레코드를 구성하는 필드들을 Value Object 의 Attribute 로 하고 해당 변수에 접근할 수 있는 gettr / setter 메소드의 조합으로 형성된 클래스.

특성은 대체로 불변성이고, equals() 메소드로 비교할 경우 객체의 모든 값을 비교해야 한다.

DTO 와 유사한 개념이지만, 특정 비즈니스 로직만 전달한다는 것으로 이해하는 것이 구분에 용이하다.

즉, 일반적으로 Value Object 는 read only 속성을 갖는다.

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


PreparedStatement 객체

1. Statement 의 execute() 메소드는 문자열로 구성된 SQL 문을 DBMS 로 전달하는 역할을 수행하며, 내부적으로는 SQL 문을 JDBC 드라이버가 읽어들일 수 있는 형식으로 전처리(Precompile) 한다.

이후 드라이버는 DBMS 에 전처리된 요구사항을 전송하게 되는데, SQL 문을 매번 전처리 해야 하기 때문에 반복적인 작업에서 속도가 늦어질 수 있다. 하지만 PreparedStatement 는 전처리된 Statement 로 주어진 SQL 문을 미리 전처리 과정을 거친 상태로 보관하기 때문에 반복 작업에 유리하다.

Statement 의 서브클래스인 PreparedStatement 는 Statement 의 모든 기능을 상속받으며 IN 매개변수의 위치에 데이터베이스로 전송되어질 값을 지정하기 위해 필요한 전체 모든 메소드들의 집합을 포함시킨다.

또한, 세 개의 메소드 execute(), executeQuery(), executeUpdate() 는 아무런 매개변수도 갖지 않는다. 이러한 메소드들의 Statement 형태(SQL 문 매개변수를 가지는 형태)는 PreparedStatement 객체에서 사용되지 않는다.


2. IN 매개변수 넘겨주기

PreparedStatement 객체를 실행하기 전에 각 『?』 매개변수의 값이 설정되어져야 한다.

이것은 setXXX() 메소드를 호출하여 이루어지며 XXX 는 매개변수에 대한 적당한 데이터타입(형)이다.

예를 들어, 매개변수가 long 형이라면, 사용할 메소드는 getLong() 이다.

setXXX() 메소드의 첫 번째 인자는 설정될 매개변수의 순번이고, 두 번째 인자는 매개변수가 설정될 값이다.

※ 실무에서는 주로 PreparedStatement를 사용한다!! (보안이 향상된 형태)


JSP(Java Server Pages)

1. Java Server Pages : 웹 프로그램 작성 언어의 한 종류.

2. JSP(Java Server Pages) 는 HTML 내에 자바 코드를 삽입하여 웹 서버에서 동적으로 웹 페이지를 생성하여 웹 브라우저에 돌려주는 언어이다. Java EE 스펙 중 일부로 웹 애플리케이션 서버에서 동작한다.

3. JSP(Java Server Pages) 는 동적(Dynamic)인 웹 페이지를 비교적 간단히 만들 수 있는 방법을 제공하는 자바를 기반으로 하고 있는 스크립트 언어(Server Side Script)로 자바 엔터프라이즈 애플리케이션에서 UI(User Interface) 영역을 탐당하고 있다.

4. JSP(Java Server Pages) 는 실행 시에는 자바 서블릿(Servlet)으로 변환 후 실행되므로 서블릿(Servlet) 과 거의 유사하다고 볼 수 있다. 하지만, 서블릿과는 달리 HTML 표준에 따라 작성되므로 웹 디자인(구조)하기에 편리하다. 이와 비슷한 구조인 것으로 PHP, ASP, ASP.NET 등도 있다.

5. JSP(Java Server Pages) 는 자바를 서버 환경에서 사용하는 스크립트 방식의 언어로 단일 스레드로 클라이언트의 요청에 서비스한다. 요청이 있을 때 마다... 즉, 객체가 생성될 때 마다... 프로세스를 생성하는 기존의 CGI 와는 달리 하나의 메모리를 공유하면서 서비스되는 원리를 가지고 있다. 이러한 원리는 서버측의 부하를 줄여주며, JSP 내부에는 보여주는 코드만 작성하고 직접 작업하는 부분은 자바 빈으로 구성하여 둘을 분리할 수 있다. 이는 서로 영향을 주지 않으면서 수정할 수 있는 장점을 취하며, JAVA 가 갖고 있는 장점에 해당하는 재사용성을 높을 수 있도록 한다.

클라이언트                 <------------->   서버

HTML, CSS, Javascript   <------------->   JSP(JAVA)

브라우저(IE, FF, CR)      <------------->   웹서버(톰캣), 오라클

요청                        <------------->   응답

6. 아파치 스트럿츠나 자카르타 프로젝트의 JSTL 등의 JSP 태그 라이브러리를 사용하는 경우에는 자바 코딩 없이 태그만으로 간략히 기술하는 것이 가능하기 때문에 생산성을 높일 수 있다.

7. JSP 실행 구조

  • 1단계. 웹 클라이언트에서 웹 서버에 웹 프로그램 요청.

  • 2단계. 웹 서버에서 클라이언트가 요청한 JSP 프로그램 로드.

  • 3단계. JSP 페이지에 대한 변환 실행

  • 이 과정에서 일반 『.java』인 파일로 변환된다. → Servlet

  • 4단계. 『.java』인 파일로 변환된 서블릿(Servlet)의 컴파일 및 실행

  • 5단계. 실행 결과로 동적 생성된 HTML Document 를 클라이언트측에 응답(전달).

  • 6단계. 웹 클라이언트는 응답받은 HTML Document 를 브라우저에서 웹 페이지 형태로 출력

=> 클라이언트에서 서비스가 요청되면 JSP 의 실행을 요구하고, JSP 는 웹 애플리케이션 서버의 서블릿 컨테이너에서 서블릿 원시 코드로 변환된다. 그 후에 서블릿 원시 코드는 바로 컴파일된 후 실행되어 결과를 HTML 형태로 클라이언트에게 돌려주게 된다.


실습

SqlTest03

package com.test;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import com.util.DBConn;

public class SqlTest03 
{
	public static void main(String[] args) 
	{
		Connection conn = DBConn.getConnection();
		
		if (conn != null)
		{
			System.out.println("데이터베이스 연결 성공~!!!");
			
			try
			{
				Statement stmt = conn.createStatement();
				String sql = "SELECT SID, NAME, TEL"
						   + " FROM TBL_MEMBER"
						   + " ORDER BY SID";
				
				// 데이터베이스로부터의 질의 결과를 가져와야 하는 경우이기 때문에
				// executeQuery() 메소드를 사용.
				// executeQuery() 메소드를 사용하면
				// 질의 결과를 ResultSet 객체로 가져올 수 있다.
				// 이 때, ResultSet 객체가 질의에 대한 결과물 모두를 갖고있는 것은 아니다.
				// 단지 데이터베이스로부터 획득한 질의 결과물에 대한 관리만 할 뿐이다.
				// 데이터베이스와 연결을 끊게 되면
				// ResultSet 객체는 더 이상 질의 결과를 관리할 수 없게 된다.
				 ResultSet rs= stmt.executeQuery(sql);
				 
				 // 연결된 형태의 데이터(레코드)로 결과값이 넘어온다.
				 // 레코드들은 ResultSet 객체의 next() 메소드에 의해
				 // 다음 레코드로 이동할 수 있다.
				 // 모든 레코드를 출력해 보기 위해서는 next() 메소드를 가지고
				 // 다음으로 또 그 다음으로 이동하는 작업을 반복하여 수행해야 한다.
				 // 다음 레코드가 있으면 next() 메소드는 true 를 반환한다.
				 while (rs.next())
				 {
					 // 레코드로부터 결과값을 가져오는 것은 getXXX() 메소드.
					 String sid = rs.getString("SID");
					 String name = rs.getString("NAME");
					 String tel = rs.getString("TEL");
					 
					 String str = String.format("%3s %10s %20s", sid, name, tel);
					 System.out.println(str);
				 }
				 rs.close();
				
			} catch (Exception e)
			{
				System.out.println(e.toString());
			}
			
			DBConn.close();
			
			System.out.println("데이터베이스 연결 닫힘~!!!");
			System.out.println("프로그램 종료됨~!!!");
		}
	}
}

MemberDTO

/*=================================================
   MemberDTO.java
   - 문제에서 요구한 Member 클래스
   - DTO / VO 의 개념으로 활용하기 위한 클래스
=================================================*/

package com.test;

public class MemberDTO 
{
	// 주요 속성 구성
	private String sid, name, tel;

	// getter / setter 구성
	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

/*========================================
   Member.java
   - 데이터베이스 액션 처리 전용 클래스
========================================*/

package com.test;

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

import com.util.DBConn;

public class MemberDAO 
{
	private Connection conn;
	
	// 데이터베이스 연결 → 생성자 형태로 정의
	public MemberDAO()
	{
		conn = DBConn.getConnection();
	}
	
	// 회원 정보(데이터) 추가
	public int add(MemberDTO dto) throws SQLException
	{
		int result = 0;
		
		Statement stmt = conn.createStatement();
		String sql = String.format("INSERT INTO TBL_MEMBER(SID, NAME, TEL)"
				+ "VALUES(MEMBERSEQ.NEXTVAL, '%s', '%s')"
				, dto.getName(), dto.getTel());
		
		result = stmt.executeUpdate(sql);
		
		return result;
	}
	
	// 인원(데이터) 수 확인
	public int count() throws SQLException
	{
		// 결과값 변수 선언
		int result = 0;
		
		// 작업 객체 생성
		Statement stmt = conn.createStatement();
		
		// 쿼리문 준비
		String sql = "SELECT COUNT(*) AS COUNT FROM TBL_MEMBER";
		
		// 쿼리문 실행 → 결과 집합 반환(ResultSet)
		ResultSet rs = stmt.executeQuery(sql);
		
		while (rs.next())
		{
			result = rs.getInt("COUNT");
//			result = rs.getInt(1);		//-- 인덱스는 1 부터
		}
		rs.close();   //-- 리소스 반납
		
		// 최종 결과 반환
		return result;
	}
	
	
	// 회원 목록(데이터) 조회
	public ArrayList<MemberDTO> lists() throws SQLException
	{
		// 결과값 변수 선언
		ArrayList<MemberDTO> result =new ArrayList<MemberDTO>(); 
		
		// 작업 객체 생성
		Statement stmt = conn.createStatement();
		
		// 쿼리문 준비
		String sql = "SELECT SID, NAME, TEL FROM TBL_MEMBER";
		
		// 작업 객체를 활용하여 쿼리문 실행
		ResultSet rs = stmt.executeQuery(sql);
		
		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;
	}
	
	
	// 데이터베이스 연결 해제
	public void close()
	{
		DBConn.close();
	}
	
}

SqlTest01(PreparedStatement)

package com.test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;

import com.util.DBConn;

public class SqlTest01 
{
	public static void main(String[] args) 
	{
		try
		{
			Connection conn = DBConn.getConnection();
			
			if (conn != null)
			{
				System.out.println("데이터베이스 연결 성공");
				
				try
				{
					// 쿼리문 준비
					String sql = "INSERT INTO TBL_MEMBER(SID, NAME, TEL) VALUES(?, ?, ?)";
					
					// 작업 객체 생성
					PreparedStatement pstmt = conn.prepareStatement(sql);
					
					// IN 매개변수 넘겨주기
					pstmt.setInt(1, 4);
					pstmt.setString(2, "고길동");
					pstmt.setString(3, "010-4444-4444");
					
					// 쿼리문 실행
					int result = pstmt.executeUpdate();
					
					if(result > 0)
						System.out.println("데이터 입력 성공~!!!");
					
				} catch (Exception e)
				{
					System.out.println(e.toString());
				}
			}
			
			DBConn.close();
			
		} catch (Exception e)
		{
			System.out.println(e.toString());
		}
	}
}

SqlTest02(PreparedStatement)

package com.test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Scanner;

import com.util.DBConn;

public class SqlTest02 
{
	public static void main(String[] args) 
	{
		Scanner sc = new Scanner(System.in);
		
		Connection conn = DBConn.getConnection();
		
		do
		{
			System.out.print("번호를 입력하세요 : ");
			String sid = sc.next();
			
			if(sid.equals("-1"))
				break;
			
			System.out.print("이름을 입력하세요 : ");
			String name = sc.next();

			System.out.print("전화번호를 입력하세요 : ");
			String tel = sc.next();
			
			if (conn != null)
			{
				System.out.println("데이터베이스 연결 성공~!!!");
				
				try
				{
//					Statement stmt = conn.createStatement();
					String sql = "INSERT INTO TBL_MEMBER(SID, NAME, TEL) VALUES(?, ?, ?)";
					
					PreparedStatement pstmt = conn.prepareStatement(sql);
					pstmt.setInt(1, Integer.parseInt(sid));
					pstmt.setString(2, name);
					pstmt.setString(3, tel);
					
					int result = pstmt.executeUpdate();
					if(result > 0)
						System.out.println("회원 정보 입력 완료~!!!");
					
				} catch (Exception e)
				{
					System.out.println(e.toString());
				}
			}
			
		} while (true);
		
		DBConn.close();
		sc.close();
		
		System.out.println("데이터베이스 연결 닫힘~!!!");
		System.out.println("프로그램 종료됨~!!!");
	}
}

SqlTest03(PreparedStatement)

package com.test;

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

import com.util.DBConn;

public class SqlTest03 
{
	public static void main(String[] args) 
	{
		Connection conn = DBConn.getConnection();
		
		if (conn != null)
		{
			System.out.println("데이터베이스 연결 성공~!!!");
			
			try
			{
				String sql = "SELECT SID, NAME, TEL"
						   + " FROM TBL_MEMBER"
						   + " ORDER BY SID";
				
				PreparedStatement pstmt = conn.prepareStatement(sql);
				
				 ResultSet rs= pstmt.executeQuery();
				
				 while (rs.next())
				 {
					 String sid = rs.getString("SID");
					 String name = rs.getString("NAME");
					 String tel = rs.getString("TEL");
					 
					 String str = String.format("%3s %10s %20s", sid, name, tel);
					 System.out.println(str);
				 }
				 rs.close();
				
			} catch (Exception e)
			{
				System.out.println(e.toString());
			}
			
			DBConn.close();
			
			System.out.println("데이터베이스 연결 닫힘~!!!");
			System.out.println("프로그램 종료됨~!!!");
		}
	}
}


반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함