- Entity
- 데이터베이스 테이블과 직접 매핑되는 객체
- JPA 어노테이션을 사용하여 정의
- 데이터의 영속성을 담당
- Repository:
- Entity에 대한 데이터 접근을 추상화
- CRUD 연산과 기본적인 쿼리 메소드를 제공
- 데이터베이스와의 직접적인 상호작용을 담당
- Domain:
- 비즈니스 로직을 포함하는 객체들의 집합
- Entity를 포함할 수 있으며, 추가적인 비즈니스 객체들도 포함
- 핵심 비즈니스 규칙과 로직을 구현
- DTO (Data Transfer Object):
- 계층 간 데이터 전송을 위한 객체
- 주로 클라이언트와 서버 간의 데이터 교환에 사용
- Entity의 일부 데이터만 포함하거나, 여러 Entity의 데이터를 조합 가능
- Service:
- 비즈니스 로직을 구현하는 계층
- Repository를 통해 데이터를 조회하고 조작
- Domain 객체들을 사용하여 복잡한 비즈니스 로직을 처리
- DTO와 Entity 간의 변환 로직을 정의
이들의 관계와 사용 예시:
- Entity 정의:
@Entity
public class User {
@Id @GeneratedValue
private Long id;
private String name;
private String email;
// getters, setters
}
- Repository 정의:
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByEmail(String email);
}
- DTO 정의:
public class UserDTO {
private Long id;
private String name;
private String email;
// getters, setters
}
- Domain 객체 정의 (비즈니스 로직을 포함):
public class UserManager {
public boolean isValidEmail(String email) {
// 이메일 유효성 검사 로직
return email.contains("@");
}
}
- 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;
}
}
이 구조의 흐름:
- 클라이언트가 Controller를 통해 요청 전송 (DTO 형태의 데이터).
- Controller는 Service를 호출
- Service는 비즈니스 로직을 처리
- Domain 객체 (예: UserManager)를 사용하여 비즈니스 규칙을 검증
- Repository를 통해 데이터베이스와 상호작용
- Entity와 DTO 간의 변환을 수행
- Repository는 JPA를 사용하여 실제 데이터베이스 연산을 수행
- Service는 처리 결과를 DTO 형태로 Controller에 반환
- 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 |