본문 바로가기
데이터베이스 & ORM

Entity, Repository, DTO, domain, service의 연관성과 개념

by DoRightting 2024. 7. 20.
  1. Entity
    • 데이터베이스 테이블과 직접 매핑되는 객체
    • JPA 어노테이션을 사용하여 정의
    • 데이터의 영속성을 담당
  2. Repository:
    • Entity에 대한 데이터 접근을 추상화
    • CRUD 연산과 기본적인 쿼리 메소드를 제공
    • 데이터베이스와의 직접적인 상호작용을 담당
  3. Domain:
    • 비즈니스 로직을 포함하는 객체들의 집합
    • Entity를 포함할 수 있으며, 추가적인 비즈니스 객체들도 포함
    • 핵심 비즈니스 규칙과 로직을 구현
  4. DTO (Data Transfer Object):
    • 계층 간 데이터 전송을 위한 객체
    • 주로 클라이언트와 서버 간의 데이터 교환에 사용
    • Entity의 일부 데이터만 포함하거나, 여러 Entity의 데이터를 조합 가능
  5. Service:
    • 비즈니스 로직을 구현하는 계층
    • Repository를 통해 데이터를 조회하고 조작
    • Domain 객체들을 사용하여 복잡한 비즈니스 로직을 처리
    • DTO와 Entity 간의 변환 로직을 정의

이들의 관계와 사용 예시:

  1. Entity 정의:
@Entity
public class User {
    @Id @GeneratedValue
    private Long id;
    private String name;
    private String email;
// getters, setters
}

  1. Repository 정의:
public interface UserRepository extends JpaRepository<User, Long> {
    Optional<User> findByEmail(String email);
}

  1. DTO 정의:
public class UserDTO {
    private Long id;
    private String name;
    private String email;
// getters, setters
}

  1. Domain 객체 정의 (비즈니스 로직을 포함):
public class UserManager {
    public boolean isValidEmail(String email) {
// 이메일 유효성 검사 로직
        return email.contains("@");
    }
}

  1. Service 정의:
@Service
public class UserService {
    private final UserRepository userRepository;
    private final UserManager userManager;

    public UserService(UserRepository userRepository, UserManager userManager) {
        this.userRepository = userRepository;
        this.userManager = userManager;
    }

    public UserDTO createUser(UserDTO userDTO) {
        if (!userManager.isValidEmail(userDTO.getEmail())) {
            throw new IllegalArgumentException("Invalid email");
        }

        User user = new User();
        user.setName(userDTO.getName());
        user.setEmail(userDTO.getEmail());

        User savedUser = userRepository.save(user);

        return convertToDTO(savedUser);
    }

    public UserDTO getUserByEmail(String email) {
        return userRepository.findByEmail(email)
                .map(this::convertToDTO)
                .orElseThrow(() -> new EntityNotFoundException("User not found"));
    }

    private UserDTO convertToDTO(User user) {
        UserDTO dto = new UserDTO();
        dto.setId(user.getId());
        dto.setName(user.getName());
        dto.setEmail(user.getEmail());
        return dto;
    }
}

이 구조의 흐름:

  1. 클라이언트가 Controller를 통해 요청 전송 (DTO 형태의 데이터).
  2. Controller는 Service를 호출
  3. Service는 비즈니스 로직을 처리
    • Domain 객체 (예: UserManager)를 사용하여 비즈니스 규칙을 검증
    • Repository를 통해 데이터베이스와 상호작용
    • Entity와 DTO 간의 변환을 수행
  4. Repository는 JPA를 사용하여 실제 데이터베이스 연산을 수행
  5. Service는 처리 결과를 DTO 형태로 Controller에 반환
  6. Controller는 클라이언트에게 DTO를 응답으로 전송

이 구조의 장점:

  • 관심사 분리: 각 계층이 명확한 책임을 가짐.
  • 유연성: 데이터베이스 구조 (Entity)와 API 응답 (DTO)을 독립적으로 변경 가능
  • 보안: Entity의 모든 정보를 노출하지 않고 필요한 정보만 DTO를 통해 전송 가능
  • 테스트 용이성: 각 계층을 독립적으로 테스트 가능
  • 재사용성: Domain 로직과 Repository를 다양한 Service에서 재사용 가능

'데이터베이스 & ORM' 카테고리의 다른 글

VACUUM ANALYZE  (1) 2024.11.11
PostgreSQL GIN  (5) 2024.11.10
QueryDSL 개요  (0) 2024.07.25
JPA에서의 엔티티 참조 조회 방식  (1) 2024.07.24
Q DTO  (0) 2024.07.21