[Spring] 간단한 SHOP 제작(2)

JJoSuk·2023년 6월 19일
0

본 프로젝트 자료는 김영한님의 실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발을 참고 제작됐음을 알립니다.

엔티티 클래스 개발

예제에서는 엔티티 클래스에 @Getter, @Setter를 모두 열어두려고 한다. 연습이라 열어두지만 실무에 들어가면 가급적 @Getter 는 열어두고, @Setter 는 필요한 경우만 아니면 사용하는걸 권장하지 않는다.

그 이유는 @Getter 는 조회할 일이 많은 실무에서는 열어둬야 조회하기 편하고 반복 조회를 했을 때도 어떤 일이 발생하지 않는다. 하지만 @Setter 는 호출하는 순간 데이터가 변하는 문제 때문에 실무에서 반복 조회를 했을 때 나중에는 엔티티가 왜 변경됐는지 추척하기 힘든다고 한다.

그래서 엔티티를 변경할 때는 Setter 대신에 변경 지점이 명확하도록 변경을 위한 비즈니스 메서드를 별도로 제공해야 한다.

Member - 회원 엔티티 생성

  • 엔티티의 식별자는 id, PK 컬럼명은 member_id 를 사용.
  • 엔티티 타입이 Member 로 설정되어 있어 id 필드만으로 쉽고 구분 가능하다.
  • 테이블 관례상 테이블명 + id 를 주로 사용한다.

참고로 객체에서 id 대신에 memberId 를 사용해도 무관하다.

Order - 주문 엔티티 생성

OrderStatus - 주문상태 생성

OrderItem - 주문상품 엔티티 생성

Item - 상품 엔티티 생성

Book - 상품 도서 엔티티 생성

Album - 상품 음반 엔티티 생성

Movie - 상품 영화 엔티티 생성

Delivery - 배송 엔티티 생성

DeliveryStatus - 배송 상태 생성

Category - 카테고리 엔티티 생성

위 방식에서는 @ManyToMany 를 사용하긴 했지만, 실무에서는 가급적 사용하지 말자. 추가 생성해야 할 상황해서 ManyToMany 를 사용하면 생성하는걸 막아버린다.

Address - 주소 값 타입 생성

다음과 같이 값 타입들은 변경 불가능하게 만들어야 한다.
값 타입을 변경 못하게 하려면 일단 @Setter 를 사용하지 않고 public 대신 protected 를 사용하면 된다.


엔티티 설계시 주의점

  • 엔티티에서 가급적 Setter 를 사용하지 말자.
  • 모든 연관관계는 지연로딩으로 설정하자.
    • 예를 들어 ManyToOne 같은 경우 즉시로딩(EAGER) 으로 설정되어 있어, 이것만 쓰면 딱히 상관은 없지만 지연로딩(LAZY) 이 섞이는 순간 트랜잭션이 지연로딩에 맞춰 전부 출력하기에 문제가 발생할 수 있다. xxToMany 는 설계상 자동으로 LAZY 가 설정되어 있어 건들지 않아도 되지만, xxToOne 같은 경우 EAGER 에 맞춰 설정이 된 값들이라 전부 LAZY 로 변경 작업을 해줘야 한다.
    • @XToOne(OneToOne, ManyToOne) 관계는 기본이 즉시로딩이므로 직접 지연로딩으로 설정해야 한다.

전부 다음과 같이 수정하면 된다.

컬렉션은 필드에서 초기화 하자.

  • 컬렉션은 필드에서 바로 초기화 하는 것이 안전하다. (null 문제에서 안전해 진다)
  • 하이버네이트는 엔티티를 영속화 할 때, 컬랙션을 감싸서 하이버네이트가 제공하는 내장 컬렉션으로 변경한다. 만약 getOrders() 처럼 임의의 메서드에서 컬력션을 잘못 생성하면 하이버네이트 내부 메커니즘에 문제가 발생할 수 있다. 따라서 필드레벨에서 생성하는 것이 가장 안전하고, 코드도 간결해진다.

만약 다음과 같이 하지 않는다면 아래와 같이 문제가 발생한다.


애플리케이션 구현 준비

회원 도메인 개발

회원 도메인 부터 개발해보자.

구현 기능

회원 등록
회원 목록 조회

순서

회원 엔티티 코드 다시 보기
회원 리포지토리 개발
회원 서비스 개발
회원 기능 테스트

MemberRepository - 회원 리포지토리 생성


회원 서비스 개발

실무에서는 검증 로직이 있어도 멀티 쓰레드 상황을 고려해서 회원 테이블의 회원명 컬럼에 유니크 제 약 조건을 추가하는 것이 안전하다.

그리고 롬복 기능을 이용해 필드 주입이 아닌 생성자 주입을 하는걸 추천한다.

  • @RequiredArgsConstructor
  • 변경 불가능한 안전한 객체 생성 가능.

참고

스프링 데이터 JPA를 사용하면 EntityManager 도 주입 가능하다.


회원 기능 테스트

이제 테스트를 생성해서 테스트 진행해보자.

요구사항

  • 회원가입을 성공해야 한다.
  • 회원가입 할 때 같은 이름이 있으면 예외가 발생해야 한다.

MemberServiceTest - 테스트 생성

  • @SpringBootTest : 스프링 부트 띄우고 테스트(이게 없으면 @Autowired 적용불가)
  • @Transactional : 반복 가능한 테스트 지원, 각각의 테스트를 실행할 때마다 트랜잭션을 시작하고 테스트
    가 끝나면 트랜잭션을 강제로 롤백 (이 어노테이션이 테스트 케이스에서 사용될 때만 롤백)
profile
안녕하세요

0개의 댓글