스프링부트를 사용하다 보면,

DTO, DAO, Repository, Domain, Entity, 등 다양한 용어를 접할 수 있다.

그리고 이 용어들에 대해서 공부하다보면 각 용어가 점점 헷갈려진다.. 

이번 게시글에서는 이 용어들에 대해서 공부해보고자 한다.

 

DTO (Data Transfer Object)

말 그대로 '데이터 전송 객체'이다.

뷰에서 컨트롤러로 넘어오는 데이터를 담거나, 컨트롤러에서 서비스로 넘기는 데이터를 담거나 할 때 사용할 수 있다.

로직을 가지지 않고, 데이터 객체에 대한 정보만 담고 있다.

  • 예제
1
2
3
4
5
6
7
8
9
10
11
12
import com.sun.istack.NotNull;
import lombok.Data;
 
// 사용자 정보를 담는 Dto
@Data
public class UserInfoDto {
  @NotNull
  private String userNo; // 사용자 고유번호
 
  private String name; // 이름
  private String email; // 이메일
}
cs

사용자 정보를 담는 간단한 Dto이다.

(@Data 어노테이션은 @Getter, @Setter, @RequiredArgsConstructor, @ToString, @EqualsAndHashCode를 한꺼번에 설정해준다)

 

DAO (Data Access Object)

이름 그대로 DB에 접근하기 위한 객체이다.

서비스와 DB를 연결하기 위한 중간 다리의 역할을 한다.

Mybatis를 기준으로 예시를 작성한다.

  • 예제
1
2
3
4
5
6
7
8
9
@Repository
public class UserDao{
    @Autowired
    private SqlSessionTemplate sqlSession;
    
    public int selectUserCnt(UserDomain userDomain){
        return sqlSession.select("User.selectUserInfo", userDomain);
    }
}
cs

Mybatis 모듈의 SqlSessionTemplate를 주입받아

쿼리문이 작성된 mapper xml 에서 namespace(예제에선 User) 와 쿼리ID(selectUserInfo)로 쿼리를 호출해 결과를 리턴받는다.

 

Repository

데이터베이스에 접근하기 위한 객체이다.

Spring Data JPA를 기준으로 예시를 작성한다.

  • 예제
1
2
3
4
5
6
7
import org.springframework.data.jpa.repository.JpaRepository; 
import org.springframework.stereotype.Repository; 
 
@Repository 
public interface SampleEntityRepository extends JpaRepository <UserEntity, String> {
     List<UserEntity> findByUserNo(String userNo);
}
cs

 

DAO =/ Repository ??

처음에는 DAO와 Repository가 같은 역할을 하는 것처럼 보여서 같은 친구들인 줄 알았는데..

찾아보니 DAO와 Repository는 명백한 차이점이 있는 다른 요소이다.

DAO와 Repository가 DAL(Data Access Layer, DB 관련 정보를 처리하는)의 구현체인 것은 같지만

제공/관리(매핑)하는 주체의 차이에 따라서 달라지는 것 같다.

 

자세하게 설명하자면,

위 예제에서 볼 수 있듯이 Repository는 자바 객체를 테이블에 매핑 할 수 있고 이는 매핑 레벨이 객체 수준임을 알 수 있다. 하지만, DAO는 SQL에 대한 매핑이기 때문에 매핑 레벨이 SQL 수준이다.

 

이런 차이는 두 개념이 추상화하는 대상이 다름을 의미한다.

DAO는 SQL 수준의 매핑을 지원하기 때문에 퍼시스턴스 레이어(영속성, 일반 데이터와 다르게 계속 유지되는 데이터)에 속하여 퍼시스턴스 레이어에 대한 추상화이지만 Repository는 도메인 레이어에 객체 컬렉션의 추상화이다.

 

결과적으로 보면 DAO와 Repository 모두 퍼시스턴스(데이터 처리) 로직을 위해 동작하지만, 따로 놓고보면 명백한 차이점이 있다고 볼 수 있겠다.

 

추가) DAO가 SQL 수준의 매핑을 지원하기 때문에 객체 수준으로 매핑하는 Repository에서는 이 DAO를 여러개 선언해서 사용할 수 있는 것이다.

(예. 값을 select 해오는 여러 DAO의 데이터를 합쳐 리스트를 조회하는 것을 Repository에서 구현하는 것)

 

Domain(Entity)

실제 DB 테이블과 매핑시키는 클래스이다.

  • 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Entity(name = "user")
@Table(name = "`USER_INFO`")
@Getter
@Setter
@ToString
public class User{
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
 
  @Column(length = 10, name = "USER_NO")
  private String userNo;
 
  @Column(name = "USER_NM")
  @NotNull
  private String userNm;
 
  @Column(name = "USER_BIRTH")
  @NotNull
  private String userBirth;
}
cs

@Entity 어노테이션을 사용해 데이터베이스 테이블과 매칭될 클래스임을 나타낸다. 

@Builder 어노테이션을 사용해서 객체 생성 시점에 값을 넣어줄 수 있다.

Setter를 여러 군데에서 사용해서 일관성을 보장하지 못하게 사용하는 것보다, Builder 어노테이션을 사용하는 것이 좋아보인다. (관련 내용은 추후 포스팅 할 예정)

 

 

+ Recent posts