본문 바로가기
Language/Java

[Java] DAO, DTO, VO, Entity 란?

by lucas_owner 2022. 12. 22.

웹 개발을 하다 보면 DAO, DTO, VO, Entity라는 단어들을 많이 접하게 된다. 

해당 개념을 잘 잡아놔야 협업시에 문제가 없을 것 같다. 

 

DAO 

- DAO란 Data Access Object 의 약자이며 이름 그대로

  DB의 data에 접근하는 객체 이다. 비즈니스 로직과, DB Access 로직을 분리하기 위해 사용된다.

 

- Java Spring을 기준으로 DAO는 여러 가지의 모양새를 취하고 있는걸 알 수 있을것이다. 

  여러가지 모양새라 함은 DAO에 DB Connection이 설정되어 있는 경우, 아닌 경우로 나눌 수 있다. 

 

- 많이 사용하는 MyBatis의 경우 DB Connection 정보를 root-context.xml이라는 파일에 정의한다. 

- JPA 같은 경우는 application.yml(properties)에 설정하여 사용하는 경우가 있다. 

 

1. DAO 클래스 예제 (Connection)

- 코드가 상당히 복잡해 보이지만. 사실상 간단한 Create 코드이다.

- DB Connection 정보만 메서드로 따로 정의해서 사용한다면, SQL 관련만 정의해주면 된다.

package connectToDB;

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

import javax.swing.JOptionPane;

public class TravelReservationTableDAO {

	// 예약정보 입력 & 예약 확정
	public int createCard(String reserveID, String reserveAdult, String reserveChild, String day) throws Exception {
																					//,String totalCoast
		// -------------- DB Connect --------------
        Class.forName("com.mysql.jdbc.Driver");
		
		String url = "jdbc:mysql://localhost:3306/TravelDB?useSSL=false";
		String username = "root";
		String password = "1234";
		Connection con = DriverManager.getConnection(url, username, password);

		// --------------  SQL 문 생성  --------------
		
		
		String sql = "insert into TravelReservationTable values (?, ?, ?, ?, ?)";    

		int totalCoast1 = Integer.parseInt(reserveAdult);
		int totalCoast2 = Integer.parseInt(reserveChild);
		int totalCoast3 = (totalCoast1 * 27900) + (totalCoast2 * 10900);		
		
		PreparedStatement ps = con.prepareStatement(sql);
		ps.setString(1, reserveID);
		ps.setString(2, reserveAdult);
		ps.setString(3, reserveChild);
		ps.setString(4, day);
		ps.setInt(5, totalCoast3);

		// -------------- DB 로 전송 --------------
		
 
	int result = ps.executeUpdate();
		return result;
		
		
	}//create end

2. DAO 클래스 예제 (MyBatis)

- MyBatis를 사용한다면 DB 연결 정보, SQL 쿼리문 등등 따로 정의되어있고 

   DAO에서는 어떤 정의되어있는 SQL을 사용할 건지 파라미터는 무엇인지 정의해주면 끝이다. 

@Repository
@RequiredArgsConstructor
public class CustMgmtDAO {

	private final SqlSessionTemplate db;
	
	/**
	 * 
	 * <pre>
	 * </pre>
	 * @Name    : 고객 로그인
	 * @Method  : logIn
	 * @Return  : void
	 * @Version : V1
	 */
	public CustMgmtDTO logIn(CustMgmtDTO inDTO) {
		
		CustMgmtDTO outDTO = db.selectOne("O_custMgmt.retrieveCustLogin", inDTO);
		return outDTO;
		
	}

DTO

- DTO(Data Transfer Object)의 약자이며 계층(Layer) 간 데이터교환을 위한 객체이다. 

* 여기서 계층(Layer)란 - Controller, View, Business, Persistent 레이어 등을 말한다.

 

- 이름 그대로 데이터를 교환하는 목적을 갖는 객체이기 때문에, 서비스 로직을 갖고 있지 않다.

   순수한 Data 객체이며 Getter, Setter만 포함하고 있다. 

   Getter/Setter로 데이터를 조작, 가져오기가 가능하다. 

 

- Lombok 라이브러리를 활용하면 가독성이 훨씬 좋아질 수 있다. 

 

1. DTO 객체

public class MemberDTO {

