Programming/Back-end(Java, JSP)

VO(DTO), DAO, Service 용어 설명

Sujin Lee (Daisy) 2020. 3. 18. 01:28

# DAO

 - DAO: Data Access Object. ==> '데이터에 접근하는 객체' 

   DB를 사용해 데이터를 조회하거나 조작하는 기능을 전담하도록 만든 오브젝트를 말한다. (출처: 토비의 Spring) 

 - DAO 클래스: 데이터에 접근할 때 사용하는 객체를 위한 클래스.

 

- SELECT, INSERT, UPDATE, DELETE 등 데이터 처리가 주 목적 

 1) 드라이버 등록
 - public xxxDAO() {...}
 2) 연결
  - public void getConnection(){...}
 3) 연결 해제 
  - public void disConnection(){,,,}
 4) 기능 설정 (SQL 전송 → DB 조회/조작) 
  - DB가 어떻게 필요한지에 따라서 적절한 SQL 문 작성 (SELECT, INSERT, UPDATE ...) 
  - ex) 게시판 글 상세보기 
    public BoardVO boardDetailData(int no){...}   ==> 글 상세보기니까 SELECT해서 데이터를 가져올 것이다. 

웹서버는 DB와 연결하기 위해서 매번 커넥션 객체를 생성하는데, 이것을 해결하기 위해 나온것이 컨넥션 풀입니다. ConnectionPool 이란 connection 객체를 미리 만들어 놓고 그것을 가져다 쓰는것입니다. 또 다쓰고 난 후에는 반환해 놓는 것. 하지만 유저 한명이 접속해서 한번에 하나의 커넥션만 일으키지 않고 게시판 하나만 봐도 목록볼때 한번, 글읽을때마다 한번, 글쓸때 한번 등등… 엄청나게 많은 커넥션이 일어나기에, 커넥션풀은 커넥션을 또 만드는 오버헤드를 효율적으로 하기 위해 DB에 접속하는 객체를 전용으로 하나만 만들고, 모든 페이지에서 그 객체를 호출해다 사용한다면? 이렇게 커넥션을 하나만 가져오고 그 커넥션을 가져온 객체가 모든 DB와의 연결을 하는것이 바로 DAO 객체입니다

 - 출처: https://jungwoon.github.io/common%20sense/2017/11/16/DAO-VO-DTO/

 

# VO ≒ DTO 

 - VO: Value Object.  

   DTO: Data Transfer Object ==> '데이터를 교환하는 객체' 

 - 계층 데이터 교환을 위해 사용하는 객체이다. (계층: View-Controller-Service-DAO와 같은 각 계층)

 - Spring에서의 VO ≒ MyBatis에서의 DTO JSP에서의 JavaBeans

   단, VO는 read-only 라는 점에서 DTO와 다르다. 

 - 순수한 데이터 객체. 단순히 데이터 교환만을 위한 것. 로직X. 속성에 접근하기 위한 getter,setter 메소드 有

 - Database에서 데이터를 얻어 Service나 Controller 등으로 보낼 때 사용하는 객체를 말한다. 

 1) 필드 선언

  - 하나의 컬럼 값을 저장

  - 보안성 및 캡슐화, 데이터 은닉의 목적으로 private 으로 선언

 2) getter

  - 인스턴스의 변수 값을 가져옴

 3) setter 

  - 필드에 값을 저장하는 기능

  - HTML 폼의 input 태그의 값(value)을 빈에 저장

 

 

 # Service 

 - DAO 여러개를 묶어서 사용할 때 'Service'라고 부름. DAO가 여러개 합쳐진 것.

 - 서비스 클래스는 사용자의 요청을 처리하기 위한 기능을 제공한다.
   주로 DAO를 통해서 데이터에 접근하고 기능을 수행하는 데 필요한 로직을 구현한다. 
   (출처: JSP 2.3 웹 프로그래밍, 최범균 저) 

 

 

# Service와 DAO의 차이? 

Service는 사용자가 요청한 작업을 처리하는 과정을 하나의 작업으로 묶은 것이고,
dao는 CRUD작업을 하나씩 분할해 놓은 것이다.
사용자가 한 번의 요청으로 단순히 페이지 이동이 필요하다면 select와 같은 단순히 하나의 dao만 작동하기 때문에 Service와 dao가 나눌 필요가 없는 것처럼 보이지만,
사용자가 글을 작성하거나 수정하는 것과 동시에 페이지가 이동한다면 update, select가 작동하기 때문에 여러 dao를 Service안에 조립하는 로직을 갖게된다.

출처: ysyapr91.tistory.com/4

 

 

 

# DAO 예시 (Java) 

package com.sist.dao;
import java.util.*;
import java.sql.*;
public class EmpDAO {
	// 연결 도구 Connection (Sockeet)
	private Connection conn;
	// 입출력 => InputStream, OutputStream
	private PreparedStatement ps;
	// URL 주소 고정
	private final String URL="jdbc:oracle:thin:@localhost:1521:XE";
	
