스프링을 사용한 웹앱의 경우 DAO, DTO, Repository, Entity를 사용하여 데이터를 다루는데
스프링부트의 경우 내장 톰캣을 통해 서블릿을 관리하고 이를 컨트롤러에서 각 어노테이션을 통해 매핑한다.
도메인(엔티티)의 경우 가장 Persistence Layer에 가까운데 이를 이용하기 위해 사용하는 방법들을 알아본다.
@Repository
@RequiredArgsConstructor
public class MemberRepository{
private final EntityManager em;
public void save(Member member) {
em.persist(member);
}
여기서는 JPA 구현체인 Entity Manger 객체를 사용하여 DB에 접근
하지만 별도의 Entity Class를 사용하여 그 클래스를 테이블과 1:1 매칭할 수 있다.
이러한 Entity Class를 도메인이라고 하며 가장 DB와 가까운 클래스다.
@Entity
@Getter
public class Member {
@Id @GeneratedValue
@Column(name = "member_id")
private Long id; // PK
@NotEmpty
@NotNull
private String name;
@Embedded // 내장 타입 임베딩
private Address address;
@JsonIgnore
@OneToMany (mappedBy = "member")
private List<Order> orders = new ArrayList<>();
}
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class MemberService {
private final MemberRepository memberRepository; // 서비스 계층의 Repository 시용
Entity를 통해 DB에서 데이터를 꺼내왔지만 한가지 문제가 있다.
요청을 받고 데이터를 처리하고 반환해주기 위해선 데이터에 접근해야 하는데
여기서 Controller, Presentation Layer의 경우 클라이언트와 직접 맞닿는 부분이고
엔티티는 프레젠테이션 계층과 완전히 분리되어야 한다
이럴 때 DTO를 사용하는데
@Data
@AllArgsConstructor
static class MemberDto {
private String name;
private Address address;
}
결론적으로 스프링 프로젝트는 다음과 같은 구조를 가지게 된다
@Entity
@Getter @Setter
public class Member {
@Id @GeneratedValue
@Column(name = "member_id")
private Long id;
@Repository
@RequiredArgsConstructor
public class MemberRepository{
private final EntityManager em;
@Service
@Transactional(readOnly = true)
@RequiredArgsConstructor
public class MemberService {
private final MemberRepository memberRepository;
@RestController // Response + Request
@RequiredArgsConstructor
public class MemberApiController {
private final MemberService memberService;
@GetMapping("api/v1/members")
public Result<List<MemberDto>> memberV2() {
DTO 어노테이션 @Data에 getter setter 다 들어가 있는거 아닌가요 ??