    pulic MemberDTO() { }

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2. DTO 객체 (Lombok)

@Data // Getter, Setter, toString
@Builder
@AllArgsConstructor // 모든 필드 값을 파라미터로 받는 생성자 
@NoArgsConstructor // 파라미터가 없는 기본 생성자 
public class MemberDTO {

	private String name;
    
}

VO

VO(Value Object)는 DTO 와 같이 많이 듣게 된다. 

그 이유는 DTO와 VO를 혼용해서 사용하기 때문이다. DTO와 VO가 같다고 생각할 수 있지만.

조금의 차이가 존재하기 때문에 같은 객체라고 말하지 않는다. 

 

그 이유는 VO는 DTO와는 다르게 setter가 존재하지 않는다. 즉 DTO는 데이터 조작(전송을 위한)이 가능하지만. 

VO는 단순히 데이터를 담아서 이동만 한다. 또한 새로운 값을 사용하기 위해서는 새로이 객체를 생성해야한다.

즉 VO는 중간에 데이터 조작X, Read Only

(또한 객체 자체를 어떠한 값으로 보기위해서도 사용. ex. Color.Blue)

 


Entity

- 엔티티는 위의 3가지 객체와는 조금 다른 개념이다.

 

* 개념

- JPA(Java Persistence API)에서 주로 사용되는 개념이며. 

  Entity Class는 : 실제 DataBase 의 테이블과 1:1 매핑되는 클래스이다. 

  (Entity class를 보면 해당 DB Table의 정보를 거의 알 수 있음.)

   DB table에 존재하는 컬럼만을 속성(필드)로 가져야 한다. 또한 테이블에 존재하지 않는 컬럼을 가져서도 안되며, 

  상속이나, 구현체여서도 안된다. 

 

1. Entity와 DTO를 분리하여 사용하여야 하는 이유

- Entity class를 사용할 때에는 Entity 자체로 각 레이어별 전송을 하는것 보다는 DTO 를 사용해서 전달 하는 방식을 권장한다. 

  그 이유는 각 객체의 쓰임이 다르다고 할 수가 있다. 

 

  Entity는 DB와 1:1 객체, DTO는 계층간 데이터 교환 객체.

  이 말이 무슨뜻인지 안다면 쓰임새가 어떻게 다른지 알 수 있다.  

  단순하게 Entity나 도메인 객체는 계층이나 컴포넌트간 전달을 위해 사용되는 객체가 아니다.

 

* View :  의 시선에서 보았을때 View -> Server로 수많은 데이터들이 변경되고 사용된다. 

   만약 이때 DB Table과 1:1 관계인 Entity를 사용을 한다면 객체의 내용을 신뢰 할 수 없게된다. 

   또한 엔티티 클래스의 값이 변하면 DB Data 또한 반영되기 때문이다. 

 

* 위에서 언급한 내용과 연결되지만 더 자세하게 살펴보자면

  Client에서 Server로 넘어오는 Data는 생각보다 복잡 할 수 있다. 

  (여러가지 테이블이 조인된 data 형태 라던지..) 

  이것을 Entity 자체로 받아오는것도 문제가 발생하고, Data의 조작이 많기 때문에 어디서부터 Data가 잘못 되었는지 파악도 힘들다.

 

* DTO와 Entity 분리에 대해서는 다음에 더 자세하게 포스팅 하겠습니다. 


간단 정리

DAO 

- DB에 접근하는 Java 객체.

- 사용 라이브러리에 따라 코드의 생김새가 조금씩 다르나 기능과 사용 이유는 같음

 

DTO

- 계층간 데이터 교환을 위한 객체

- Client -> Server, Server -> Client 또는

   Controller -> service 같은 Layer에서 사용.

- 순수 데이터 객체

- 로직을 가지지 않음(비지니스 로직)

 

VO

- 단순 데이터 객체

- 데이터의 조작 불가

 

Entity 

- DB 테이블과 1:1 매핑되는 객체

- JPA 사용시 주로 사용됨. 

- DTO 와 분리하여 사용 하여야 함.

- 상속받거나, 구현체여서는 안된다. 

반응형

댓글