	//1. 드라이버 등록
	public EmpDAO()
	{
		try 
		{
			Class.forName("oracle.jdbc.driver.OracleDriver"); //메모리 할당
		} catch (Exception ex) 
		{
			ex.printStackTrace();
		}
	}
	
	//2. 연결
	public void getConnection()
	{
		try 
		{
			conn=DriverManager.getConnection(URL,"ID","PASSWORD");
		} catch (Exception ex) {}
	}
	
	//3. 해제
	public void disConnection()
	{
		try
		{
			if(ps!=null) ps.close();
			if(conn!=null) conn.close();
		}catch (Exception ex) {}
	}
	
	//4. 기능설정(기능수행)
	// ex1) SELECT로 전체 데이터 읽어오는 것 만들어봐라. 
    // 전체 데이터 ==> 결과값 多 ==> 리턴형: ArrayList
	// ※ 결과값이 여러개 ==> 리턴형: ArrayList 
    //    결과값이 1,2개 ==> 리턴형: vo 
	public ArrayList<EmpVO> empAllData()
	{
		ArrayList<EmpVO> list = new ArrayList<EmpVO>();
		try 
		{
			// (1) 연결
			getConnection();
			// (2) SQL 문장 만들고
			String sql="SELECT * "
						+"FROM emp "
						+"ORDER BY empno";
			// (3) 오라클로 전송
			ps=conn.prepareStatement(sql); // ==> (2)에서 만든 SQL문장이 오라클로 넘어갔다. 
			// (4) 결과값 받기 
			ResultSet rs=ps.executeQuery();
			// (5) 결과값 받은 것을 list에 첨부 
			while(rs.next())
			{
				// rs.next() : 결과값에서 첫 행에 커서를 두고 처음 행을 읽음 ==> 커서를 한 행씩 뒤로 이동하면서 다음줄 데이터를 한 줄 한 줄 읽음... 
				EmpVO vo = new EmpVO();
				vo.setEmpno(rs.getInt(1));
				vo.setEname(rs.getString(2));
				vo.setJob(rs.getString(3));
				vo.setMgr(rs.getInt(4));
				vo.setHiredate(rs.getDate(5));
				vo.setSal(rs.getInt(6));
				vo.setComm(rs.getInt(7));
				vo.setDeptno(rs.getInt(8));
				
				list.add(vo); //14개를 모아서 전송
			}
			rs.close();
		} catch (Exception ex) 
		{
			// 에러처리 
			ex.printStackTrace();
		}
		finally
		{
			// 연결 해제 
			disConnection();
		}
		return list;
	}
	
	// ex2) SELECT, WHERE 문장 이용
	//		사용자가 empno 입력하면 데이터 뽑아오게 (결과 1줄. 1명 것만) 만들어봐라. 
    // 1명의 데이터만 출력 ==> 결과값이 1개 ==> 리턴형: vo 
	// ※ 결과값이 여러개 ==> 리턴형: ArrayList 
    //    결과값이 1,2개 ==> 리턴형: vo 
	public EmpVO empDetailData(int empno) 
	{
		EmpVO vo = new EmpVO();
		
		try 
		{
			// (1) 연결
			getConnection();
			// (2) SQL 문장 만들고
			String sql="SELECT * " 
						+"FROM emp "
						+"WHERE empno=?"; 
			// (3) 오라클로 전송
			ps=conn.prepareStatement(sql); 
			ps.setInt(1, empno);
			// (4) 결과값 받기 
			ResultSet rs=ps.executeQuery();
			// (5) 결과값 받은 것을 list에 첨부 
			rs.next();
			vo.setEmpno(rs.getInt(1));
			vo.setEname(rs.getString(2));
			vo.setJob(rs.getString(3));
			vo.setMgr(rs.getInt(4));
			vo.setHiredate(rs.getDate(5));
			vo.setSal(rs.getInt(6));
			vo.setComm(rs.getInt(7));
			vo.setDeptno(rs.getInt(8));
  
			rs.close();
		} catch (Exception ex) 
		{
			// 에러처리 
			ex.printStackTrace();
		}
		finally
		{
			// 연결 해제 
			disConnection();
		}
		return vo; 
	}
}

 

 

# VO 예시 (Java) 

public class CategoryVO {
	private int cateno;
	private String title;
	
	public int getCateno() {
		return cateno;
	}
	public void setCateno(int cateno) {
		this.cateno = cateno;
	}
	public String getTitle() {
		return title;
	}
	public void setTitle(String title) {
		this.title = title;
	}
}

 

# JSP 자바빈 예시

/* <JSP 자바빈 클래스> */
public class BeanClassName implements java.io.Serializable{
	/* 값을 저장하는 필드 */
    private String value;
    
    /* BeanClassName의 기본 생성자 */
    public BeanClassName(){
    }
    
    /* 필드의 값을 읽어오는 값 */
    public String getValue(){
    	return value;
    }
    
    /* 필드의 값을 변경하는 값 */
    public void setValue(String value){
    	this.value = value;
    }
}

 

반응형